summaryrefslogtreecommitdiffhomepage
path: root/.rules/docs/obsidian/editor-api.md
diff options
context:
space:
mode:
Diffstat (limited to '.rules/docs/obsidian/editor-api.md')
-rw-r--r--.rules/docs/obsidian/editor-api.md166
1 files changed, 166 insertions, 0 deletions
diff --git a/.rules/docs/obsidian/editor-api.md b/.rules/docs/obsidian/editor-api.md
new file mode 100644
index 0000000..8db6463
--- /dev/null
+++ b/.rules/docs/obsidian/editor-api.md
@@ -0,0 +1,166 @@
+# Obsidian Editor API
+
+## Editor Class
+
+Access via `MarkdownView.editor` or through editor commands. Abstracts CodeMirror 5/6.
+
+```typescript
+// Get editor from active view
+const view = this.app.workspace.getActiveViewOfType(MarkdownView);
+if (view) {
+ const editor = view.editor;
+ // ...
+}
+
+// Or use editorCallback in commands
+this.addCommand({
+ id: 'my-cmd',
+ name: 'My Command',
+ editorCallback: (editor: Editor, ctx: MarkdownView | MarkdownFileInfo) => {
+ // editor is available here
+ },
+});
+```
+
+### Cursor & Selection
+
+| Method | Returns | Description |
+|--------|---------|-------------|
+| `getCursor(side?)` | `EditorPosition` | Get cursor position. `side`: `'from'`, `'to'`, `'head'`, `'anchor'` |
+| `setCursor(pos)` | `void` | Set cursor position |
+| `getSelection()` | `string` | Get selected text |
+| `setSelection(anchor, head?)` | `void` | Set selection range |
+| `setSelections(ranges, main?)` | `void` | Set multiple selections |
+| `listSelections()` | `EditorSelection[]` | Get all selections |
+| `somethingSelected()` | `boolean` | Check if anything is selected |
+| `wordAt(pos)` | `EditorRange \| null` | Get word boundaries at position |
+
+### EditorPosition
+
+```typescript
+interface EditorPosition {
+ line: number; // 0-based line number
+ ch: number; // 0-based character offset in line
+}
+```
+
+### Reading Content
+
+| Method | Returns | Description |
+|--------|---------|-------------|
+| `getValue()` | `string` | Entire document content |
+| `getLine(line)` | `string` | Text at line (0-indexed) |
+| `getRange(from, to)` | `string` | Text in range |
+| `lineCount()` | `number` | Total lines |
+| `lastLine()` | `number` | Last line number |
+
+### Modifying Content
+
+| Method | Description |
+|--------|-------------|
+| `setValue(content)` | Replace entire document |
+| `setLine(n, text)` | Replace line content |
+| `replaceRange(text, from, to?, origin?)` | Replace text in range. If only `from`, inserts at position. |
+| `replaceSelection(text, origin?)` | Replace current selection |
+| `transaction(tx, origin?)` | Batch multiple changes atomically |
+| `processLines(read, write, ignoreEmpty?)` | Process each line |
+
+### Navigation
+
+| Method | Description |
+|--------|-------------|
+| `scrollTo(x, y)` | Scroll to position |
+| `scrollIntoView(range, center?)` | Scroll range into view |
+| `getScrollInfo()` | Get current scroll info |
+| `posToOffset(pos)` | Convert position to character offset |
+| `offsetToPos(offset)` | Convert character offset to position |
+
+### Other
+
+| Method | Description |
+|--------|-------------|
+| `focus()` / `blur()` | Focus/blur editor |
+| `hasFocus()` | Check if editor has focus |
+| `undo()` / `redo()` | Undo/redo |
+| `exec(command)` | Execute an editor command |
+| `refresh()` | Refresh editor display |
+
+### Common Patterns
+
+**Insert at cursor:**
+```typescript
+editor.replaceRange(text, editor.getCursor());
+```
+
+**Replace selection:**
+```typescript
+const sel = editor.getSelection();
+editor.replaceSelection(sel.toUpperCase());
+```
+
+**Insert at end of document:**
+```typescript
+const lastLine = editor.lastLine();
+const lastLineText = editor.getLine(lastLine);
+editor.replaceRange('\nNew content', { line: lastLine, ch: lastLineText.length });
+```
+
+## Markdown Post Processing
+
+Change how markdown renders in Reading view.
+
+### Post Processor
+
+```typescript
+this.registerMarkdownPostProcessor((element: HTMLElement, context: MarkdownPostProcessorContext) => {
+ // element = rendered HTML fragment
+ // Modify DOM as needed
+ const codeblocks = element.findAll('code');
+ for (const block of codeblocks) {
+ // Transform code blocks
+ }
+});
+```
+
+### Code Block Processor
+
+Register custom fenced code block handlers (like Mermaid):
+
+```typescript
+this.registerMarkdownCodeBlockProcessor('csv', (source: string, el: HTMLElement, ctx) => {
+ // source = raw text inside the code block
+ // el = container div (replaces <pre><code>)
+ const rows = source.split('\n').filter(r => r.length > 0);
+ const table = el.createEl('table');
+ // Build table from CSV data...
+});
+```
+
+Usage in markdown:
+````
+```csv
+Name,Age
+Alice,30
+Bob,25
+```
+````
+
+## MarkdownRenderer
+
+Static utility for rendering markdown to HTML:
+
+```typescript
+import { MarkdownRenderer } from 'obsidian';
+
+// Render markdown string to element
+await MarkdownRenderer.render(
+ this.app, // App instance
+ '**bold** text', // Markdown string
+ containerEl, // Target HTMLElement
+ sourcePath, // Source file path (for link resolution)
+ this // Component (for lifecycle management)
+);
+
+// Alternative (older API)
+await MarkdownRenderer.renderMarkdown(markdown, el, sourcePath, component);
+```