Code Block Plugin
The CodeBlockPlugin adds fenced code blocks with a non-editable header (language label + copy button), keyboard-driven indentation, Markdown input rules, and full color theming.
import { CodeBlockPlugin } from '@notectl/core';
// Default (dark theme)new CodeBlockPlugin()
// Light themenew CodeBlockPlugin({ background: '#f8f9fa', headerBackground: '#e9ecef', textColor: '#212529', headerColor: '#868e96',})Configuration
Section titled “Configuration”interface CodeBlockConfig { /** Optional syntax highlighter implementation. */ readonly highlighter?: SyntaxHighlighter; /** Default language when creating new code blocks. */ readonly defaultLanguage?: string; /** Use spaces instead of tabs for indentation. */ readonly useSpaces?: boolean; /** Number of spaces per indent level (default: 2). */ readonly spaceCount?: number; /** Show the copy button in the header (default: true). */ readonly showCopyButton?: boolean; /** Render separator after toolbar item. */ readonly separatorAfter?: boolean; /** Body background color (overrides --notectl-code-block-bg). */ readonly background?: string; /** Header background color (overrides --notectl-code-block-header-bg). */ readonly headerBackground?: string; /** Code text color (overrides --notectl-code-block-color). */ readonly textColor?: string; /** Header/label text color (overrides --notectl-code-block-header-color). */ readonly headerColor?: string; /** Customize keyboard bindings for code block actions. */ readonly keymap?: CodeBlockKeymap; /** Locale override for user-facing strings. */ readonly locale?: CodeBlockLocale;}
interface CodeBlockKeymap { /** Insert a paragraph below the code block. Default: 'Mod-Enter'. Set to null to disable. */ readonly insertAfter?: string | null; /** Toggle between code block and paragraph. Default: 'Mod-Shift-M'. Set to null to disable. */ readonly toggle?: string | null;}Custom Keybindings
Section titled “Custom Keybindings”Override or disable the default code block shortcuts:
new CodeBlockPlugin({ keymap: { insertAfter: 'Mod-Shift-Enter', // override default Mod-Enter toggle: 'Mod-Shift-C', // override default Mod-Shift-M },})Set a binding to null to disable it entirely:
new CodeBlockPlugin({ keymap: { insertAfter: null, // disable insert-after shortcut toggle: 'Mod-Shift-C', },})Mod resolves to Cmd on macOS and Ctrl on Windows/Linux.
Theming
Section titled “Theming”There are two ways to customize code block colors:
Option 1: Plugin Config
Section titled “Option 1: Plugin Config”Pass colors directly in the constructor. Best for fixed application themes.
new CodeBlockPlugin({ background: '#f8f9fa', headerBackground: '#e9ecef', textColor: '#212529', headerColor: '#868e96',})Option 2: CSS Custom Properties
Section titled “Option 2: CSS Custom Properties”Set CSS variables on the <notectl-editor> element. Best for dynamic theming (dark/light mode toggle, media queries).
notectl-editor { --notectl-code-block-bg: #f8f9fa; --notectl-code-block-header-bg: #e9ecef; --notectl-code-block-color: #212529; --notectl-code-block-header-color: #868e96; --notectl-code-block-header-border: #dee2e6;}Or responsive with media queries:
@media (prefers-color-scheme: light) { notectl-editor { --notectl-code-block-bg: #f8f9fa; --notectl-code-block-color: #212529; --notectl-code-block-header-bg: #e9ecef; --notectl-code-block-header-color: #868e96; }}
@media (prefers-color-scheme: dark) { notectl-editor { --notectl-code-block-bg: #1e1e2e; --notectl-code-block-color: #cdd6f4; --notectl-code-block-header-bg: rgba(255, 255, 255, 0.06); --notectl-code-block-header-color: #7f849c; }}Available CSS Custom Properties
Section titled “Available CSS Custom Properties”| Property | Default | Description |
|---|---|---|
--notectl-code-block-bg | #1e1e2e | Body background |
--notectl-code-block-color | #cdd6f4 | Code text color |
--notectl-code-block-header-bg | rgba(255,255,255,0.06) | Header background |
--notectl-code-block-header-color | #7f849c | Header label and copy button color |
--notectl-code-block-header-border | rgba(255,255,255,0.08) | Header bottom border |
Priority
Section titled “Priority”When both methods are used, plugin config wins because it sets inline CSS custom properties on each <pre> element:
- CSS defaults in stylesheet (lowest)
- External CSS custom properties on
notectl-editor - Plugin config (highest)
Commands
Section titled “Commands”| Command | Description | Returns |
|---|---|---|
toggleCodeBlock | Toggle between paragraph and code block | boolean |
insertCodeBlock | Convert the current block to a code block | boolean |
exitCodeBlock | Exit the code block (same as Escape) | boolean |
setCodeBlockLanguage | Reserved — use the Service API instead | false |
setCodeBlockBackground | Reserved — use the Service API instead | false |
editor.executeCommand('toggleCodeBlock');Keyboard Shortcuts
Section titled “Keyboard Shortcuts”| Shortcut | Action |
|---|---|
Ctrl+Shift+M / Cmd+Shift+M | Toggle code block (configurable via keymap.toggle) |
Enter | Insert newline within code block |
Enter (twice, on empty last line) | Exit code block, create paragraph below |
Tab | Insert indent (tab or spaces) |
Shift+Tab | Remove indent from current line |
Ctrl+Enter / Cmd+Enter | Insert paragraph below and move cursor there (configurable via keymap.insertAfter) |
Escape | Exit code block to next block or new paragraph |
ArrowDown (on last line) | Exit code block to next block or new paragraph |
ArrowUp (on first line) | Exit to previous block |
ArrowRight (at end) | Exit code block to next block |
ArrowLeft (at start) | Exit code block to previous block |
Backspace (at position 0) | Convert code block back to paragraph |
Input Rules
Section titled “Input Rules”| Pattern | Result |
|---|---|
``` + Space | Create empty code block |
```typescript + Space | Create code block with language set to “typescript” |
Toolbar
Section titled “Toolbar”The code block button appears in the block toolbar group with the </> icon. It shows as active when the cursor is inside a code block.
Node Spec
Section titled “Node Spec”| Type | HTML Tag | Attributes | Description |
|---|---|---|---|
code_block | <pre><code> | language, backgroundColor | Fenced code block |
Service API
Section titled “Service API”The plugin registers a typed service for programmatic access:
import { CODE_BLOCK_SERVICE_KEY } from '@notectl/core';
const service = context.getService(CODE_BLOCK_SERVICE_KEY);
service.setLanguage(blockId, 'python');service.getLanguage(blockId); // 'python'service.setBackground(blockId, '#282c34');service.getBackground(blockId); // '#282c34'service.isCodeBlock(blockId); // trueservice.getSupportedLanguages(); // ['typescript', 'python', ...]Syntax Highlighting
Section titled “Syntax Highlighting”Provide a SyntaxHighlighter implementation to enable token-based highlighting:
interface SyntaxHighlighter { tokenize(code: string, language: string): readonly SyntaxToken[]; getSupportedLanguages(): readonly string[];}
interface SyntaxToken { readonly from: number; readonly to: number; readonly type: string; // e.g. 'keyword', 'string', 'number', 'comment'}The plugin generates decoration classes like notectl-token--keyword, notectl-token--string, etc. Style them in your CSS:
notectl-editor .notectl-token--keyword { color: #c678dd; }notectl-editor .notectl-token--string { color: #98c379; }notectl-editor .notectl-token--number { color: #d19a66; }notectl-editor .notectl-token--comment { color: #5c6370; font-style: italic; }Mark Prevention
Section titled “Mark Prevention”The plugin automatically prevents formatting marks (bold, italic, underline, etc.) from being applied inside code blocks via middleware.