Prism Code Editor

repository·main·Indexed 41 days ago

https://github.com/jonpyt/prism-code-editor

A library for creating interactive code editors and highlighted code blocks. Includes prism-react-editor for React applications, as well as markdown-it-prism-code-editor and marked-prism-code-editor plugins to transform fenced code blocks into interactive editors.

Tokens
75.6K
Snippets
238
Records
320
Agent score
99%

What's inside Prism Code Editor

  1. Overview of Prism code editor

    main

    Prism code editor is a lightweight and extensible code editor component for the web built on top of Prism. It is designed to be highly efficient, using a Prism instance that is less than 1/3 the size of the standard one, making it better suited for editor environments.

    Key characteristics include:

    • Syntax highlighting with Prism: Uses a specialized, lightweight Prism instance.
    • Zero bloat: The library has no dependencies; you only import the specific packages or functionality you need.
    • Extensible: Most features are implemented via optional extensions, allowing for a minimal footprint.
  2. Extend CodeBlock with extensions and hooks

    main

    You can enhance CodeBlock by passing extension components as children. To create your own extension and access the code block instance or its props, use the usePrismCodeBlock() hook inside your extension component.

    import { usePrismCodeBlock } from "prism-react-editor/code-blocks"
    
    function MyCodeBlockExtension() {
      const [codeBlock, props] = usePrismCodeBlock()
      // ...
    }
  3. Configure hotkey precedence

    main

    When multiple hotkeys are registered to the same key, you can control their execution order using the precedence parameter in addEditorHotkey.

    • Precedence: A positive integer (defaults to 2).
    • Lower numbers = Higher precedence (runs earlier).
    • Precedence 1: Use this when you want to conditionally override existing commands.
    • Precedence 0: The highest possible precedence. Use with caution, as it can override sequential commands if the key is part of a sequence.
    • Tie-breaking: If precedence is equal, commands execute in the order they were added.
  4. How to make editors interactive and add extensions

    main

    The markdown plugins do not inject any JavaScript or CSS. They only generate the HTML structure.

    Mounting Editors

    To make the editors interactive on the client side, you must manually call mountEditorsUnder() in your client-side JavaScript.

    Adding Features

    You can add client-side features like copy buttons, bracket highlighting, or hover descriptions by using forEachCodeBlock() to iterate over the code blocks in your client-side code.

  5. Manage grammar import order

    main

    While import order usually doesn't matter, it is critical when one grammar extends or modifies another. If a grammar (like js-templates) depends on features added to another grammar (like typescript or javascript), ensure the base grammar is imported first. If the order is incorrect, the extension may fail to apply to the base language.

    // Correct order for extensions
    import "prism-code-editor/prism/languages/typescript"
    import "prism-code-editor/prism/languages/js-templates"
  6. Performance considerations and limits

    main

    The editor tokenizes all code each time for simplicity. While it optimizes DOM updates by only refreshing changed lines, performance will degrade as the document size increases.

    Threshold: Once a file exceeds 1000 lines of code (LOC), the editor will likely experience slowdowns on most hardware. For documents of this size, it is recommended to use a more robust, heavy-duty editor library.

  7. How extensions work in Prism react editor

    main

    To keep the core lightweight, most functionality is provided via optional extensions. Extensions are implemented as React components that use the usePrismEditor hook to access the editor instance.

    Common extensions include:

    • useBracketMatcher / useHighlightBracketPairs: Bracket matching.
    • useTagMatcher / useHighlightMatchingTags: Tag matching.
    • useSearchWidget / useHighlightSelectionMatches: Search and selection highlighting.
    • useEditorCommands / useEditHistory: Commands and undo/redo.
    • useCopyButton: Copy button functionality.
    • IndentGuides: Visual indentation guides.

    You can use BasicSetup for a pre-configured set of common extensions, or manually compose your own by importing specific hooks and components.

    import { Editor, PrismEditor } from "prism-react-editor"
    import { usePrismEditor } from "prism-react-editor/extensions"
    import { useBracketMatcher } from "prism-react-editor/match-brackets"
    import { IndentGuides } from "prism-react-editor/guides"
    
    function MyExtensions() {
      const [editor] = usePrismEditor()
      useBracketMatcher(editor)
    
      return <IndentGuides />
    }
    
    function MyEditor() {
      return <Editor language="jsx" value="const foo = 'bar'">
        <MyExtensions />
      </Editor>
    }
  8. Style static code blocks

    main

    Static code blocks require both prism-code-editor/layout.css and prism-code-editor/code-block.css to render correctly.

    DOM Structure

    Code blocks use a pre and code structure similar to the interactive editors:

    <pre class="prism-code-editor language-[lang] [extra-classes]">
    	<code class="pce-wrapper">
    		<div class="pce-overlays"></div>
    		<div class="pce-line">
    			<!-- ::before: line number, ::after: indentation guides -->
    		</div>
    		<div class="pce-line"></div>
    	</code>
    </pre>

    Available CSS Classes

    • show-line-numbers: Applied if line numbers are enabled.
    • pce-wrap: Applied if word wrap is enabled.
    • pce-nowrap: Applied if word wrap is disabled.
    • pce-preserve: Applied if preserveIndent is enabled.
    • pce-guides: Applied if guideIndents is enabled.
    • pce-rtl: Applied if the rtl option is true.
  9. Choose between framework rewrites and the core library

    main

    The prism-code-editor library has dedicated rewrites for React (prism-react-editor) and SolidJS (solid-prism-editor).

    Key Considerations:

    • Integration: The rewrites are recommended for React and SolidJS users as they integrate more deeply with the framework lifecycle than a generic wrapper.
    • API Differences: While they support the same extensions and behave nearly identically, the methods for creating editors and adding extensions differ. Refer to the specific package READMEs for API details.
    • Performance: The rewrites maintain high performance by using manual DOM manipulation instead of relying heavily on JSX, making them nearly as fast as the original.
    • SSR Compatibility: Because they avoid heavy JSX usage for performance, they do not work well with standard SSR, but they can still be used within frameworks like Next.js and SolidStart.
  10. How prism-code-editor works

    main

    The editor works by overlaying syntax-highlighted code over a standard <textarea>.

    Key architectural advantages include:

    • Lightweight Prism Core: Uses a trimmed version of Prism that is less than 1/3 the size and does not rely on global variables.
    • Efficient DOM Updates: The library splits highlighted code into individual lines. This allows it to update only the lines that have changed in the DOM, improving performance.
    • Runtime Language Resolution: Re-exports Prism languages that automatically import required dependencies, resolving embedded languages at runtime.