vim-sim 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +507 -0
- package/dist/index.d.ts +1380 -0
- package/dist/index.js +6928 -0
- package/dist/index.js.map +1 -0
- package/docs/ADVANCED-FEATURES-COMPLETE.md +547 -0
- package/docs/ADVANCED-FEATURES.md +460 -0
- package/docs/DEPLOYMENT-READY.md +194 -0
- package/docs/FINAL-SUMMARY.md +318 -0
- package/docs/IMPLEMENTATION-SUMMARY.md +298 -0
- package/docs/PARAGRAPH-MOTIONS-FIX.md +238 -0
- package/docs/QUICK-FIXES-SUMMARY.md +184 -0
- package/docs/QUICK-START-ADVANCED.md +260 -0
- package/docs/TEST-ANALYSIS-SUMMARY.md +213 -0
- package/docs/TEST-FAILURES-ANALYSIS.md +373 -0
- package/docs/TODO-COMPLETION-SUMMARY.md +326 -0
- package/package.json +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/Modes.ts","../src/core/buffer.ts","../src/core/cursor.ts","../src/core/viewport.ts","../src/types/Fold.ts","../src/types/Mark.ts","../src/types/JumpList.ts","../src/types/FileSystem.ts","../src/types/Window.ts","../src/types/SpellChecker.ts","../src/types/CompletionManager.ts","../src/core/state.ts","../src/core/insert.ts","../src/types/TextObject.ts","../src/types/Command.ts","../src/core/motion.ts","../src/utils/character.ts","../src/utils/cursor-state.ts","../src/utils/cursor-movement.ts","../src/utils/search.ts","../src/utils/word-navigation.ts","../src/utils/line-navigation.ts","../src/utils/buffer-operations.ts","../src/utils/range-utils.ts","../src/utils/state-utils.ts","../src/motions/word.ts","../src/motions/basic.ts","../src/registers/register.ts","../src/registers/manager.ts","../src/history/change.ts","../src/history/undotree.ts","../src/core/indent-manager.ts","../src/core/config-manager.ts","../src/core/mode-transition.ts","../src/commands/mode-commands.ts","../src/core/operator.ts","../src/operators/delete.ts","../src/core/command.ts","../src/commands/basic-edit.ts","../src/commands/number-ops.ts","../src/commands/macros.ts","../src/operators/yank.ts","../src/operators/change.ts","../src/operators/paste.ts","../src/motions/find.ts","../src/motions/screen.ts","../src/motions/extended.ts","../src/motions/paragraph.ts","../src/motions/search.ts","../src/commands/scroll.ts","../src/commands/visual.ts","../src/operators/case.ts","../src/operators/indent.ts","../src/textobjects/word.ts","../src/textobjects/sentence.ts","../src/commands/misc.ts","../src/commands/fold.ts","../src/commands/marks.ts","../src/commands/file.ts","../src/commands/window.ts","../src/core/session.ts","../src/core/registry.ts"],"sourcesContent":["export enum Mode {\n NORMAL,\n INSERT,\n VISUAL,\n VISUAL_LINE,\n VISUAL_BLOCK,\n REPLACE,\n COMMAND\n}","export class Buffer {\n constructor(public content: string) {\n }\n\n getLineCount(): number {\n return this.content.split('\\n').length;\n }\n}","export class Cursor {\n constructor(public line: number, public column: number) {\n }\n}","export class VimViewport {\n constructor(public topLine: number = 0, public height: number = 24) {\n }\n\n scrollToLine(line: number) {\n if (line < this.topLine) {\n this.topLine = line;\n } else if (line >= this.topLine + this.height) {\n this.topLine = line - this.height + 1;\n }\n }\n}","/**\n * Fold type definitions\n */\n\nexport interface Fold {\n /** Starting line of the fold (inclusive, 0-indexed) */\n startLine: number;\n /** Ending line of the fold (inclusive, 0-indexed) */\n endLine: number;\n /** Whether the fold is currently closed */\n isClosed: boolean;\n /** Nesting level (0 = top level) */\n level: number;\n}\n\n/**\n * Manager for tracking and manipulating folds in a buffer\n */\nexport class FoldManager {\n /** Array of folds, sorted by startLine */\n private folds: Fold[] = [];\n\n constructor(folds: Fold[] = []) {\n this.folds = [...folds].sort((a, b) => a.startLine - b.startLine);\n }\n\n /**\n * Get all folds\n */\n getFolds(): Fold[] {\n return [...this.folds];\n }\n\n /**\n * Create a new fold\n */\n createFold(startLine: number, endLine: number): FoldManager {\n if (startLine >= endLine) {\n return this; // Invalid fold\n }\n\n // Calculate nesting level based on existing folds\n let level = 0;\n for (const fold of this.folds) {\n if (fold.startLine < startLine && fold.endLine > endLine) {\n level = Math.max(level, fold.level + 1);\n }\n }\n\n const newFold: Fold = {\n startLine,\n endLine,\n isClosed: false,\n level\n };\n\n const newFolds = [...this.folds, newFold].sort((a, b) => a.startLine - b.startLine);\n return new FoldManager(newFolds);\n }\n\n /**\n * Find fold at a specific line\n */\n findFoldAtLine(line: number): Fold | null {\n // Find the innermost fold containing this line\n let innermost: Fold | null = null;\n let maxLevel = -1;\n\n for (const fold of this.folds) {\n if (fold.startLine <= line && fold.endLine >= line) {\n if (fold.level > maxLevel) {\n maxLevel = fold.level;\n innermost = fold;\n }\n }\n }\n\n return innermost;\n }\n\n /**\n * Open fold at line\n */\n openFold(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n const newFolds = this.folds.map(f =>\n f === fold ? { ...f, isClosed: false } : f\n );\n return new FoldManager(newFolds);\n }\n\n /**\n * Open fold and all nested folds recursively\n */\n openFoldRecursive(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n const newFolds = this.folds.map(f => {\n // Open this fold and any folds nested within it\n if (f.startLine >= fold.startLine && f.endLine <= fold.endLine) {\n return { ...f, isClosed: false };\n }\n return f;\n });\n return new FoldManager(newFolds);\n }\n\n /**\n * Close fold at line\n */\n closeFold(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n const newFolds = this.folds.map(f =>\n f === fold ? { ...f, isClosed: true } : f\n );\n return new FoldManager(newFolds);\n }\n\n /**\n * Close fold and all nested folds recursively\n */\n closeFoldRecursive(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n const newFolds = this.folds.map(f => {\n // Close this fold and any folds nested within it\n if (f.startLine >= fold.startLine && f.endLine <= fold.endLine) {\n return { ...f, isClosed: true };\n }\n return f;\n });\n return new FoldManager(newFolds);\n }\n\n /**\n * Toggle fold at line\n */\n toggleFold(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n return fold.isClosed ? this.openFold(line) : this.closeFold(line);\n }\n\n /**\n * Toggle fold and nested folds recursively\n */\n toggleFoldRecursive(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n return fold.isClosed ? this.openFoldRecursive(line) : this.closeFoldRecursive(line);\n }\n\n /**\n * Delete fold at line\n */\n deleteFold(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n const newFolds = this.folds.filter(f => f !== fold);\n return new FoldManager(newFolds);\n }\n\n /**\n * Delete fold and all nested folds recursively\n */\n deleteFoldRecursive(line: number): FoldManager {\n const fold = this.findFoldAtLine(line);\n if (!fold) return this;\n\n const newFolds = this.folds.filter(f => {\n // Remove this fold and any folds nested within it\n return !(f.startLine >= fold.startLine && f.endLine <= fold.endLine);\n });\n return new FoldManager(newFolds);\n }\n\n /**\n * Open all folds\n */\n openAllFolds(): FoldManager {\n const newFolds = this.folds.map(f => ({ ...f, isClosed: false }));\n return new FoldManager(newFolds);\n }\n\n /**\n * Close all folds\n */\n closeAllFolds(): FoldManager {\n const newFolds = this.folds.map(f => ({ ...f, isClosed: true }));\n return new FoldManager(newFolds);\n }\n\n /**\n * Open folds up to a certain level\n */\n openFoldsToLevel(maxLevel: number): FoldManager {\n const newFolds = this.folds.map(f => ({\n ...f,\n isClosed: f.level > maxLevel ? f.isClosed : false\n }));\n return new FoldManager(newFolds);\n }\n\n /**\n * Close folds from a certain level\n */\n closeFoldsFromLevel(minLevel: number): FoldManager {\n const newFolds = this.folds.map(f => ({\n ...f,\n isClosed: f.level >= minLevel ? true : f.isClosed\n }));\n return new FoldManager(newFolds);\n }\n\n /**\n * Open folds to view a specific line\n */\n openToViewLine(line: number): FoldManager {\n const newFolds = this.folds.map(f => {\n // Open any fold that contains this line\n if (f.startLine <= line && f.endLine >= line) {\n return { ...f, isClosed: false };\n }\n return f;\n });\n return new FoldManager(newFolds);\n }\n\n /**\n * Find next fold starting after a given line\n */\n findNextFold(line: number): Fold | null {\n for (const fold of this.folds) {\n if (fold.startLine > line) {\n return fold;\n }\n }\n return null;\n }\n\n /**\n * Find previous fold starting before a given line\n */\n findPrevFold(line: number): Fold | null {\n for (let i = this.folds.length - 1; i >= 0; i--) {\n const fold = this.folds[i];\n if (fold && fold.startLine < line) {\n return fold;\n }\n }\n return null;\n }\n\n /**\n * Check if a line is hidden (inside a closed fold)\n */\n isLineHidden(line: number): boolean {\n for (const fold of this.folds) {\n if (fold.isClosed && line > fold.startLine && line <= fold.endLine) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get visible lines (accounting for closed folds)\n * Returns array of line numbers that should be visible\n */\n getVisibleLines(totalLines: number): number[] {\n const visible: number[] = [];\n for (let i = 0; i < totalLines; i++) {\n if (!this.isLineHidden(i)) {\n visible.push(i);\n }\n }\n return visible;\n }\n}\n","import {Cursor} from \"../core/cursor\";\n\n/**\n * Mark type definitions\n */\n\nexport interface Mark {\n /** The cursor position of the mark */\n position: Cursor;\n /** Optional buffer identifier (for global marks) */\n bufferId?: string;\n}\n\n/**\n * Manager for tracking and manipulating marks in a buffer\n */\nexport class MarkManager {\n /** Map of mark names to their positions */\n private marks: Map<string, Mark>;\n\n constructor(marks: Map<string, Mark> = new Map()) {\n this.marks = new Map(marks);\n }\n\n /**\n * Set a mark at a position\n * @param name - Mark name (a-z for local, A-Z for global)\n * @param position - Cursor position\n * @param bufferId - Optional buffer ID for global marks\n */\n setMark(name: string, position: Cursor, bufferId?: string): MarkManager {\n // Validate mark name (a-z, A-Z, or special marks like `, ', etc.)\n if (!this.isValidMarkName(name)) {\n return this;\n }\n\n const newMarks = new Map(this.marks);\n const mark: Mark = {\n position: { ...position },\n ...(bufferId !== undefined && { bufferId })\n };\n newMarks.set(name, mark);\n\n return new MarkManager(newMarks);\n }\n\n /**\n * Get a mark by name\n */\n getMark(name: string): Mark | undefined {\n return this.marks.get(name);\n }\n\n /**\n * Check if a mark exists\n */\n hasMark(name: string): boolean {\n return this.marks.has(name);\n }\n\n /**\n * Delete a mark\n */\n deleteMark(name: string): MarkManager {\n const newMarks = new Map(this.marks);\n newMarks.delete(name);\n return new MarkManager(newMarks);\n }\n\n /**\n * Delete all marks\n */\n deleteAllMarks(): MarkManager {\n return new MarkManager();\n }\n\n /**\n * Delete all marks in a range\n */\n deleteMarksInRange(startLine: number, endLine: number): MarkManager {\n const newMarks = new Map<string, Mark>();\n\n for (const [name, mark] of this.marks) {\n const line = mark.position.line;\n if (line < startLine || line > endLine) {\n newMarks.set(name, mark);\n }\n }\n\n return new MarkManager(newMarks);\n }\n\n /**\n * Get all marks\n */\n getAllMarks(): Map<string, Mark> {\n return new Map(this.marks);\n }\n\n /**\n * Get local marks (a-z)\n */\n getLocalMarks(): Map<string, Mark> {\n const local = new Map<string, Mark>();\n for (const [name, mark] of this.marks) {\n if (this.isLocalMark(name)) {\n local.set(name, mark);\n }\n }\n return local;\n }\n\n /**\n * Get global marks (A-Z)\n */\n getGlobalMarks(): Map<string, Mark> {\n const global = new Map<string, Mark>();\n for (const [name, mark] of this.marks) {\n if (this.isGlobalMark(name)) {\n global.set(name, mark);\n }\n }\n return global;\n }\n\n /**\n * Check if a mark name is valid\n */\n private isValidMarkName(name: string): boolean {\n if (name.length !== 1) return false;\n\n // a-z: local marks\n // A-Z: global marks\n // Special marks: `, ', <, >, [, ], ^, ., etc.\n const code = name.charCodeAt(0);\n const isLowercase = code >= 97 && code <= 122; // a-z\n const isUppercase = code >= 65 && code <= 90; // A-Z\n const specialMarks = ['`', \"'\", '<', '>', '[', ']', '^', '.', '\"'];\n\n return isLowercase || isUppercase || specialMarks.includes(name);\n }\n\n /**\n * Check if a mark is a local mark (a-z)\n */\n private isLocalMark(name: string): boolean {\n const code = name.charCodeAt(0);\n return code >= 97 && code <= 122; // a-z\n }\n\n /**\n * Check if a mark is a global mark (A-Z)\n */\n private isGlobalMark(name: string): boolean {\n const code = name.charCodeAt(0);\n return code >= 65 && code <= 90; // A-Z\n }\n\n /**\n * Update mark positions when lines are inserted\n * Shifts marks after the insertion point\n */\n adjustMarksAfterInsert(insertLine: number, numLines: number): MarkManager {\n const newMarks = new Map<string, Mark>();\n\n for (const [name, mark] of this.marks) {\n if (mark.position.line >= insertLine) {\n // Shift mark down\n newMarks.set(name, {\n ...mark,\n position: {\n line: mark.position.line + numLines,\n column: mark.position.column\n }\n });\n } else {\n newMarks.set(name, mark);\n }\n }\n\n return new MarkManager(newMarks);\n }\n\n /**\n * Update mark positions when lines are deleted\n * Removes marks in deleted range and shifts marks after deletion\n */\n adjustMarksAfterDelete(startLine: number, endLine: number): MarkManager {\n const newMarks = new Map<string, Mark>();\n const numDeleted = endLine - startLine + 1;\n\n for (const [name, mark] of this.marks) {\n const line = mark.position.line;\n\n if (line < startLine) {\n // Mark is before deletion, keep as is\n newMarks.set(name, mark);\n } else if (line > endLine) {\n // Mark is after deletion, shift up\n newMarks.set(name, {\n ...mark,\n position: {\n line: line - numDeleted,\n column: mark.position.column\n }\n });\n }\n // Marks in the deleted range are removed (not added to newMarks)\n }\n\n return new MarkManager(newMarks);\n }\n\n /**\n * Set automatic marks\n * These are special marks that vim sets automatically\n */\n setAutomaticMark(name: string, position: Cursor): MarkManager {\n // Special marks that are automatically set by vim:\n // ` - position before last jump\n // ' - position before last jump (line)\n // [ - start of last changed/yanked text\n // ] - end of last changed/yanked text\n // < - start of last visual selection\n // > - end of last visual selection\n // . - position of last change\n // ^ - position where insert mode was last stopped\n // \" - position when last exiting buffer\n\n const automaticMarks = ['`', \"'\", '[', ']', '<', '>', '.', '^', '\"'];\n\n if (!automaticMarks.includes(name)) {\n return this;\n }\n\n return this.setMark(name, position);\n }\n}\n","import {Cursor} from \"../core/cursor\";\n\n/**\n * Jump list type definitions\n */\n\nexport interface Jump {\n /** The cursor position of the jump */\n position: Cursor;\n /** Optional buffer identifier */\n bufferId?: string;\n /** Timestamp when jump was created */\n timestamp: number;\n}\n\n/**\n * Manager for tracking and navigating the jump list\n *\n * The jump list is automatically maintained by Vim to track \"jumps\" -\n * movements that cross multiple lines (like G, gg, %, searches, marks)\n */\nexport class JumpListManager {\n /** Array of jumps in chronological order */\n private jumps: Jump[];\n /** Current position in the jump list (null if at most recent position) */\n private currentIndex: number | null;\n /** Maximum number of jumps to keep */\n private readonly maxJumps: number = 100;\n\n constructor(jumps: Jump[] = [], currentIndex: number | null = null) {\n this.jumps = [...jumps];\n this.currentIndex = currentIndex;\n }\n\n /**\n * Add a jump to the list\n * This removes any \"future\" jumps if we're in the middle of the list\n */\n addJump(position: Cursor, bufferId?: string): JumpListManager {\n const newJump: Jump = {\n position: { ...position },\n ...(bufferId !== undefined && { bufferId }),\n timestamp: Date.now()\n };\n\n // If we're in the middle of the jump list, discard everything after current position\n let newJumps: Jump[];\n if (this.currentIndex !== null) {\n newJumps = this.jumps.slice(0, this.currentIndex + 1);\n } else {\n newJumps = [...this.jumps];\n }\n\n // Add the new jump\n newJumps.push(newJump);\n\n // Keep only the most recent maxJumps\n if (newJumps.length > this.maxJumps) {\n newJumps = newJumps.slice(newJumps.length - this.maxJumps);\n }\n\n // Reset current index to null (we're at the newest position)\n return new JumpListManager(newJumps, null);\n }\n\n /**\n * Jump backward in the list (Ctrl-o)\n * Returns the jump position to go to, or null if can't go back\n */\n jumpBackward(): { manager: JumpListManager; position: Cursor | null } {\n if (this.jumps.length === 0) {\n return { manager: this, position: null };\n }\n\n // If we're at the most recent position (currentIndex is null),\n // we need to go back to the last jump\n if (this.currentIndex === null) {\n if (this.jumps.length === 0) {\n return { manager: this, position: null };\n }\n const newIndex = this.jumps.length - 1;\n return {\n manager: new JumpListManager(this.jumps, newIndex),\n position: this.jumps[newIndex]?.position ?? null\n };\n }\n\n // We're already in the jump list, go back one more\n if (this.currentIndex > 0) {\n const newIndex = this.currentIndex - 1;\n return {\n manager: new JumpListManager(this.jumps, newIndex),\n position: this.jumps[newIndex]?.position ?? null\n };\n }\n\n // Already at the oldest jump\n return { manager: this, position: null };\n }\n\n /**\n * Jump forward in the list (Ctrl-i)\n * Returns the jump position to go to, or null if can't go forward\n */\n jumpForward(): { manager: JumpListManager; position: Cursor | null } {\n if (this.currentIndex === null) {\n // Already at the most recent position\n return { manager: this, position: null };\n }\n\n // Move forward one jump\n const newIndex = this.currentIndex + 1;\n\n if (newIndex >= this.jumps.length) {\n // Moving past the end means we're back at the most recent position\n return {\n manager: new JumpListManager(this.jumps, null),\n position: null // Caller should use current cursor position\n };\n }\n\n return {\n manager: new JumpListManager(this.jumps, newIndex),\n position: this.jumps[newIndex]?.position ?? null\n };\n }\n\n /**\n * Get the current jump position (if in the middle of the list)\n */\n getCurrentJump(): Jump | null {\n if (this.currentIndex === null) {\n return null;\n }\n return this.jumps[this.currentIndex] ?? null;\n }\n\n /**\n * Get all jumps\n */\n getAllJumps(): Jump[] {\n return [...this.jumps];\n }\n\n /**\n * Get current index in jump list\n */\n getCurrentIndex(): number | null {\n return this.currentIndex;\n }\n\n /**\n * Check if we can jump backward\n */\n canJumpBackward(): boolean {\n if (this.jumps.length === 0) {\n return false;\n }\n if (this.currentIndex === null) {\n return this.jumps.length > 0;\n }\n return this.currentIndex > 0;\n }\n\n /**\n * Check if we can jump forward\n */\n canJumpForward(): boolean {\n return this.currentIndex !== null;\n }\n\n /**\n * Update jump positions when lines are inserted\n */\n adjustJumpsAfterInsert(insertLine: number, numLines: number): JumpListManager {\n const newJumps = this.jumps.map(jump => {\n if (jump.position.line >= insertLine) {\n return {\n ...jump,\n position: {\n line: jump.position.line + numLines,\n column: jump.position.column\n }\n };\n }\n return jump;\n });\n\n return new JumpListManager(newJumps, this.currentIndex);\n }\n\n /**\n * Update jump positions when lines are deleted\n */\n adjustJumpsAfterDelete(startLine: number, endLine: number): JumpListManager {\n const numDeleted = endLine - startLine + 1;\n const newJumps: Jump[] = [];\n\n for (const jump of this.jumps) {\n const line = jump.position.line;\n\n if (line < startLine) {\n // Jump is before deletion, keep as is\n newJumps.push(jump);\n } else if (line > endLine) {\n // Jump is after deletion, shift up\n newJumps.push({\n ...jump,\n position: {\n line: line - numDeleted,\n column: jump.position.column\n }\n });\n }\n // Jumps in the deleted range are removed\n }\n\n // Adjust current index if needed\n let newIndex = this.currentIndex;\n if (newIndex !== null && newIndex >= newJumps.length) {\n newIndex = newJumps.length > 0 ? newJumps.length - 1 : null;\n }\n\n return new JumpListManager(newJumps, newIndex);\n }\n\n /**\n * Clear the jump list\n */\n clear(): JumpListManager {\n return new JumpListManager();\n }\n\n /**\n * Check if a cursor movement should be considered a \"jump\"\n * (movements that cross multiple lines)\n */\n static isJumpMotion(fromLine: number, toLine: number, minLineDiff: number = 1): boolean {\n return Math.abs(toLine - fromLine) > minLineDiff;\n }\n}\n","import {Buffer} from \"../core/buffer\";\n\n/**\n * Represents a file in the simulated file system\n */\nexport interface VimFile {\n path: string;\n buffer: Buffer;\n modified: boolean;\n readonly: boolean;\n}\n\n/**\n * Manages the simulated file system with multiple buffers\n * Immutable operations return new FileSystemManager instances\n */\nexport class FileSystemManager {\n private files: Map<string, VimFile>;\n private currentFilePath: string | null;\n\n constructor(files: Map<string, VimFile> = new Map(), currentFilePath: string | null = null) {\n this.files = new Map(files);\n this.currentFilePath = currentFilePath;\n }\n\n /**\n * Create or open a file with the given path\n */\n openFile(path: string, content: string = '', readonly: boolean = false): FileSystemManager {\n const newFiles = new Map(this.files);\n\n // If file already exists, just switch to it\n if (newFiles.has(path)) {\n return new FileSystemManager(newFiles, path);\n }\n\n // Create new file\n const file: VimFile = {\n path,\n buffer: new Buffer(content),\n modified: false,\n readonly\n };\n newFiles.set(path, file);\n\n return new FileSystemManager(newFiles, path);\n }\n\n /**\n * Update the buffer content for the current file\n */\n updateCurrentBuffer(buffer: Buffer, modified: boolean = true): FileSystemManager {\n if (!this.currentFilePath) {\n return this;\n }\n\n const currentFile = this.files.get(this.currentFilePath);\n if (!currentFile) {\n return this;\n }\n\n const newFiles = new Map(this.files);\n newFiles.set(this.currentFilePath, {\n ...currentFile,\n buffer,\n modified\n });\n\n return new FileSystemManager(newFiles, this.currentFilePath);\n }\n\n /**\n * Save the current file (mark as not modified)\n */\n saveCurrentFile(): FileSystemManager {\n if (!this.currentFilePath) {\n return this;\n }\n\n const currentFile = this.files.get(this.currentFilePath);\n if (!currentFile) {\n return this;\n }\n\n const newFiles = new Map(this.files);\n newFiles.set(this.currentFilePath, {\n ...currentFile,\n modified: false\n });\n\n return new FileSystemManager(newFiles, this.currentFilePath);\n }\n\n /**\n * Close the current file\n */\n closeCurrentFile(): { manager: FileSystemManager; success: boolean; message?: string } {\n if (!this.currentFilePath) {\n return { manager: this, success: false, message: 'No file to close' };\n }\n\n const currentFile = this.files.get(this.currentFilePath);\n if (!currentFile) {\n return { manager: this, success: false, message: 'File not found' };\n }\n\n // Check if file is modified\n if (currentFile.modified) {\n return {\n manager: this,\n success: false,\n message: `No write since last change (add ! to override)`\n };\n }\n\n const newFiles = new Map(this.files);\n newFiles.delete(this.currentFilePath);\n\n // Switch to another file or null\n const remainingFiles = Array.from(newFiles.keys());\n const newCurrentPath = remainingFiles.length > 0 ? remainingFiles[0] : null;\n\n return {\n manager: new FileSystemManager(newFiles, newCurrentPath),\n success: true\n };\n }\n\n /**\n * Force close the current file (ignore modifications)\n */\n forceCloseCurrentFile(): { manager: FileSystemManager; success: boolean } {\n if (!this.currentFilePath) {\n return { manager: this, success: false };\n }\n\n const newFiles = new Map(this.files);\n newFiles.delete(this.currentFilePath);\n\n // Switch to another file or null\n const remainingFiles = Array.from(newFiles.keys());\n const newCurrentPath = remainingFiles.length > 0 ? remainingFiles[0] : null;\n\n return {\n manager: new FileSystemManager(newFiles, newCurrentPath),\n success: true\n };\n }\n\n /**\n * Switch to a specific file by path\n */\n switchToFile(path: string): FileSystemManager {\n if (this.files.has(path)) {\n return new FileSystemManager(this.files, path);\n }\n return this;\n }\n\n /**\n * Get the current file\n */\n getCurrentFile(): VimFile | null {\n if (!this.currentFilePath) {\n return null;\n }\n return this.files.get(this.currentFilePath) || null;\n }\n\n /**\n * Get current file path\n */\n getCurrentPath(): string | null {\n return this.currentFilePath;\n }\n\n /**\n * Get all file paths\n */\n getAllPaths(): string[] {\n return Array.from(this.files.keys());\n }\n\n /**\n * Get number of open files\n */\n getFileCount(): number {\n return this.files.size;\n }\n\n /**\n * Check if current file is modified\n */\n isCurrentModified(): boolean {\n const currentFile = this.getCurrentFile();\n return currentFile ? currentFile.modified : false;\n }\n\n /**\n * Check if current file is readonly\n */\n isCurrentReadonly(): boolean {\n const currentFile = this.getCurrentFile();\n return currentFile ? currentFile.readonly : false;\n }\n\n /**\n * Get next file in the list (for buffer cycling)\n */\n getNextFilePath(): string | null {\n const paths = this.getAllPaths();\n if (paths.length === 0) return null;\n if (!this.currentFilePath) return paths[0] ?? null;\n\n const currentIndex = paths.indexOf(this.currentFilePath);\n const nextIndex = (currentIndex + 1) % paths.length;\n return paths[nextIndex] ?? null;\n }\n\n /**\n * Get previous file in the list (for buffer cycling)\n */\n getPreviousFilePath(): string | null {\n const paths = this.getAllPaths();\n if (paths.length === 0) return null;\n if (!this.currentFilePath) return paths[0] ?? null;\n\n const currentIndex = paths.indexOf(this.currentFilePath);\n const prevIndex = currentIndex === 0 ? paths.length - 1 : currentIndex - 1;\n return paths[prevIndex] ?? null;\n }\n}\n","/**\n * Represents the type of window split\n */\nexport enum SplitType {\n HORIZONTAL,\n VERTICAL\n}\n\n/**\n * Represents a window in the editor\n */\nexport interface Window {\n id: number;\n bufferId: string | null; // Which file/buffer is displayed\n cursorLine: number;\n cursorColumn: number;\n scrollOffset: number; // Top line visible in window\n width: number;\n height: number;\n}\n\n/**\n * Layout node for window tree structure\n */\nexport interface WindowLayout {\n type: 'leaf' | 'split';\n splitType?: SplitType;\n window?: Window;\n children?: [WindowLayout, WindowLayout]; // Exactly 2 children for splits\n}\n\n/**\n * Manages window splits and navigation\n * Immutable operations return new WindowManager instances\n */\nexport class WindowManager {\n private windows: Map<number, Window>;\n private layout: WindowLayout;\n private activeWindowId: number;\n private nextWindowId: number;\n\n constructor(\n windows: Map<number, Window> = new Map(),\n layout: WindowLayout | null = null,\n activeWindowId: number = 1,\n nextWindowId: number = 2\n ) {\n this.windows = new Map(windows);\n this.nextWindowId = nextWindowId;\n\n // Initialize with single window if no layout provided\n if (!layout && windows.size === 0) {\n const defaultWindow: Window = {\n id: 1,\n bufferId: null,\n cursorLine: 0,\n cursorColumn: 0,\n scrollOffset: 0,\n width: 80,\n height: 24\n };\n this.windows.set(1, defaultWindow);\n this.layout = {\n type: 'leaf',\n window: defaultWindow\n };\n this.activeWindowId = 1;\n } else {\n const defaultLayout: WindowLayout = { type: 'leaf' };\n const firstWindow = this.windows.get(1);\n if (firstWindow) {\n defaultLayout.window = firstWindow;\n }\n this.layout = layout || defaultLayout;\n this.activeWindowId = activeWindowId;\n }\n }\n\n /**\n * Split the active window horizontally (above/below)\n */\n splitHorizontal(): WindowManager {\n const activeWindow = this.windows.get(this.activeWindowId);\n if (!activeWindow) return this;\n\n const newHeight = Math.floor(activeWindow.height / 2);\n const newWindow: Window = {\n id: this.nextWindowId,\n bufferId: activeWindow.bufferId,\n cursorLine: activeWindow.cursorLine,\n cursorColumn: activeWindow.cursorColumn,\n scrollOffset: activeWindow.scrollOffset,\n width: activeWindow.width,\n height: newHeight\n };\n\n const updatedActiveWindow: Window = {\n ...activeWindow,\n height: activeWindow.height - newHeight\n };\n\n const newWindows = new Map(this.windows);\n newWindows.set(activeWindow.id, updatedActiveWindow);\n newWindows.set(newWindow.id, newWindow);\n\n // Update layout\n const newLayout = this.replaceWindowInLayout(\n this.layout,\n activeWindow.id,\n {\n type: 'split',\n splitType: SplitType.HORIZONTAL,\n children: [\n { type: 'leaf', window: updatedActiveWindow },\n { type: 'leaf', window: newWindow }\n ]\n }\n );\n\n return new WindowManager(newWindows, newLayout, this.activeWindowId, this.nextWindowId + 1);\n }\n\n /**\n * Split the active window vertically (left/right)\n */\n splitVertical(): WindowManager {\n const activeWindow = this.windows.get(this.activeWindowId);\n if (!activeWindow) return this;\n\n const newWidth = Math.floor(activeWindow.width / 2);\n const newWindow: Window = {\n id: this.nextWindowId,\n bufferId: activeWindow.bufferId,\n cursorLine: activeWindow.cursorLine,\n cursorColumn: activeWindow.cursorColumn,\n scrollOffset: activeWindow.scrollOffset,\n width: newWidth,\n height: activeWindow.height\n };\n\n const updatedActiveWindow: Window = {\n ...activeWindow,\n width: activeWindow.width - newWidth\n };\n\n const newWindows = new Map(this.windows);\n newWindows.set(activeWindow.id, updatedActiveWindow);\n newWindows.set(newWindow.id, newWindow);\n\n // Update layout\n const newLayout = this.replaceWindowInLayout(\n this.layout,\n activeWindow.id,\n {\n type: 'split',\n splitType: SplitType.VERTICAL,\n children: [\n { type: 'leaf', window: updatedActiveWindow },\n { type: 'leaf', window: newWindow }\n ]\n }\n );\n\n return new WindowManager(newWindows, newLayout, this.activeWindowId, this.nextWindowId + 1);\n }\n\n /**\n * Close the active window\n */\n closeActiveWindow(): { manager: WindowManager; success: boolean; message?: string } {\n if (this.windows.size === 1) {\n return {\n manager: this,\n success: false,\n message: 'Cannot close last window'\n };\n }\n\n const newWindows = new Map(this.windows);\n newWindows.delete(this.activeWindowId);\n\n // Remove from layout and get sibling\n const { layout: newLayout, siblingId } = this.removeWindowFromLayout(\n this.layout,\n this.activeWindowId\n );\n\n // Switch to sibling window\n const newActiveId = siblingId || Array.from(newWindows.keys())[0];\n\n return {\n manager: new WindowManager(newWindows, newLayout, newActiveId, this.nextWindowId),\n success: true\n };\n }\n\n /**\n * Close all windows except the active one\n */\n closeOtherWindows(): WindowManager {\n const activeWindow = this.windows.get(this.activeWindowId);\n if (!activeWindow) return this;\n\n // Keep only active window\n const updatedWindow = {\n ...activeWindow,\n width: 80,\n height: 24\n };\n const newWindows = new Map([[this.activeWindowId, updatedWindow]]);\n\n const newLayout: WindowLayout = {\n type: 'leaf',\n window: updatedWindow\n };\n\n return new WindowManager(newWindows, newLayout, this.activeWindowId, this.nextWindowId);\n }\n\n /**\n * Navigate to the next window\n */\n cycleWindow(): WindowManager {\n const windowIds = Array.from(this.windows.keys()).sort();\n const currentIndex = windowIds.indexOf(this.activeWindowId);\n const nextIndex = (currentIndex + 1) % windowIds.length;\n const nextWindowId = windowIds[nextIndex];\n\n return new WindowManager(this.windows, this.layout, nextWindowId, this.nextWindowId);\n }\n\n /**\n * Navigate to window in a direction (h/j/k/l)\n */\n navigateWindow(direction: 'h' | 'j' | 'k' | 'l'): WindowManager {\n // Simple implementation: just cycle for now\n // A full implementation would consider window positions\n return this.cycleWindow();\n }\n\n /**\n * Update the active window\n */\n updateActiveWindow(updates: Partial<Window>): WindowManager {\n const activeWindow = this.windows.get(this.activeWindowId);\n if (!activeWindow) return this;\n\n const updatedWindow = { ...activeWindow, ...updates };\n const newWindows = new Map(this.windows);\n newWindows.set(this.activeWindowId, updatedWindow);\n\n // Update in layout\n const newLayout = this.updateWindowInLayout(this.layout, this.activeWindowId, updatedWindow);\n\n return new WindowManager(newWindows, newLayout, this.activeWindowId, this.nextWindowId);\n }\n\n /**\n * Get the active window\n */\n getActiveWindow(): Window | null {\n return this.windows.get(this.activeWindowId) || null;\n }\n\n /**\n * Get all windows\n */\n getAllWindows(): Window[] {\n return Array.from(this.windows.values());\n }\n\n /**\n * Get window count\n */\n getWindowCount(): number {\n return this.windows.size;\n }\n\n /**\n * Get layout tree\n */\n getLayout(): WindowLayout {\n return this.layout;\n }\n\n // Helper methods for layout manipulation\n\n private replaceWindowInLayout(\n layout: WindowLayout,\n windowId: number,\n replacement: WindowLayout\n ): WindowLayout {\n if (layout.type === 'leaf') {\n if (layout.window?.id === windowId) {\n return replacement;\n }\n return layout;\n }\n\n // Split node\n if (layout.children) {\n return {\n ...layout,\n children: [\n this.replaceWindowInLayout(layout.children[0], windowId, replacement),\n this.replaceWindowInLayout(layout.children[1], windowId, replacement)\n ]\n };\n }\n\n return layout;\n }\n\n private removeWindowFromLayout(\n layout: WindowLayout,\n windowId: number\n ): { layout: WindowLayout; siblingId: number | null } {\n if (layout.type === 'leaf') {\n return { layout, siblingId: null };\n }\n\n // Check if one of the children is the window to remove\n if (layout.children) {\n const [left, right] = layout.children;\n\n if (left.type === 'leaf' && left.window?.id === windowId) {\n return { layout: right, siblingId: right.window?.id || null };\n }\n\n if (right.type === 'leaf' && right.window?.id === windowId) {\n return { layout: left, siblingId: left.window?.id || null };\n }\n\n // Recursively remove from children\n const leftResult = this.removeWindowFromLayout(left, windowId);\n if (leftResult.siblingId !== null) {\n return leftResult;\n }\n\n const rightResult = this.removeWindowFromLayout(right, windowId);\n if (rightResult.siblingId !== null) {\n return rightResult;\n }\n }\n\n return { layout, siblingId: null };\n }\n\n private updateWindowInLayout(\n layout: WindowLayout,\n windowId: number,\n updatedWindow: Window\n ): WindowLayout {\n if (layout.type === 'leaf') {\n if (layout.window?.id === windowId) {\n return { ...layout, window: updatedWindow };\n }\n return layout;\n }\n\n // Split node\n if (layout.children) {\n return {\n ...layout,\n children: [\n this.updateWindowInLayout(layout.children[0], windowId, updatedWindow),\n this.updateWindowInLayout(layout.children[1], windowId, updatedWindow)\n ]\n };\n }\n\n return layout;\n }\n}\n","// @ts-ignore - nspell doesn't have type definitions\nimport nspell from 'nspell';\n\nexport interface SpellCheckResult {\n word: string;\n line: number;\n column: number;\n suggestions: string[];\n}\n\n/**\n * Manages spell checking functionality using nspell\n */\nexport class SpellChecker {\n private spell: any;\n private enabled: boolean = false;\n private goodWords: Set<string> = new Set();\n private badWords: Set<string> = new Set();\n private sessionGoodWords: Set<string> = new Set();\n private sessionBadWords: Set<string> = new Set();\n\n constructor() {\n this.initializeSpellChecker();\n }\n\n private initializeSpellChecker(): void {\n // Create a simple mock spell checker\n // In production, you would load actual dictionary files:\n // import {readFileSync} from 'fs';\n // const aff = readFileSync('node_modules/dictionary-en/index.aff', 'utf8');\n // const dic = readFileSync('node_modules/dictionary-en/index.dic', 'utf8');\n // this.spell = nspell({aff, dic});\n\n this.spell = {\n correct: (word: string) => {\n // Simple heuristic: accept words in our custom dictionaries\n // or common English words\n if (this.goodWords.has(word) || this.sessionGoodWords.has(word)) {\n return true;\n }\n if (this.badWords.has(word) || this.sessionBadWords.has(word)) {\n return false;\n }\n // For demo purposes, accept most words\n // In production, use real nspell with dictionaries\n return true;\n },\n suggest: (word: string) => {\n // Simple suggestions based on common typos\n const suggestions: string[] = [];\n\n // Common substitutions\n const commonFixes: Record<string, string> = {\n 'teh': 'the',\n 'wrold': 'world',\n 'recieve': 'receive',\n 'occured': 'occurred',\n 'seperate': 'separate',\n 'definately': 'definitely',\n 'wierd': 'weird'\n };\n\n const fix = commonFixes[word.toLowerCase()];\n if (fix) {\n suggestions.push(fix);\n }\n\n return suggestions;\n }\n };\n }\n\n /**\n * Enable spell checking\n */\n enable(): void {\n this.enabled = true;\n }\n\n /**\n * Disable spell checking\n */\n disable(): void {\n this.enabled = false;\n }\n\n /**\n * Check if spell checking is enabled\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Check if a word is spelled correctly\n */\n isCorrect(word: string): boolean {\n if (!this.enabled) return true;\n if (this.badWords.has(word) || this.sessionBadWords.has(word)) {\n return false;\n }\n if (this.goodWords.has(word) || this.sessionGoodWords.has(word)) {\n return true;\n }\n return this.spell.correct(word);\n }\n\n /**\n * Get spelling suggestions for a word\n */\n suggest(word: string, maxSuggestions: number = 10): string[] {\n if (!this.enabled) return [];\n\n const suggestions = this.spell.suggest(word);\n return suggestions.slice(0, maxSuggestions);\n }\n\n /**\n * Add word to personal dictionary (persistent)\n */\n addGoodWord(word: string): void {\n this.goodWords.add(word);\n // Note: In production, would call this.spell.add(word) if available\n if (this.spell && typeof this.spell.add === 'function') {\n this.spell.add(word);\n }\n }\n\n /**\n * Add word to session word list (temporary)\n */\n addSessionGoodWord(word: string): void {\n this.sessionGoodWords.add(word);\n }\n\n /**\n * Mark word as bad in personal dictionary (persistent)\n */\n addBadWord(word: string): void {\n this.badWords.add(word);\n this.goodWords.delete(word);\n }\n\n /**\n * Mark word as bad in session list (temporary)\n */\n addSessionBadWord(word: string): void {\n this.sessionBadWords.add(word);\n this.sessionGoodWords.delete(word);\n }\n\n /**\n * Remove word from good word list\n */\n removeGoodWord(word: string): void {\n this.goodWords.delete(word);\n }\n\n /**\n * Remove word from session good word list\n */\n removeSessionGoodWord(word: string): void {\n this.sessionGoodWords.delete(word);\n }\n\n /**\n * Remove word from bad word list\n */\n removeBadWord(word: string): void {\n this.badWords.delete(word);\n }\n\n /**\n * Remove word from session bad word list\n */\n removeSessionBadWord(word: string): void {\n this.sessionBadWords.delete(word);\n }\n\n /**\n * Check all words in buffer content\n */\n checkBuffer(content: string): SpellCheckResult[] {\n if (!this.enabled) return [];\n\n const results: SpellCheckResult[] = [];\n const lines = content.split('\\n');\n\n for (let lineNum = 0; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum];\n if (!line) continue;\n\n const words = this.extractWords(line);\n\n for (const { word, column } of words) {\n if (!this.isCorrect(word)) {\n results.push({\n word,\n line: lineNum,\n column,\n suggestions: this.suggest(word)\n });\n }\n }\n }\n\n return results;\n }\n\n /**\n * Extract words from a line with their positions\n */\n private extractWords(line: string): Array<{ word: string; column: number }> {\n const words: Array<{ word: string; column: number }> = [];\n const wordRegex = /\\b[a-zA-Z']+\\b/g;\n let match: RegExpExecArray | null;\n\n while ((match = wordRegex.exec(line)) !== null) {\n words.push({\n word: match[0],\n column: match.index\n });\n }\n\n return words;\n }\n\n /**\n * Find next misspelled word from cursor position\n */\n findNextMisspelled(content: string, currentLine: number, currentColumn: number): SpellCheckResult | null {\n const errors = this.checkBuffer(content);\n\n for (const error of errors) {\n if (error.line > currentLine ||\n (error.line === currentLine && error.column > currentColumn)) {\n return error;\n }\n }\n\n // Wrap around to beginning\n return errors.length > 0 ? errors[0] || null : null;\n }\n\n /**\n * Find previous misspelled word from cursor position\n */\n findPrevMisspelled(content: string, currentLine: number, currentColumn: number): SpellCheckResult | null {\n const errors = this.checkBuffer(content);\n\n // Search backwards\n for (let i = errors.length - 1; i >= 0; i--) {\n const error = errors[i];\n if (error && (error.line < currentLine ||\n (error.line === currentLine && error.column < currentColumn))) {\n return error;\n }\n }\n\n // Wrap around to end\n const lastError = errors[errors.length - 1];\n return errors.length > 0 ? (lastError || null) : null;\n }\n\n /**\n * Get word at specific position\n */\n getWordAt(content: string, line: number, column: number): string | null {\n const lines = content.split('\\n');\n if (line >= lines.length) return null;\n\n const lineContent = lines[line];\n if (!lineContent) return null;\n\n const words = this.extractWords(lineContent);\n\n for (const { word, column: wordCol } of words) {\n if (column >= wordCol && column < wordCol + word.length) {\n return word;\n }\n }\n\n return null;\n }\n\n /**\n * Create a copy of this spell checker\n */\n clone(): SpellChecker {\n const newChecker = new SpellChecker();\n newChecker.enabled = this.enabled;\n newChecker.goodWords = new Set(this.goodWords);\n newChecker.badWords = new Set(this.badWords);\n newChecker.sessionGoodWords = new Set(this.sessionGoodWords);\n newChecker.sessionBadWords = new Set(this.sessionBadWords);\n return newChecker;\n }\n}\n","import path from \"path\";\nimport * as fs from \"node:fs\";\n\n\nexport interface CompletionMatch {\n text: string;\n type: CompletionType;\n info?: string; // Additional information about the match\n}\n\nexport enum CompletionType {\n KEYWORD = 'keyword',\n LINE = 'line',\n FILENAME = 'filename',\n TAG = 'tag',\n OMNI = 'omni',\n USER = 'user',\n SPELLING = 'spelling'\n}\n\nexport interface CompletionState {\n matches: CompletionMatch[];\n currentIndex: number;\n prefix: string;\n type: CompletionType;\n isActive: boolean;\n}\n\n/**\n * Manages completion functionality for insert mode\n */\nexport class CompletionManager {\n private state: CompletionState | null = null;\n\n constructor() {}\n\n /**\n * Check if completion is active\n */\n isActive(): boolean {\n return this.state?.isActive ?? false;\n }\n\n /**\n * Get current completion state\n */\n getState(): CompletionState | null {\n return this.state;\n }\n\n /**\n * Get currently selected completion match\n */\n getCurrentMatch(): CompletionMatch | null {\n if (!this.state || this.state.matches.length === 0) return null;\n return this.state.matches[this.state.currentIndex] || null;\n }\n\n /**\n * Cancel completion\n */\n cancel(): void {\n this.state = null;\n }\n\n /**\n * Select next completion match\n */\n next(): void {\n if (!this.state || this.state.matches.length === 0) return;\n this.state = {\n ...this.state,\n currentIndex: (this.state.currentIndex + 1) % this.state.matches.length\n };\n }\n\n /**\n * Select previous completion match\n */\n prev(): void {\n if (!this.state || this.state.matches.length === 0) return;\n this.state = {\n ...this.state,\n currentIndex: (this.state.currentIndex - 1 + this.state.matches.length) % this.state.matches.length\n };\n }\n\n /**\n * Start keyword completion - complete from buffer words\n */\n keywordCompletion(buffer: string, cursorLine: number, cursorCol: number): CompletionMatch[] {\n const prefix = this.getWordPrefix(buffer, cursorLine, cursorCol);\n if (prefix.length === 0) return [];\n\n const keywords = this.extractKeywords(buffer);\n const matches = keywords\n .filter(word => word !== prefix && word.toLowerCase().startsWith(prefix.toLowerCase()))\n .map(text => ({\n text,\n type: CompletionType.KEYWORD\n }));\n\n this.state = {\n matches,\n currentIndex: 0,\n prefix,\n type: CompletionType.KEYWORD,\n isActive: prefix.length > 0 // Active if we have a prefix, even if no matches\n };\n\n return matches;\n }\n\n /**\n * Start line completion - complete entire lines\n */\n lineCompletion(buffer: string, cursorLine: number, cursorCol: number): CompletionMatch[] {\n const lines = buffer.split('\\n');\n const currentLine = lines[cursorLine] || '';\n const prefix = currentLine.substring(0, cursorCol).trimStart();\n\n if (prefix.length === 0) return [];\n\n const matches = lines\n .map((line, idx) => ({ line: line.trimStart(), idx }))\n .filter(({ line, idx }) =>\n idx !== cursorLine &&\n line.startsWith(prefix) &&\n line.length > prefix.length\n )\n .map(({ line }) => ({\n text: line,\n type: CompletionType.LINE,\n info: 'whole line'\n }));\n\n // Remove duplicates\n const uniqueMatches = Array.from(\n new Map(matches.map(m => [m.text, m])).values()\n );\n\n this.state = {\n matches: uniqueMatches,\n currentIndex: 0,\n prefix,\n type: CompletionType.LINE,\n isActive: prefix.length > 0 // Active if we have a prefix, even if no matches\n };\n\n return uniqueMatches;\n }\n\n /**\n * Start filename completion\n */\n async fileNameCompletion(\n buffer: string,\n cursorLine: number,\n cursorCol: number,\n currentDir: string = process.cwd()\n ): Promise<CompletionMatch[]> {\n const prefix = this.getFilePathPrefix(buffer, cursorLine, cursorCol);\n if (prefix.length === 0) return [];\n\n try {\n const dirname = path.dirname(path.join(currentDir, prefix));\n const basename = path.basename(prefix);\n\n let files: string[] = [];\n try {\n files = await fs.promises.readdir(dirname);\n } catch {\n // Directory doesn't exist, return no matches\n return [];\n }\n\n const matches = files\n .filter(file => file.startsWith(basename))\n .map(file => ({\n text: path.join(path.dirname(prefix), file),\n type: CompletionType.FILENAME,\n info: this.getFileTypeInfo(path.join(dirname, file))\n }));\n\n this.state = {\n matches,\n currentIndex: 0,\n prefix,\n type: CompletionType.FILENAME,\n isActive: prefix.length > 0 // Active if we have a prefix, even if no matches\n };\n\n return matches;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Start omni completion - context-aware completion\n * This is a simplified version that combines keyword and line completion\n */\n omniCompletion(buffer: string, cursorLine: number, cursorCol: number): CompletionMatch[] {\n // For now, combine keyword and line completion\n const keywordMatches = this.extractKeywords(buffer);\n const prefix = this.getWordPrefix(buffer, cursorLine, cursorCol);\n\n const matches = keywordMatches\n .filter(word => word !== prefix && word.toLowerCase().startsWith(prefix.toLowerCase()))\n .map(text => ({\n text,\n type: CompletionType.OMNI,\n info: 'omni'\n }));\n\n this.state = {\n matches,\n currentIndex: 0,\n prefix,\n type: CompletionType.OMNI,\n isActive: prefix.length > 0 // Active if we have a prefix, even if no matches\n };\n\n return matches;\n }\n\n /**\n * Extract word prefix before cursor\n */\n private getWordPrefix(buffer: string, line: number, column: number): string {\n const lines = buffer.split('\\n');\n\n // Handle out-of-bounds line numbers gracefully\n if (line < 0) line = 0;\n if (line >= lines.length) line = lines.length - 1;\n\n const lineContent = lines[line];\n if (!lineContent) return '';\n\n const beforeCursor = lineContent.substring(0, column);\n\n // Find the last word boundary\n const match = beforeCursor.match(/(\\w+)$/);\n return match ? match[1] || '' : '';\n }\n\n /**\n * Extract file path prefix before cursor\n */\n private getFilePathPrefix(buffer: string, line: number, column: number): string {\n const lines = buffer.split('\\n');\n\n // Handle out-of-bounds line numbers gracefully\n if (line < 0) line = 0;\n if (line >= lines.length) line = lines.length - 1;\n\n const lineContent = lines[line];\n if (!lineContent) return '';\n\n const beforeCursor = lineContent.substring(0, column);\n\n // Find the last path segment\n const match = beforeCursor.match(/([./\\w-]+)$/);\n return match ? match[1] || '' : '';\n }\n\n /**\n * Extract all keywords from buffer\n */\n private extractKeywords(buffer: string): string[] {\n const wordRegex = /\\b[a-zA-Z_]\\w+\\b/g;\n const words = buffer.match(wordRegex) || [];\n\n // Return unique words sorted by frequency\n const wordCounts = new Map<string, number>();\n for (const word of words) {\n wordCounts.set(word, (wordCounts.get(word) || 0) + 1);\n }\n\n return Array.from(wordCounts.entries())\n .sort((a, b) => b[1] - a[1]) // Sort by frequency\n .map(([word]) => word);\n }\n\n /**\n * Get file type information\n */\n private getFileTypeInfo(filepath: string): string {\n try {\n const stat = fs.statSync(filepath);\n if (stat.isDirectory()) return 'directory';\n if (stat.isFile()) return 'file';\n if (stat.isSymbolicLink()) return 'symlink';\n return 'unknown';\n } catch {\n return 'unknown';\n }\n }\n\n /**\n * Get completion text to insert (without prefix)\n */\n getCompletionText(): string {\n const match = this.getCurrentMatch();\n if (!match || !this.state) return '';\n\n // For line completion, return the entire line\n if (this.state.type === CompletionType.LINE) {\n return match.text;\n }\n\n // For other types, return the part after the prefix\n if (match.text.toLowerCase().startsWith(this.state.prefix.toLowerCase())) {\n return match.text.substring(this.state.prefix.length);\n }\n\n return match.text;\n }\n\n /**\n * Get full completion text including prefix\n */\n getFullCompletionText(): string {\n const match = this.getCurrentMatch();\n return match?.text || '';\n }\n\n /**\n * Clone this completion manager\n */\n clone(): CompletionManager {\n const newManager = new CompletionManager();\n if (this.state) {\n newManager.state = {\n ...this.state,\n matches: [...this.state.matches]\n };\n }\n return newManager;\n }\n}\n","import {Buffer} from \"./buffer\";\nimport {Cursor} from \"./cursor\";\nimport {Mode} from \"../types/Modes\";\nimport type {Range} from \"../types/Range\";\nimport {VimViewport} from \"./viewport\";\nimport {FoldManager} from \"../types/Fold\";\nimport {MarkManager} from \"../types/Mark\";\nimport {JumpListManager} from \"../types/JumpList\";\nimport {FileSystemManager} from \"../types/FileSystem\";\nimport {WindowManager} from \"../types/Window\";\nimport {SpellChecker} from \"../types/SpellChecker\";\nimport {CompletionManager} from \"../types/CompletionManager\";\nimport type {UndoTree} from \"../types/UndoTree\";\n\nexport interface LastVisualSelection {\n range: Range;\n mode: Mode.VISUAL | Mode.VISUAL_LINE | Mode.VISUAL_BLOCK;\n}\n\nexport interface SearchState {\n pattern: string;\n isForward: boolean;\n}\n\nexport interface LastCommand {\n key: string;\n count?: number;\n register?: string;\n}\n\nexport class State {\n constructor(\n public buffer: Buffer,\n public cursor: Cursor,\n public selection: Range | null,\n public mode: Mode,\n public commandLine: string = '',\n public desiredColumn: number | null = null,\n public viewport: VimViewport = new VimViewport(),\n public visualAnchor: Cursor | null = null,\n public lastVisualSelection: LastVisualSelection | null = null,\n public recordingRegister: string | null = null,\n public lastMacroRegister: string | null = null,\n public foldManager: FoldManager = new FoldManager(),\n public markManager: MarkManager = new MarkManager(),\n public jumpListManager: JumpListManager = new JumpListManager(),\n public fileSystem: FileSystemManager = new FileSystemManager(),\n public windowManager: WindowManager = new WindowManager(),\n public lastSearch: SearchState | null = null,\n public spellChecker: SpellChecker = new SpellChecker(),\n public completionManager: CompletionManager = new CompletionManager(),\n public undoTree: UndoTree | null = null,\n public lastCommand: LastCommand | null = null\n ) {\n }\n}\nexport function createEmptyState(): State {\n const state = new State(\n new Buffer(''),\n new Cursor(0, 0),\n null,\n Mode.NORMAL,\n '',\n null,\n new VimViewport(),\n null,\n null,\n null,\n null,\n new FoldManager(),\n new MarkManager(),\n new JumpListManager(),\n new FileSystemManager(),\n new WindowManager(),\n null,\n new SpellChecker(),\n new CompletionManager(),\n null, // undoTree will be initialized separately\n null // lastCommand\n );\n return state;\n}","import {State} from \"./state\";\nimport {Buffer} from \"./buffer\";\nimport {Cursor} from \"./cursor\";\nimport {Mode} from \"../types/Modes\";\nimport type {IndentationManager} from \"./indent-manager\";\n\n/**\n * Handle Escape key in insert mode - return to normal mode\n */\nexport function handleInsertEscape(state: State): State {\n let newState: State = {\n ...state,\n mode: Mode.NORMAL,\n desiredColumn: null\n };\n\n // Move cursor back one position if not at start of line\n if (state.cursor.column > 0) {\n newState = {\n ...newState,\n cursor: new Cursor(state.cursor.line, state.cursor.column - 1)\n };\n }\n\n return newState;\n}\n\n/**\n * Handle Backspace key in insert mode - delete character before cursor\n */\nexport function handleInsertBackspace(state: State): State {\n if (state.cursor.column > 0) {\n // Delete character before cursor on current line\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const newLine = currentLine.slice(0, state.cursor.column - 1) +\n currentLine.slice(state.cursor.column);\n lines[state.cursor.line] = newLine;\n\n return {\n ...state,\n buffer: new Buffer(lines.join('\\n')),\n cursor: new Cursor(state.cursor.line, state.cursor.column - 1),\n desiredColumn: null\n };\n } else if (state.cursor.line > 0) {\n // Join with previous line\n const lines = state.buffer.content.split('\\n');\n const prevLine = lines[state.cursor.line - 1] ?? '';\n const currentLine = lines[state.cursor.line] ?? '';\n const newColumn = prevLine.length;\n\n lines[state.cursor.line - 1] = prevLine + currentLine;\n lines.splice(state.cursor.line, 1);\n\n return {\n ...state,\n buffer: new Buffer(lines.join('\\n')),\n cursor: new Cursor(state.cursor.line - 1, newColumn),\n desiredColumn: null\n };\n }\n\n return state;\n}\n\n/**\n * Handle Enter key in insert mode - insert new line with proper indentation\n */\nexport function handleInsertEnter(state: State, indentationManager: IndentationManager): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const beforeCursor = currentLine.slice(0, state.cursor.column);\n const afterCursor = currentLine.slice(state.cursor.column);\n\n // Calculate indent for new line\n const newLineIndent = indentationManager.calculateIndentForNewLine(\n state.buffer,\n state.cursor.line\n );\n\n lines[state.cursor.line] = beforeCursor;\n lines.splice(state.cursor.line + 1, 0, newLineIndent + afterCursor);\n\n return {\n ...state,\n buffer: new Buffer(lines.join('\\n')),\n cursor: new Cursor(state.cursor.line + 1, newLineIndent.length),\n desiredColumn: null\n };\n}\n\n/**\n * Handle Space key in insert mode - insert space character\n */\nexport function handleInsertSpace(state: State): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const newLine = currentLine.slice(0, state.cursor.column) +\n ' ' +\n currentLine.slice(state.cursor.column);\n lines[state.cursor.line] = newLine;\n\n return {\n ...state,\n buffer: new Buffer(lines.join('\\n')),\n cursor: new Cursor(state.cursor.line, state.cursor.column + 1),\n desiredColumn: null\n };\n}\n\n/**\n * Handle ArrowLeft key in insert mode - move cursor left, wrapping to previous line\n */\nexport function handleInsertArrowLeft(state: State): State {\n if (state.cursor.column > 0) {\n // Move left within current line\n return {\n ...state,\n cursor: new Cursor(state.cursor.line, state.cursor.column - 1),\n desiredColumn: null\n };\n } else if (state.cursor.line > 0) {\n // At start of line, wrap to end of previous line\n const lines = state.buffer.content.split('\\n');\n const prevLine = lines[state.cursor.line - 1] ?? '';\n return {\n ...state,\n cursor: new Cursor(state.cursor.line - 1, prevLine.length),\n desiredColumn: null\n };\n }\n return state;\n}\n\n/**\n * Handle ArrowRight key in insert mode - move cursor right, wrapping to next line\n */\nexport function handleInsertArrowRight(state: State): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n // In insert mode, cursor can be at line.length (one past last character)\n if (state.cursor.column < currentLine.length) {\n // Move right within current line\n return {\n ...state,\n cursor: new Cursor(state.cursor.line, state.cursor.column + 1),\n desiredColumn: null\n };\n } else if (state.cursor.line < lines.length - 1) {\n // At end of line, wrap to start of next line\n return {\n ...state,\n cursor: new Cursor(state.cursor.line + 1, 0),\n desiredColumn: null\n };\n }\n return state;\n}\n\n/**\n * Handle ArrowUp key in insert mode - move cursor up\n */\nexport function handleInsertArrowUp(state: State): State {\n if (state.cursor.line > 0) {\n const lines = state.buffer.content.split('\\n');\n const prevLine = lines[state.cursor.line - 1] ?? '';\n // In insert mode, cursor can be at line.length\n const newColumn = Math.min(state.cursor.column, prevLine.length);\n return {\n ...state,\n cursor: new Cursor(state.cursor.line - 1, newColumn),\n desiredColumn: null\n };\n }\n return state;\n}\n\n/**\n * Handle ArrowDown key in insert mode - move cursor down\n */\nexport function handleInsertArrowDown(state: State): State {\n const lines = state.buffer.content.split('\\n');\n if (state.cursor.line < lines.length - 1) {\n const nextLine = lines[state.cursor.line + 1] ?? '';\n // In insert mode, cursor can be at line.length\n const newColumn = Math.min(state.cursor.column, nextLine.length);\n return {\n ...state,\n cursor: new Cursor(state.cursor.line + 1, newColumn),\n desiredColumn: null\n };\n }\n return state;\n}\n\n/**\n * Handle regular character insertion in insert mode\n */\nexport function handleInsertCharacter(state: State, char: string): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const newLine = currentLine.slice(0, state.cursor.column) +\n char +\n currentLine.slice(state.cursor.column);\n lines[state.cursor.line] = newLine;\n\n return {\n ...state,\n buffer: new Buffer(lines.join('\\n')),\n cursor: new Cursor(state.cursor.line, state.cursor.column + 1),\n desiredColumn: null\n };\n}\n","import type {State} from \"../core/state\";\nimport type {Range} from \"./Range\";\n\nexport abstract class TextObject {\n abstract key: string;\n\n abstract getRange(state: State, variant: 'inner' | 'outer'): Range | null;\n}","import type {State} from \"../core/state\";\nimport type {Motion} from \"../core/motion\";\nimport {TextObject} from \"./TextObject\";\nimport type {RegisterManager} from \"../registers/manager\";\nimport type {IndentationManager} from \"../core/indent-manager\";\nimport type {Range} from \"./Range\";\n\nexport interface CommandContext {\n count?: number;\n motion?: Motion;\n textObject?: TextObject;\n variant?: 'inner' | 'outer';\n register?: string; // For register prefix (e.g., \"a in \"ayy)\n char?: string; // For character-capture commands (e.g., char in f{char})\n registerManager?: RegisterManager;\n indentationManager?: IndentationManager;\n args?: string; // For ex commands that take arguments (e.g., :e filename)\n range?: Range; // For commands that operate on a range (e.g., :10,20d)\n}\n\nexport abstract class Command {\n abstract key: string;\n\n // Existing flags\n public acceptsMotion: boolean = false;\n public acceptsTextObject: boolean = false;\n public acceptsPrecedingCount: boolean = false;\n\n // New flags for extended command types\n public acceptsRegister: boolean = false; // Can be prefixed with \"{register} (d, y, c, p, P)\n public needsFollowingChar: boolean = false; // Needs following character (f, t, r, m)\n public isPrefix: boolean = false; // Is a prefix to other commands (g, z, Ctrl-w)\n public inclusive: boolean = false; // Whether motion is inclusive when used with operators\n\n abstract execute(state: State, context: CommandContext): State;\n}","import {Command} from \"../types/Command\";\n\nexport abstract class Motion extends Command {\n abstract key: string; // The key that triggers this motion (e.g., 'w', 'e', '$')\n\n // Motions don't accept motions or text objects, only counts\n public acceptsMotion = false;\n public acceptsTextObject = false;\n public acceptsPrecedingCount = true;\n\n // Whether this motion is inclusive when used with operators\n // Inclusive motions (e, $) include the character at the end position\n // Exclusive motions (w, b) do not\n public inclusive: boolean = false;\n\n // Whether this motion operates on entire lines when used with operators\n // Linewise motions (G, gg, etc.) delete/change/yank entire lines\n public linewise: boolean = false;\n}","import type {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Character classification utilities\n */\nexport type CharClassifier = (char: string) => boolean;\n\nexport function isWordChar(char: string): boolean {\n return /[a-zA-Z0-9_]/.test(char);\n}\n\nexport function isWhitespace(char: string): boolean {\n return /\\s/.test(char);\n}\n\nexport function isPunctuation(char: string): boolean {\n return !isWordChar(char) && !isWhitespace(char) && char !== '';\n}\n\nexport function isNewline(char: string): boolean {\n return char === '\\n';\n}\n\n/**\n * Character access utilities\n */\nexport function getCharAt(buffer: Buffer, cursor: Cursor): string {\n const lines = buffer.content.split('\\n');\n if (cursor.line >= lines.length) return '';\n const line = lines[cursor.line] ?? '';\n return line[cursor.column] ?? '';\n}\n\n// Note: getCharAtOffset moved to cursor-movement.ts to avoid circular dependency\n","import type {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCharAt, type CharClassifier, isWordChar, isWhitespace, isPunctuation} from \"./character\";\n\n/**\n * Cursor state checks\n */\nexport function isOnChar(buffer: Buffer, cursor: Cursor, classifier: CharClassifier): boolean {\n const char = getCharAt(buffer, cursor);\n return classifier(char);\n}\n\nexport function isOnWord(buffer: Buffer, cursor: Cursor): boolean {\n return isOnChar(buffer, cursor, isWordChar);\n}\n\nexport function isOnWhitespace(buffer: Buffer, cursor: Cursor): boolean {\n return isOnChar(buffer, cursor, isWhitespace);\n}\n\nexport function isOnPunctuation(buffer: Buffer, cursor: Cursor): boolean {\n return isOnChar(buffer, cursor, isPunctuation);\n}\n\nexport function isAtLineStart(cursor: Cursor): boolean {\n return cursor.column === 0;\n}\n\nexport function isAtLineEnd(buffer: Buffer, cursor: Cursor): boolean {\n const lines = buffer.content.split('\\n');\n const line = lines[cursor.line] ?? '';\n return cursor.column >= line.length;\n}\n\nexport function isAtBufferStart(cursor: Cursor): boolean {\n return cursor.line === 0 && cursor.column === 0;\n}\n\nexport function isAtBufferEnd(buffer: Buffer, cursor: Cursor): boolean {\n const lines = buffer.content.split('\\n');\n const lastLine = lines.length - 1;\n if (cursor.line !== lastLine) return false;\n const line = lines[lastLine] ?? ''; //unexpected behaviour I think,\n return cursor.column >= (lines[lastLine] ?? '').length; //'line.length' is the line as a string??\n}\n","import type {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCharAt} from \"./character\";\n\n/**\n * Atomic cursor movement utilities\n */\n\n/**\n * Convert cursor position to absolute character offset in buffer.\n * Treats newlines as single characters.\n */\nfunction cursorToAbsolutePosition(lines: string[], cursor: Cursor): number {\n let position = 0;\n\n // Add length of all lines before cursor line (including newlines)\n for (let i = 0; i < cursor.line && i < lines.length; i++) {\n position += (lines[i]?.length ?? 0) + 1; // +1 for newline\n }\n\n // Add column offset within current line\n position += cursor.column;\n\n return position;\n}\n\n/**\n * Convert absolute character offset to cursor position.\n * Clamps to valid buffer positions.\n */\nfunction absolutePositionToCursor(lines: string[], absolutePos: number): Cursor {\n if (lines.length === 0) {\n return new Cursor(0, 0);\n }\n\n let remaining = absolutePos;\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const lineLength = lines[lineIndex]?.length ?? 0;\n\n // If position falls within this line, we found it\n if (remaining <= lineLength) {\n return new Cursor(lineIndex, remaining);\n }\n\n // Move past this line and its newline character\n remaining -= lineLength + 1;\n }\n\n // Position is past end of buffer - clamp to last valid position\n const lastLineIndex = lines.length - 1;\n const lastLineLength = lines[lastLineIndex]?.length ?? 0;\n return new Cursor(lastLineIndex, lastLineLength);\n}\n\n/**\n * Move cursor by a given character offset.\n * Handles moving across line boundaries.\n */\nexport function moveCursorBy(buffer: Buffer, cursor: Cursor, offset: number): Cursor {\n const lines = buffer.content.split('\\n');\n\n // Convert to absolute position, apply offset, convert back\n const absolutePos = cursorToAbsolutePosition(lines, cursor);\n const newPos = Math.max(0, absolutePos + offset);\n\n return absolutePositionToCursor(lines, newPos);\n}\n\nexport function moveRight(buffer: Buffer, cursor: Cursor): Cursor {\n return moveCursorBy(buffer, cursor, 1);\n}\n\nexport function moveLeft(buffer: Buffer, cursor: Cursor): Cursor {\n return moveCursorBy(buffer, cursor, -1);\n}\n\nexport function moveDown(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = buffer.content.split('\\n');\n if (cursor.line >= lines.length - 1) return cursor;\n return new Cursor(cursor.line + 1, cursor.column);\n}\n\nexport function moveUp(buffer: Buffer, cursor: Cursor): Cursor {\n if (cursor.line === 0) return cursor;\n return new Cursor(cursor.line - 1, cursor.column);\n}\n\n/**\n * Character access by offset\n */\nexport function getCharAtOffset(buffer: Buffer, cursor: Cursor, offset: number): string {\n return getCharAt(buffer, moveCursorBy(buffer, cursor, offset));\n}\n","import type {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCharAt, type CharClassifier} from \"./character\";\nimport {moveRight, moveLeft} from \"./cursor-movement\";\nimport {isAtBufferEnd, isAtBufferStart} from \"./cursor-state\";\n\n/**\n * Generic search functions\n */\nexport function findNext(\n buffer: Buffer,\n cursor: Cursor,\n classifier: CharClassifier,\n inclusive: boolean = false\n): Cursor {\n let current = inclusive ? cursor : moveRight(buffer, cursor);\n\n while (!isAtBufferEnd(buffer, current)) {\n if (classifier(getCharAt(buffer, current))) {\n return current;\n }\n current = moveRight(buffer, current);\n }\n\n return current;\n}\n\nexport function findPrev(\n buffer: Buffer,\n cursor: Cursor,\n classifier: CharClassifier,\n inclusive: boolean = false\n): Cursor {\n let current = inclusive ? cursor : moveLeft(buffer, cursor);\n\n while (!isAtBufferStart(current)) {\n if (classifier(getCharAt(buffer, current))) {\n return current;\n }\n current = moveLeft(buffer, current);\n }\n\n return current;\n}\n\n/**\n * Skip while character matches classifier\n */\nexport function skipWhile(\n buffer: Buffer,\n cursor: Cursor,\n classifier: CharClassifier,\n forward: boolean = true\n): Cursor {\n let current = cursor;\n\n while (true) {\n if (forward && isAtBufferEnd(buffer, current)) break;\n if (!forward && isAtBufferStart(current)) break;\n\n if (!classifier(getCharAt(buffer, current))) {\n break;\n }\n\n current = forward ? moveRight(buffer, current) : moveLeft(buffer, current);\n }\n\n return current;\n}\n\n/**\n * Skip until character matches classifier\n */\nexport function skipUntil(\n buffer: Buffer,\n cursor: Cursor,\n classifier: CharClassifier,\n forward: boolean = true\n): Cursor {\n return skipWhile(buffer, cursor, (char) => !classifier(char), forward);\n}\n","import type {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCharAt, isWordChar, isWhitespace, isPunctuation} from \"./character\";\nimport {moveRight, moveLeft} from \"./cursor-movement\";\nimport {isOnWord, isOnWhitespace, isOnPunctuation, isAtBufferEnd, isAtBufferStart, isAtLineStart} from \"./cursor-state\";\nimport {skipWhile} from \"./search\";\n\n/**\n * Word boundary navigation (built on atomic functions)\n */\n\n/**\n * Find the start of the next word (w motion)\n */\nexport function findNextWordStart(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer end, can't move forward\n if (isAtBufferEnd(buffer, cursor)) {\n return cursor;\n }\n\n let pos = cursor;\n const initialChar = getCharAt(buffer, pos);\n\n // Skip current word if on word char\n if (isWordChar(initialChar)) {\n pos = skipWhile(buffer, pos, isWordChar, true);\n // Skip any following whitespace\n pos = skipWhile(buffer, pos, isWhitespace, true);\n }\n // Skip current punctuation group if on punctuation char\n else if (isPunctuation(initialChar)) {\n pos = skipWhile(buffer, pos, (c) => isPunctuation(c) && c === initialChar, true);\n // Skip any following whitespace\n pos = skipWhile(buffer, pos, isWhitespace, true);\n }\n // If on whitespace, skip it\n else if (isWhitespace(initialChar)) {\n pos = skipWhile(buffer, pos, isWhitespace, true);\n }\n\n // If we're at end of line (empty string), move forward to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferEnd(buffer, pos)) {\n pos = moveRight(buffer, pos);\n // Skip any whitespace on the new line\n pos = skipWhile(buffer, pos, isWhitespace, true);\n }\n\n return pos;\n}\n\n/**\n * Find the start of the previous word (b motion)\n */\nexport function findPrevWordStart(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer start, can't move backward\n if (isAtBufferStart(cursor)) {\n return cursor;\n }\n\n let pos = moveLeft(buffer, cursor);\n\n // If we landed on end of line (empty string), move left again to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferStart(pos)) {\n pos = moveLeft(buffer, pos);\n }\n\n // Skip whitespace backward\n if (isWhitespace(getCharAt(buffer, pos))) {\n pos = skipWhile(buffer, pos, isWhitespace, false);\n }\n\n // If we're at start of line (after skipping whitespace), move back to previous line\n if (isAtLineStart(pos) && !isAtBufferStart(pos)) {\n pos = moveLeft(buffer, pos);\n // If we landed on end of line again, move left once more\n if (getCharAt(buffer, pos) === '' && !isAtBufferStart(pos)) {\n pos = moveLeft(buffer, pos);\n }\n // Skip whitespace backward on previous line\n pos = skipWhile(buffer, pos, isWhitespace, false);\n }\n\n // Now we should be on a word or punctuation character\n const char = getCharAt(buffer, pos);\n\n if (isWordChar(char)) {\n // Skip backward to start of word\n pos = skipWhile(buffer, pos, isWordChar, false);\n // We went one past the start, so move forward if not at start\n if (!isAtBufferStart(pos) && !isWordChar(getCharAt(buffer, pos))) {\n pos = moveRight(buffer, pos);\n }\n } else if (isPunctuation(char)) {\n // Skip backward through same punctuation group\n pos = skipWhile(buffer, pos, (c) => isPunctuation(c) && c === char, false);\n // We went one past the start, so move forward if needed\n if (!isAtBufferStart(pos) && getCharAt(buffer, pos) !== char) {\n pos = moveRight(buffer, pos);\n }\n }\n\n return pos;\n}\n\nexport function findNextWordEnd(buffer: Buffer, cursor: Cursor): Cursor {\n // If we are at the end of the buffer, can't move forward\n let pos = cursor;\n if (!isAtBufferEnd(buffer, pos)) {\n pos = moveRight(buffer, pos);\n }\n else{\n return pos;\n }\n\n // If we're at end of line (empty string), move forward to cross line boundary\n // But only if we're not at the buffer end\n if (getCharAt(buffer, pos) === '' && !isAtBufferEnd(buffer, pos)) {\n pos = moveRight(buffer, pos);\n }\n\n // If we moved to buffer end and there's no word/punctuation, go back one\n if (isAtBufferEnd(buffer, pos) && !isOnWord(buffer, pos) && !isOnPunctuation(buffer, pos)) {\n return moveLeft(buffer, pos);\n }\n\n //skip whitespace first if on whitespace char\n if (isOnWhitespace(buffer, pos)) {\n pos = skipWhile(buffer, pos, isWhitespace, true);\n }\n\n //skip to punctuation group end if on punctuation char\n if (isOnPunctuation(buffer, pos)) {\n pos = skipWhile(buffer, pos, (c) => isPunctuation(c), true);\n return moveLeft(buffer, pos);\n }\n //skip to word end if on word char\n if (isOnWord(buffer, pos)) {\n pos = skipWhile(buffer, pos, isWordChar, true);\n return moveLeft(buffer, pos);\n }\n\n //Skipped all whitespace, no characters left\n return pos;\n}\n\n/**\n * WORD (big word) navigation - whitespace separated\n */\n\n/**\n * Find the start of the next WORD (W motion)\n * WORDs are whitespace-separated (hello-world is one WORD)\n */\nexport function findNextWORDStart(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer end, can't move forward\n if (isAtBufferEnd(buffer, cursor)) {\n return cursor;\n }\n\n let pos = cursor;\n const char = getCharAt(buffer, pos);\n\n // If on whitespace, skip it\n if (isWhitespace(char)) {\n pos = skipWhile(buffer, pos, isWhitespace, true);\n return pos;\n }\n\n // If on empty string (end of line), cross to next line\n if (char === '') {\n pos = moveRight(buffer, pos);\n pos = skipWhile(buffer, pos, isWhitespace, true);\n return pos;\n }\n\n // Skip current WORD (anything non-whitespace)\n pos = skipWhile(buffer, pos, (c) => c !== '' && !isWhitespace(c), true);\n\n // If we're at end of line (empty string), move forward to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferEnd(buffer, pos)) {\n pos = moveRight(buffer, pos);\n }\n\n // Skip whitespace (including newlines)\n pos = skipWhile(buffer, pos, isWhitespace, true);\n\n return pos;\n}\n\n/**\n * Find the end of the next WORD (E motion)\n * WORDs are whitespace-separated\n */\nexport function findNextWORDEnd(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer end, can't move forward\n if (isAtBufferEnd(buffer, cursor)) {\n return cursor;\n }\n\n let pos = moveRight(buffer, cursor);\n\n // If we landed on end of line (empty string), move forward to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferEnd(buffer, pos)) {\n pos = moveRight(buffer, pos);\n }\n\n // If we moved to buffer end and there's nothing there, go back one\n if (isAtBufferEnd(buffer, pos) && getCharAt(buffer, pos) === '') {\n return moveLeft(buffer, pos);\n }\n\n // Skip whitespace\n pos = skipWhile(buffer, pos, isWhitespace, true);\n\n // Skip non-whitespace to find end of WORD\n pos = skipWhile(buffer, pos, (c) => c !== '' && !isWhitespace(c), true);\n\n // We went one past the end, move back\n return moveLeft(buffer, pos);\n}\n\n/**\n * Find the start of the previous WORD (B motion)\n * WORDs are whitespace-separated\n */\nexport function findPrevWORDStart(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer start, can't move backward\n if (isAtBufferStart(cursor)) {\n return cursor;\n }\n\n let pos = moveLeft(buffer, cursor);\n\n // If we landed on end of line (empty string), move left again to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferStart(pos)) {\n pos = moveLeft(buffer, pos);\n }\n\n // Skip whitespace backward\n pos = skipWhile(buffer, pos, isWhitespace, false);\n\n // Skip non-whitespace backward to find start of WORD\n pos = skipWhile(buffer, pos, (c) => c !== '' && !isWhitespace(c), false);\n\n // We went one past the start, move forward if needed\n if (!isAtBufferStart(pos) && isWhitespace(getCharAt(buffer, pos))) {\n pos = moveRight(buffer, pos);\n }\n\n return pos;\n}\n\n/**\n * Find the end of the previous word (ge motion)\n * This is the mirror of 'e' but going backward\n */\nexport function findPrevWordEnd(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer start, can't move backward\n if (isAtBufferStart(cursor)) {\n return cursor;\n }\n\n let pos = moveLeft(buffer, cursor);\n\n // If we landed on end of line (empty string), move left again to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferStart(pos)) {\n pos = moveLeft(buffer, pos);\n }\n\n // Skip whitespace backward\n pos = skipWhile(buffer, pos, isWhitespace, false);\n\n // If we're at start of buffer after skipping whitespace, return\n if (isAtBufferStart(pos)) {\n return pos;\n }\n\n // Now we should be on the end of a word or punctuation\n // Just return this position - we've already landed at the end of the previous word\n return pos;\n}\n\n/**\n * Find the end of the previous WORD (gE motion)\n * WORDs are whitespace-separated (hello-world is one WORD)\n */\nexport function findPrevWORDEnd(buffer: Buffer, cursor: Cursor): Cursor {\n // If at buffer start, can't move backward\n if (isAtBufferStart(cursor)) {\n return cursor;\n }\n\n let pos = moveLeft(buffer, cursor);\n\n // If we landed on end of line (empty string), move left again to cross line boundary\n if (getCharAt(buffer, pos) === '' && !isAtBufferStart(pos)) {\n pos = moveLeft(buffer, pos);\n }\n\n // Skip whitespace backward\n pos = skipWhile(buffer, pos, isWhitespace, false);\n\n // If we're at start of buffer after skipping whitespace, return\n if (isAtBufferStart(pos)) {\n return pos;\n }\n\n // Now we should be on the end of a WORD (any non-whitespace character)\n return pos;\n}\n\n/**\n * Whitespace navigation\n */\nexport function skipWhitespace(buffer: Buffer, cursor: Cursor): Cursor {\n return skipWhile(buffer, cursor, isWhitespace, true);\n}\n","import type {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Line navigation\n */\n\n/**\n * First non-blank character on cursor's line\n */\nexport function findFirstNonBlank(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = buffer.content.split('\\n');\n const line = lines[cursor.line] ?? '';\n let col = 0;\n while (col < line.length && (line[col] === ' ' || line[col] === '\\t')) {\n col++;\n }\n return new Cursor(cursor.line, col);\n}\n\n/**\n * Move to start of current line\n */\nexport function findLineStart(cursor: Cursor): Cursor {\n return new (cursor.constructor as typeof Cursor)(cursor.line, 0);\n}\n\n/**\n * Move to end of current line\n */\nexport function findLineEnd(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = buffer.content.split('\\n');\n const line = lines[cursor.line] ?? '';\n return new (cursor.constructor as typeof Cursor)(cursor.line, line.length);\n}\n","import {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\nimport {State} from \"../core/state\";\nimport {VimViewport} from \"../core/viewport\";\n\n/**\n * Get lines array from buffer\n */\nexport function getLines(buffer: Buffer): string[] {\n return buffer.content.split('\\n');\n}\n\n/**\n * Get specific line\n */\nexport function getLine(buffer: Buffer, lineNum: number): string {\n const lines = getLines(buffer);\n return lines[lineNum] ?? '';\n}\n\n/**\n * Delete line and return new buffer content\n */\nexport function deleteLine(buffer: Buffer, lineNum: number): string {\n const lines = getLines(buffer);\n lines.splice(lineNum, 1);\n return lines.join('\\n');\n}\n\n/**\n * Delete multiple lines\n */\nexport function deleteLines(buffer: Buffer, startLine: number, count: number): string {\n const lines = getLines(buffer);\n lines.splice(startLine, count);\n return lines.join('\\n');\n}\n\n/**\n * Create new state with updated buffer content\n */\nexport function withBufferContent(state: State, content: string): State {\n return new State(\n new Buffer(content),\n state.cursor,\n state.selection,\n state.mode,\n state.commandLine,\n state.desiredColumn,\n state.viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n\n/**\n * Create new state with updated cursor\n * By default, preserves desiredColumn (for vertical motions)\n */\nexport function withCursor(state: State, cursor: Cursor, preserveDesiredColumn: boolean = true): State {\n return new State(\n state.buffer,\n cursor,\n state.selection,\n state.mode,\n state.commandLine,\n preserveDesiredColumn ? state.desiredColumn : null,\n state.viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n\n/**\n * Create new state with updated cursor, maintaining desiredColumn for vertical motion\n * Sets desiredColumn to the target column if not already set\n */\nexport function withCursorVertical(state: State, cursor: Cursor, targetColumn: number): State {\n const desiredCol = state.desiredColumn ?? targetColumn;\n return new State(\n state.buffer,\n cursor,\n state.selection,\n state.mode,\n state.commandLine,\n desiredCol,\n state.viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n\n/**\n * Create new state with updated cursor and reset desiredColumn (for horizontal motions)\n */\nexport function withCursorHorizontal(state: State, cursor: Cursor): State {\n return new State(\n state.buffer,\n cursor,\n state.selection,\n state.mode,\n state.commandLine,\n null,\n state.viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n\n/**\n * Create new state with updated viewport\n */\nexport function withViewport(state: State, topLine: number): State {\n const viewport = new VimViewport(topLine, state.viewport.height);\n return new State(\n state.buffer,\n state.cursor,\n state.selection,\n state.mode,\n state.commandLine,\n state.desiredColumn,\n viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n\n/**\n * Create new state with updated cursor and viewport\n */\nexport function withCursorAndViewport(state: State, cursor: Cursor, topLine: number, desiredCol: number | null = null): State {\n const viewport = new VimViewport(topLine, state.viewport.height);\n return new State(\n state.buffer,\n cursor,\n state.selection,\n state.mode,\n state.commandLine,\n desiredCol ?? state.desiredColumn,\n viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n\n/**\n * Clamp cursor to valid buffer position\n */\nexport function clampCursor(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = getLines(buffer);\n const maxLine = Math.max(0, lines.length - 1);\n const line = Math.max(0, Math.min(cursor.line, maxLine));\n const lineContent = lines[line] ?? '';\n const maxCol = Math.max(0, lineContent.length);\n const column = Math.max(0, Math.min(cursor.column, maxCol));\n return new Cursor(line, column);\n}\n\n/**\n * Clamp cursor for normal mode vertical motion\n * In normal mode, cursor must be ON a character, not past the end\n */\nexport function clampCursorNormalMode(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = getLines(buffer);\n const maxLine = Math.max(0, lines.length - 1);\n const line = Math.max(0, Math.min(cursor.line, maxLine));\n const lineContent = lines[line] ?? '';\n // For non-empty lines, max column is length - 1 (last character index)\n // For empty lines, max column is 0\n const maxCol = Math.max(0, lineContent.length - 1);\n const column = Math.max(0, Math.min(cursor.column, maxCol));\n return new Cursor(line, column);\n}\n\n/**\n * Clamp cursor for vertical motion (j/k) with Vim's whitespace handling.\n * If the desired column would land in leading whitespace (before any non-whitespace),\n * move to the beginning of the line instead.\n */\nexport function clampCursorVerticalMotion(buffer: Buffer, cursor: Cursor, desiredColumn: number): Cursor {\n const lines = getLines(buffer);\n const maxLine = Math.max(0, lines.length - 1);\n const line = Math.max(0, Math.min(cursor.line, maxLine));\n const lineContent = lines[line] ?? '';\n\n // For empty lines, always go to column 0\n if (lineContent.length === 0) {\n return new Cursor(line, 0);\n }\n\n // Clamp to valid position\n const maxCol = Math.max(0, lineContent.length - 1);\n const targetCol = Math.max(0, Math.min(desiredColumn, maxCol));\n\n // Check if the target position is whitespace\n const charAtTarget = lineContent[targetCol];\n const isTargetWhitespace = charAtTarget === ' ' || charAtTarget === '\\t';\n\n if (isTargetWhitespace) {\n // Check if all characters before target are also whitespace\n const beforeTarget = lineContent.slice(0, targetCol);\n const allWhitespaceBefore = beforeTarget.split('').every(ch => ch === ' ' || ch === '\\t');\n\n if (allWhitespaceBefore) {\n // Target is in leading whitespace, go to beginning of line\n return new Cursor(line, 0);\n }\n }\n\n return new Cursor(line, targetCol);\n}\n\n/**\n * Update visual selection based on current cursor and anchor\n * Used when cursor moves in visual mode\n */\nexport function updateVisualSelection(state: State, newCursor: Cursor): State {\n if (!state.visualAnchor) return state;\n\n return new State(\n state.buffer,\n newCursor,\n { start: state.visualAnchor, end: newCursor },\n state.mode,\n state.commandLine,\n state.desiredColumn,\n state.viewport,\n state.visualAnchor,\n state.lastVisualSelection,\n state.recordingRegister,\n state.lastMacroRegister\n );\n}\n","import type {Buffer} from \"../core/buffer\";\nimport type {Cursor} from \"../core/cursor\";\nimport {Cursor as CursorClass} from \"../core/cursor\";\n\nimport type {Range} from \"../types/Range\";\n\n/**\n * Normalize a range so that start always comes before end.\n * Handles backward motions where end < start.\n */\nexport function normalizeRange(range: Range): Range {\n const {start, end} = range;\n\n // Compare positions\n if (start.line < end.line) {\n return range; // Already normalized\n }\n if (start.line > end.line) {\n return {start: end, end: start}; // Swap\n }\n // Same line - compare columns\n if (start.column <= end.column) {\n return range; // Already normalized\n }\n return {start: end, end: start}; // Swap\n}\n\n/**\n * Extract text content from a range\n */\nexport function getTextInRange(buffer: Buffer, range: Range): string {\n const lines = buffer.content.split('\\n');\n\n if (range.start.line === range.end.line) {\n // Single line range\n const line = lines[range.start.line] ?? '';\n return line.slice(range.start.column, range.end.column);\n }\n\n // Multi-line range\n const parts: string[] = [];\n // First line: from start column to end of line\n parts.push((lines[range.start.line] ?? '').slice(range.start.column));\n // Middle lines: entire lines\n for (let i = range.start.line + 1; i < range.end.line; i++) {\n parts.push(lines[i] ?? '');\n }\n // Last line: from start to end column\n parts.push((lines[range.end.line] ?? '').slice(0, range.end.column));\n return parts.join('\\n');\n}\n\n/**\n * Delete text in a range and return new buffer content\n */\nexport function deleteRange(buffer: Buffer, range: Range): string {\n const lines = buffer.content.split('\\n');\n\n if (range.start.line === range.end.line) {\n // Single line deletion\n const line = lines[range.start.line] ?? '';\n lines[range.start.line] = line.slice(0, range.start.column) + line.slice(range.end.column);\n return lines.join('\\n');\n }\n\n // Multi-line deletion\n const startLine = lines[range.start.line] ?? '';\n const endLine = lines[range.end.line] ?? '';\n const merged = startLine.slice(0, range.start.column) + endLine.slice(range.end.column);\n lines.splice(range.start.line, range.end.line - range.start.line + 1, merged);\n return lines.join('\\n');\n}\n\n/**\n * Replace text in a range\n */\nexport function replaceRange(buffer: Buffer, range: Range, text: string): string {\n const lines = buffer.content.split('\\n');\n\n if (range.start.line === range.end.line) {\n // Single line replacement\n const line = lines[range.start.line] ?? '';\n lines[range.start.line] = line.slice(0, range.start.column) + text + line.slice(range.end.column);\n return lines.join('\\n');\n }\n\n // Multi-line replacement\n const startLine = lines[range.start.line] ?? '';\n const endLine = lines[range.end.line] ?? '';\n const merged = startLine.slice(0, range.start.column) + text + endLine.slice(range.end.column);\n lines.splice(range.start.line, range.end.line - range.start.line + 1, merged);\n return lines.join('\\n');\n}\n\n/**\n * Expand range to include surrounding whitespace\n * Prefers trailing whitespace, falls back to leading if at end of line\n */\nexport function expandRangeOuter(buffer: Buffer, range: Range): Range {\n const lines = buffer.content.split('\\n');\n const endLine = lines[range.end.line] ?? '';\n\n // Try to expand forward to include trailing whitespace\n let newEnd = range.end;\n let col = range.end.column;\n\n while (col < endLine.length && (endLine[col] === ' ' || endLine[col] === '\\t')) {\n col++;\n }\n\n // If we found trailing whitespace, use it\n if (col > range.end.column) {\n newEnd = new CursorClass(range.end.line, col);\n return { start: range.start, end: newEnd };\n }\n\n // No trailing whitespace - try to include leading whitespace instead\n const startLine = lines[range.start.line] ?? '';\n let startCol = range.start.column;\n\n while (startCol > 0 && (startLine[startCol - 1] === ' ' || startLine[startCol - 1] === '\\t')) {\n startCol--;\n }\n\n if (startCol < range.start.column) {\n return { start: new CursorClass(range.start.line, startCol), end: range.end };\n }\n\n // No surrounding whitespace found\n return range;\n}\n\n/**\n * Check if cursor is within range\n */\nexport function isInRange(cursor: Cursor, range: Range): boolean {\n if (cursor.line < range.start.line || cursor.line > range.end.line) {\n return false;\n }\n if (cursor.line === range.start.line && cursor.column < range.start.column) {\n return false;\n }\n if (cursor.line === range.end.line && cursor.column > range.end.column) {\n return false;\n }\n return true;\n}\n","import type {Buffer} from \"../core/buffer\";\nimport type {Cursor} from \"../core/cursor\";\nimport type {State} from \"../core/state\";\nimport {withCursor, withCursorHorizontal, withBufferContent, clampCursor, clampCursorNormalMode, getLines, getLine, deleteLines} from \"./buffer-operations\";\nimport {deleteRange, getTextInRange, normalizeRange} from \"./range-utils\";\nimport type {Range} from \"../types/Range\";\nimport type {CommandContext} from \"../types/Command\";\n\n/**\n * Get the effective count from a command context (defaults to 1).\n */\nexport function getCount(context: CommandContext): number {\n return context.count || 1;\n}\n\n/**\n * Get the text of the line at the cursor position.\n */\nexport function currentLine(state: State): string {\n return getLine(state.buffer, state.cursor.line);\n}\n\n/**\n * Get the total number of lines in the buffer.\n */\nexport function lineCount(state: State): number {\n return getLines(state.buffer).length;\n}\n\n/**\n * Get the maximum valid line index (0-based).\n */\nexport function lastLine(state: State): number {\n return Math.max(0, getLines(state.buffer).length - 1);\n}\n\n/**\n * Apply a cursor motion function `count` times, clamping the result.\n * Replaces the repeated loop+clamp pattern in word motions.\n * Resets desiredColumn since word motions are horizontal.\n */\nexport function repeatCursorMotion(\n state: State,\n context: CommandContext,\n fn: (buffer: Buffer, cursor: Cursor) => Cursor\n): State {\n const count = getCount(context);\n let cursor = state.cursor;\n for (let i = 0; i < count; i++) {\n cursor = fn(state.buffer, cursor);\n }\n return withCursorHorizontal(state, clampCursor(state.buffer, cursor));\n}\n\n/**\n * Resolve the operator range from either a text object or a motion in the context.\n * Returns null if neither is present.\n * Normalizes the range so start always comes before end (handles backward motions).\n * Handles inclusive motions by extending the range by 1 character.\n */\nexport function resolveOperatorRange(state: State, context: CommandContext): Range | null {\n let range: Range | null = null;\n\n if (context.textObject && context.variant) {\n range = context.textObject.getRange(state, context.variant);\n } else if (context.motion) {\n console.log('[DEBUG] resolveOperatorRange - motion:', context.motion.key, 'needsChar:', context.motion.needsFollowingChar, 'char in context:', context.char);\n const endState = context.motion.execute(state, context);\n let endCursor = endState.cursor;\n\n // If motion is inclusive, extend end position by 1 column\n // BUT only if the cursor actually moved (to avoid including a character when motion fails)\n if (context.motion.inclusive) {\n const cursorMoved = endCursor.line !== state.cursor.line || endCursor.column !== state.cursor.column;\n if (cursorMoved) {\n const line = getLine(state.buffer, endCursor.line);\n if (endCursor.column < line.length) {\n endCursor = {line: endCursor.line, column: endCursor.column + 1};\n }\n }\n }\n\n range = {start: state.cursor, end: endCursor};\n }\n\n // Normalize the range so start always comes before end\n return range ? normalizeRange(range) : null;\n}\n\n/**\n * Create a new state with both updated buffer content and cursor position.\n */\nexport function withContentAndCursor(state: State, content: string, cursor: Cursor): State {\n return withCursor(withBufferContent(state, content), cursor);\n}\n\n/**\n * Delete a range and store the deleted text in the register manager.\n * Returns a new state with the content deleted and cursor repositioned.\n * Normalizes the range to ensure start comes before end.\n */\nexport function deleteRangeWithRegister(\n state: State,\n range: Range,\n context: CommandContext,\n isLinewise: boolean = false\n): State {\n // Normalize range to handle backward motions\n const normalizedRange = normalizeRange(range);\n\n const deletedText = getTextInRange(state.buffer, normalizedRange);\n context.registerManager?.storeDelete(deletedText, isLinewise);\n\n let newContent: string;\n if (isLinewise) {\n // For linewise deletions, delete entire lines\n const startLine = normalizedRange.start.line;\n const endLine = normalizedRange.end.line;\n const lineCount = endLine - startLine + 1;\n newContent = deleteLines(state.buffer, startLine, lineCount);\n } else {\n newContent = deleteRange(state.buffer, normalizedRange);\n }\n\n // Clamp cursor with the new buffer content using normal mode rules\n const newBuffer = {content: newContent} as Buffer;\n const newCursor = clampCursorNormalMode(newBuffer, normalizedRange.start);\n return withContentAndCursor(state, newContent, newCursor);\n}\n","import {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport {\n findNextWordStart,\n findNextWordEnd,\n findPrevWordStart,\n findNextWORDStart,\n findNextWORDEnd,\n findPrevWORDStart,\n} from \"../utils/text-navigation\";\nimport {repeatCursorMotion} from \"../utils/state-utils\";\nimport type {CommandContext} from \"../types/Command\";\n\nexport class w extends Motion {\n key = 'w';\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findNextWordStart);\n }\n}\n\nexport class e extends Motion {\n key = 'e';\n inclusive = true; // e is inclusive - includes the last character\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findNextWordEnd);\n }\n}\n\nexport class b extends Motion {\n key = 'b';\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findPrevWordStart);\n }\n}\n\nexport class W extends Motion {\n key = 'W';\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findNextWORDStart);\n }\n}\n\nexport class E extends Motion {\n key = 'E';\n inclusive = true; // E is inclusive - includes the last character\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findNextWORDEnd);\n }\n}\n\nexport class B extends Motion {\n key = 'B';\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findPrevWORDStart);\n }\n}\n","import {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport {Cursor} from \"../core/cursor\";\nimport {findFirstNonBlank} from \"../utils/text-navigation\";\nimport {withCursor, withCursorHorizontal, withCursorVertical, clampCursorNormalMode, clampCursorVerticalMotion, getLine} from \"../utils/buffer-operations\";\nimport {getCount, lastLine} from \"../utils/state-utils\";\nimport type {CommandContext} from \"../types/Command\";\n\n/**\n * Horizontal character motions\n */\n\nexport class h extends Motion {\n key = 'h';\n\n execute(state: State, context: CommandContext): State {\n let count = getCount(context);\n let line = state.cursor.line;\n let col = state.cursor.column;\n\n while (count > 0) {\n if (col > 0) {\n // Can move left on current line\n const moveAmount = Math.min(col, count);\n col -= moveAmount;\n count -= moveAmount;\n } else if (line > 0) {\n // At start of line, wrap to end of previous line\n line--;\n const prevLine = getLine(state.buffer, line);\n col = Math.max(0, prevLine.length - 1);\n count--;\n } else {\n // At start of buffer, can't move further\n break;\n }\n }\n\n return withCursorHorizontal(state, new Cursor(line, col));\n }\n}\nexport class Backspace extends h{\n key = 'Backspace';\n}\nexport class ArrowLeft extends h{\n key = 'ArrowLeft';\n}\nexport class l extends Motion {\n key = 'l';\n\n execute(state: State, context: CommandContext): State {\n let count = getCount(context);\n let line = state.cursor.line;\n let col = state.cursor.column;\n const totalLines = lastLine(state) + 1;\n\n while (count > 0) {\n const currentLine = getLine(state.buffer, line);\n const maxCol = Math.max(0, currentLine.length - 1);\n\n if (col < maxCol) {\n // Can move right on current line\n const moveAmount = Math.min(maxCol - col, count);\n col += moveAmount;\n count -= moveAmount;\n } else if (line < lastLine(state)) {\n // At end of line, wrap to start of next line\n line++;\n col = 0;\n count--;\n } else {\n // At end of buffer, can't move further\n break;\n }\n }\n\n return withCursorHorizontal(state, new Cursor(line, col));\n }\n}\n\nexport class ArrowRight extends l{\n key = 'ArrowRight';\n}\n/**\n * Vertical line motions\n */\n\nexport class j extends Motion {\n key = 'j';\n\n execute(state: State, context: CommandContext): State {\n const targetLine = Math.min(state.cursor.line + getCount(context), lastLine(state));\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const newCursor = clampCursorVerticalMotion(state.buffer, new Cursor(targetLine, desiredCol), desiredCol);\n return withCursorVertical(state, newCursor, desiredCol);\n }\n}\nexport class ArrowDown extends j{\n key = 'ArrowDown';\n}\nexport class Enter extends Motion{\n key = 'Enter';\n\n // Go to first non-blank character of the next line\n execute(state: State, context: CommandContext): State {\n const targetLine = Math.min(state.cursor.line + getCount(context), lastLine(state));\n const newCursor = findFirstNonBlank(state.buffer, new Cursor(targetLine, 0));\n return withCursorVertical(state, newCursor, newCursor.column);\n }\n\n\n}\n\nexport class k extends Motion {\n key = 'k';\n\n execute(state: State, context: CommandContext): State {\n const targetLine = Math.max(0, state.cursor.line - getCount(context));\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const newCursor = clampCursorVerticalMotion(state.buffer, new Cursor(targetLine, desiredCol), desiredCol);\n return withCursorVertical(state, newCursor, desiredCol);\n }\n}\nexport class ArrowUp extends k{\n key = 'ArrowUp';\n}\nexport class G extends Motion {\n key = 'G';\n public linewise = true; // G operates on entire lines when used with operators\n\n execute(state: State, context: CommandContext): State {\n const targetLine = context.count !== undefined\n ? Math.min(context.count - 1, lastLine(state)) // 1-indexed count\n : lastLine(state); // default: last line\n const cursor = new Cursor(Math.max(0, targetLine), 0);\n return withCursorHorizontal(state, findFirstNonBlank(state.buffer, cursor));\n }\n}\n\n\nexport class gg extends Motion {\n key = 'gg';\n public linewise = true; // gg operates on entire lines when used with operators\n\n execute(state: State, context: CommandContext): State {\n const targetLine = context.count !== undefined\n ? Math.min(context.count - 1, lastLine(state)) // 1-indexed count\n : 0; // default: first line\n const cursor = new Cursor(Math.max(0, targetLine), 0);\n return withCursorHorizontal(state, findFirstNonBlank(state.buffer, cursor));\n }\n}\n\n/**\n * Line position motions\n */\n\nexport class zero extends Motion {\n key = '0';\n\n execute(state: State): State {\n return withCursorHorizontal(state, new Cursor(state.cursor.line, 0));\n }\n}\n\nexport class dollar extends Motion {\n key = '$';\n public inclusive = true; // $ is inclusive when used with operators\n\n execute(state: State, context: CommandContext): State {\n const targetLine = Math.min(state.cursor.line + getCount(context) - 1, lastLine(state));\n const lines = state.buffer.content.split('\\n');\n const col = Math.max(0, (lines[targetLine] ?? '').length - 1);\n return withCursorHorizontal(state, new Cursor(targetLine, col));\n }\n}\nexport class End extends dollar{\n key = 'End';\n}\nexport class caret extends Motion {\n key = '^';\n\n execute(state: State): State {\n return withCursorHorizontal(state, findFirstNonBlank(state.buffer, state.cursor));\n }\n}\nexport class Home extends caret{\n key = 'Home';\n}\n","export class Register {\n constructor(\n public content: string = '',\n public linewise: boolean = false,\n ) {}\n}\n","import { Register } from './register';\n\nexport class RegisterManager {\n private registers: Map<string, Register> = new Map();\n\n get(name: string): Register | undefined {\n return this.registers.get(name);\n }\n\n set(name: string, content: string, linewise: boolean): void {\n this.registers.set(name, new Register(content, linewise));\n }\n\n /**\n * Store deleted text: writes to unnamed register `\"` and shifts numbered registers 1-9.\n */\n storeDelete(content: string, linewise: boolean): void {\n // Shift numbered registers 9 <- 8 <- ... <- 1\n for (let i = 9; i >= 2; i--) {\n const prev = this.registers.get(String(i - 1));\n if (prev) {\n this.registers.set(String(i), new Register(prev.content, prev.linewise));\n }\n }\n this.registers.set('1', new Register(content, linewise));\n this.registers.set('\"', new Register(content, linewise));\n }\n\n /**\n * Store yanked text: writes to register `0` and unnamed register `\"`.\n */\n storeYank(content: string, linewise: boolean): void {\n this.registers.set('0', new Register(content, linewise));\n this.registers.set('\"', new Register(content, linewise));\n }\n\n /**\n * Returns a snapshot of all non-empty registers for display.\n */\n getAll(): Map<string, Register> {\n return new Map(this.registers);\n }\n\n getDefaultRegister(): Register | undefined {\n return this.registers.get('\"')\n }\n}\n","import type { State } from '../core/state';\n\nexport class Change {\n constructor(\n public stateBefore: State,\n public stateAfter: State,\n public keySequence: string,\n public timestamp: number,\n ) {}\n}\n","import { Change } from './change';\nimport type { State } from '../core/state';\n\nexport class UndoStack {\n private entries: Change[] = [];\n private currentIndex: number = -1;\n\n push(change: Change): void {\n // Truncate any redo entries above current position\n this.entries = this.entries.slice(0, this.currentIndex + 1);\n this.entries.push(change);\n this.currentIndex = this.entries.length - 1;\n }\n\n undo(): State | null {\n if (this.currentIndex < 0) return null;\n const change = this.entries[this.currentIndex]!;\n this.currentIndex--;\n return change.stateBefore;\n }\n\n redo(): State | null {\n if (this.currentIndex >= this.entries.length - 1) return null;\n this.currentIndex++;\n const change = this.entries[this.currentIndex]!;\n return change.stateAfter;\n }\n\n getEntries(): Change[] {\n return [...this.entries];\n }\n\n getCurrentIndex(): number {\n return this.currentIndex;\n }\n}\n","import type {Buffer} from \"./buffer\";\n\nexport interface IndentConfig {\n useSpaces: boolean;\n indentSize: number;\n}\n\n/**\n * Manages indentation detection, calculation, and adjustment\n */\nexport class IndentationManager {\n private config: IndentConfig;\n\n constructor(config?: Partial<IndentConfig>) {\n this.config = {\n useSpaces: config?.useSpaces ?? true,\n indentSize: config?.indentSize ?? 4\n };\n }\n\n /**\n * Detect indentation style from buffer content\n * Analyzes the buffer to determine if tabs or spaces are used,\n * and what the indent size is.\n */\n detectIndentation(buffer: Buffer): IndentConfig {\n const lines = buffer.content.split('\\n');\n let spacesCount = 0;\n let tabsCount = 0;\n const spaceSizes: number[] = [];\n\n for (const line of lines) {\n if (line.length === 0) continue;\n\n const match = line.match(/^(\\s+)/);\n if (!match) continue;\n\n const indent = match[1]!;\n if (indent.includes('\\t')) {\n tabsCount++;\n } else {\n spacesCount++;\n spaceSizes.push(indent.length);\n }\n }\n\n // Determine if spaces or tabs are preferred\n const useSpaces = spacesCount >= tabsCount;\n\n // Determine indent size from most common space count\n let indentSize = 4; // default\n if (useSpaces && spaceSizes.length > 0) {\n // Find GCD of space sizes to determine indent unit\n const gcd = (a: number, b: number): number => b === 0 ? a : gcd(b, a % b);\n indentSize = spaceSizes.reduce((acc, size) => gcd(acc, size), spaceSizes[0] ?? 4);\n // Clamp to reasonable range\n indentSize = Math.max(1, Math.min(8, indentSize));\n }\n\n return {useSpaces, indentSize};\n }\n\n /**\n * Update the indent configuration\n */\n setConfig(config: Partial<IndentConfig>): void {\n this.config = {...this.config, ...config};\n }\n\n /**\n * Get the current indent configuration\n */\n getConfig(): IndentConfig {\n return {...this.config};\n }\n\n /**\n * Get the indent string for a given level\n */\n getIndentString(level: number): string {\n if (this.config.useSpaces) {\n return ' '.repeat(level * this.config.indentSize);\n } else {\n return '\\t'.repeat(level);\n }\n }\n\n /**\n * Get the indent of a line (leading whitespace)\n */\n getLineIndent(line: string): string {\n const match = line.match(/^(\\s*)/);\n return match ? match[1]! : '';\n }\n\n /**\n * Get the indent level of a line (number of indent units)\n */\n getIndentLevel(line: string): number {\n const indent = this.getLineIndent(line);\n if (indent.length === 0) return 0;\n\n if (this.config.useSpaces) {\n return Math.floor(indent.length / this.config.indentSize);\n } else {\n return indent.split('\\t').length - 1;\n }\n }\n\n /**\n * Calculate indent for a new line after a given line\n * Uses smart indentation based on the content of the previous line\n */\n calculateIndentForNewLine(buffer: Buffer, afterLineIndex: number): string {\n const lines = buffer.content.split('\\n');\n if (afterLineIndex < 0 || afterLineIndex >= lines.length) {\n return '';\n }\n\n const prevLine = lines[afterLineIndex] ?? '';\n const prevIndent = this.getLineIndent(prevLine);\n const prevLevel = this.getIndentLevel(prevLine);\n\n // Smart indent: increase indent after lines ending with {, [, (\n const trimmedPrev = prevLine.trim();\n if (trimmedPrev.endsWith('{') || trimmedPrev.endsWith('[') || trimmedPrev.endsWith('(')) {\n return this.getIndentString(prevLevel + 1);\n }\n\n // Smart indent: decrease indent for lines starting with }, ], )\n const trimmedCurrent = prevLine.trimStart();\n if (trimmedCurrent.startsWith('}') || trimmedCurrent.startsWith(']') || trimmedCurrent.startsWith(')')) {\n return this.getIndentString(Math.max(0, prevLevel - 1));\n }\n\n // Default: maintain same indent as previous line\n return prevIndent;\n }\n\n /**\n * Adjust indent of content to match target indent\n * Takes content (possibly multi-line) and adjusts its indentation\n * to match the target indent while preserving relative indentation\n */\n adjustIndent(content: string, targetIndent: string): string {\n const lines = content.split('\\n');\n if (lines.length === 0) return content;\n\n // Find the base indent (minimum indent of non-empty lines)\n let baseIndent = Infinity;\n for (const line of lines) {\n if (line.trim().length === 0) continue;\n const level = this.getIndentLevel(line);\n baseIndent = Math.min(baseIndent, level);\n }\n\n if (baseIndent === Infinity) {\n // All lines are empty, just return as-is\n return content;\n }\n\n const targetLevel = this.getIndentLevel(targetIndent);\n\n // Adjust each line\n const adjustedLines = lines.map(line => {\n if (line.trim().length === 0) return line; // Keep empty lines as-is\n\n const currentLevel = this.getIndentLevel(line);\n const relativeLevel = currentLevel - baseIndent;\n const newLevel = targetLevel + relativeLevel;\n\n // Remove old indent and add new indent\n const contentWithoutIndent = line.replace(/^\\s*/, '');\n return this.getIndentString(newLevel) + contentWithoutIndent;\n });\n\n return adjustedLines.join('\\n');\n }\n\n /**\n * Re-indent a line to a specific level\n */\n reindentLine(line: string, level: number): string {\n const contentWithoutIndent = line.replace(/^\\s*/, '');\n return this.getIndentString(level) + contentWithoutIndent;\n }\n}\n","/**\n * Vim configuration options\n */\nexport interface VimConfig {\n // Display options\n number: boolean; // Show line numbers\n relativenumber: boolean; // Show relative line numbers\n wrap: boolean; // Wrap long lines\n cursorline: boolean; // Highlight current line\n\n // Indentation options\n tabstop: number; // Number of spaces a tab counts for\n shiftwidth: number; // Number of spaces for auto-indent\n expandtab: boolean; // Use spaces instead of tabs\n autoindent: boolean; // Copy indent from previous line\n smartindent: boolean; // Smart auto-indenting\n\n // Search options\n ignorecase: boolean; // Case insensitive search\n smartcase: boolean; // Override ignorecase if search has uppercase\n hlsearch: boolean; // Highlight search results\n incsearch: boolean; // Show match as you type\n\n // Editing options\n undolevels: number; // Maximum number of undo levels\n clipboard: 'unnamed' | 'unnamedplus' | ''; // System clipboard integration\n}\n\nexport type VimConfigKey = keyof VimConfig;\n\n/**\n * Manages Vim configuration options\n */\nexport class ConfigManager {\n private config: VimConfig;\n private listeners: Map<VimConfigKey | '*', Set<(key: VimConfigKey, value: unknown) => void>> = new Map();\n\n constructor(initialConfig?: Partial<VimConfig>) {\n // Default Vim-like configuration\n this.config = {\n // Display\n number: false,\n relativenumber: false,\n wrap: true,\n cursorline: false,\n\n // Indentation\n tabstop: 4,\n shiftwidth: 2,\n expandtab: true,\n autoindent: true,\n smartindent: false,\n\n // Search\n ignorecase: false,\n smartcase: false,\n hlsearch: true,\n incsearch: true,\n\n // Editing\n undolevels: 1000,\n clipboard: '',\n\n ...initialConfig\n };\n }\n\n /**\n * Get a config value\n */\n get<K extends VimConfigKey>(key: K): VimConfig[K] {\n return this.config[key];\n }\n\n /**\n * Set a config value\n */\n set<K extends VimConfigKey>(key: K, value: VimConfig[K]): void {\n const oldValue = this.config[key];\n if (oldValue === value) return; // No change\n\n this.config[key] = value;\n this.notifyListeners(key, value);\n }\n\n /**\n * Set multiple config values at once\n */\n setMultiple(updates: Partial<VimConfig>): void {\n for (const [key, value] of Object.entries(updates)) {\n this.set(key as VimConfigKey, value as any);\n }\n }\n\n /**\n * Get all config values\n */\n getAll(): Readonly<VimConfig> {\n return {...this.config};\n }\n\n /**\n * Reset to default configuration\n */\n reset(): void {\n const defaults = new ConfigManager().getAll();\n this.setMultiple(defaults);\n }\n\n /**\n * Toggle a boolean config option\n */\n toggle(key: VimConfigKey): void {\n const value = this.config[key];\n if (typeof value === 'boolean') {\n this.set(key, !value as any);\n }\n }\n\n /**\n * Subscribe to config changes\n * @param key - Config key to watch, or '*' for all changes\n * @param callback - Function to call when config changes\n * @returns Unsubscribe function\n */\n onChange(\n key: VimConfigKey | '*',\n callback: (key: VimConfigKey, value: unknown) => void\n ): () => void {\n if (!this.listeners.has(key)) {\n this.listeners.set(key, new Set());\n }\n this.listeners.get(key)!.add(callback);\n\n // Return unsubscribe function\n return () => {\n this.listeners.get(key)?.delete(callback);\n };\n }\n\n /**\n * Notify all listeners of a config change\n */\n private notifyListeners(key: VimConfigKey, value: unknown): void {\n // Notify specific listeners\n this.listeners.get(key)?.forEach(callback => callback(key, value));\n\n // Notify wildcard listeners\n this.listeners.get('*')?.forEach(callback => callback(key, value));\n }\n\n /**\n * Parse a Vim set command string (e.g., \"number\", \"nonumber\", \"tabstop=4\")\n */\n parseSetCommand(command: string): boolean {\n const noMatch = command.match(/^no(\\w+)$/);\n if (noMatch) {\n const key = noMatch[1] as VimConfigKey;\n if (key in this.config && typeof this.config[key] === 'boolean') {\n this.set(key, false as any);\n return true;\n }\n return false;\n }\n\n const valueMatch = command.match(/^(\\w+)=(.+)$/);\n if (valueMatch) {\n const key = valueMatch[1] as VimConfigKey;\n const value = valueMatch[2];\n\n if (!(key in this.config)) return false;\n\n const currentValue = this.config[key];\n if (typeof currentValue === 'number') {\n const numValue = parseInt(value!, 10);\n if (!isNaN(numValue)) {\n this.set(key, numValue as any);\n return true;\n }\n } else if (typeof currentValue === 'string') {\n this.set(key, value as any);\n return true;\n }\n return false;\n }\n\n // Simple boolean flag\n const key = command as VimConfigKey;\n if (key in this.config && typeof this.config[key] === 'boolean') {\n this.set(key, true as any);\n return true;\n }\n\n return false;\n }\n\n /**\n * Get a formatted string representation of a config value\n */\n formatValue(key: VimConfigKey): string {\n const value = this.config[key];\n if (typeof value === 'boolean') {\n return value ? key : `no${key}`;\n }\n return `${key}=${value}`;\n }\n}\n","import type {State} from \"./state\";\nimport {Mode} from \"../types/Modes\";\nimport {Command, type CommandContext} from \"../types/Command\";\n\nexport abstract class ModeTransition extends Command {\n abstract targetMode: Mode;\n\n // Optional hook to modify state before mode transition\n protected beforeTransition(state: State, context: CommandContext): State {\n return state;\n }\n\n execute(state: State, context: CommandContext): State {\n const modifiedState = this.beforeTransition(state, context);\n return {\n ...modifiedState,\n mode: this.targetMode\n };\n }\n}\n","import {ModeTransition} from \"../core/mode-transition\";\nimport {Mode} from \"../types/Modes\";\nimport type {State} from \"../core/state\";\nimport {Cursor} from \"../core/cursor\";\nimport {Buffer} from \"../core/buffer\";\nimport type {CommandContext} from \"../types/Command\";\n\n// Colon command - enters command mode\nexport class Colon extends ModeTransition {\n key = ':';\n targetMode = Mode.COMMAND;\n\n protected beforeTransition(state: State, context: CommandContext): State {\n // Initialize command line with colon prefix\n return {\n ...state,\n commandLine: ':'\n };\n }\n}\n\n// Insert mode commands\nexport class InsertAtCursor extends ModeTransition {\n key = 'i';\n targetMode = Mode.INSERT;\n}\n\nexport class InsertAtLineStart extends ModeTransition {\n key = 'I';\n targetMode = Mode.INSERT;\n\n protected beforeTransition(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const firstNonBlank = currentLine.match(/\\S/)?.index ?? 0;\n\n return {\n ...state,\n cursor: new Cursor(state.cursor.line, firstNonBlank)\n };\n }\n}\n\nexport class AppendAfterCursor extends ModeTransition {\n key = 'a';\n targetMode = Mode.INSERT;\n\n protected beforeTransition(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const newColumn = Math.min(state.cursor.column + 1, currentLine.length);\n\n return {\n ...state,\n cursor: new Cursor(state.cursor.line, newColumn)\n };\n }\n}\n\nexport class AppendAtLineEnd extends ModeTransition {\n key = 'A';\n targetMode = Mode.INSERT;\n\n protected beforeTransition(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n return {\n ...state,\n cursor: new Cursor(state.cursor.line, currentLine.length)\n };\n }\n}\n\nexport class OpenLineBelow extends ModeTransition {\n key = 'o';\n targetMode = Mode.INSERT;\n\n protected beforeTransition(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const newLine = state.cursor.line + 1;\n\n // Calculate indent for the new line\n const indentManager = context.indentationManager;\n const indent = indentManager\n ? indentManager.calculateIndentForNewLine(state.buffer, state.cursor.line)\n : '';\n\n // Insert a new line below the current line with proper indentation\n lines.splice(newLine, 0, indent);\n const newContent = lines.join('\\n');\n\n return {\n ...state,\n buffer: new Buffer(newContent),\n cursor: new Cursor(newLine, indent.length)\n };\n }\n}\n\nexport class OpenLineAbove extends ModeTransition {\n key = 'O';\n targetMode = Mode.INSERT;\n\n protected beforeTransition(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n\n // Calculate indent for the new line (based on current line or line above)\n const indentManager = context.indentationManager;\n const indent = indentManager\n ? indentManager.calculateIndentForNewLine(\n state.buffer,\n Math.max(0, state.cursor.line - 1)\n )\n : '';\n\n // Insert a new line above the current line with proper indentation\n lines.splice(state.cursor.line, 0, indent);\n const newContent = lines.join('\\n');\n\n return {\n ...state,\n buffer: new Buffer(newContent),\n cursor: new Cursor(state.cursor.line, indent.length)\n };\n }\n}\n","import {Command} from \"../types/Command\";\n\nexport abstract class Operator extends Command {\n // Operators typically accept all these\n public acceptsPrecedingCount = true;\n public acceptsMotion = true;\n public acceptsTextObject = true;\n public acceptsRegister = true; // Operators can be prefixed with register (e.g., \"ayy)\n}\n","\n\n// Delete with motion: dw, de, d$, etc.\nimport {Operator} from \"../core/operator\";\nimport {type State} from \"../core/state\";\nimport {deleteLine, deleteLines, clampCursor} from \"../utils/buffer-operations\";\nimport {Cursor} from \"../core/cursor\";\nimport {resolveOperatorRange, withContentAndCursor, deleteRangeWithRegister} from \"../utils/state-utils\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport {Mode} from \"../types/Modes\";\n\nexport class d extends Operator {\n key = 'd';\n\n execute(state: State, context: CommandContext): State {\n // If in visual mode, use selection\n let range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Visual mode selections are inclusive on both ends,\n // but deleteRange expects exclusive end, so increment end column\n if (state.selection && (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK)) {\n range = {\n start: range.start,\n end: {\n line: range.end.line,\n column: range.end.column + 1\n }\n };\n }\n\n // Determine if it's linewise based on visual mode or motion\n const isLinewise = state.mode === Mode.VISUAL_LINE || (context.motion?.linewise ?? false);\n\n const newState = deleteRangeWithRegister(state, range, context, isLinewise);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n return newState;\n }\n}\n\n// Delete line: dd (double key commands are special - they're standalone)\nexport class dd extends Command {\n key = 'dd';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const count = context.count ?? 1;\n const lines = state.buffer.content.split('\\n');\n const startLine = state.cursor.line;\n\n // Collect deleted lines for register (limited by buffer size)\n const actualCount = Math.min(count, lines.length - startLine);\n const deletedLines = lines.slice(startLine, startLine + actualCount);\n context.registerManager?.storeDelete(deletedLines.join('\\n'), true);\n\n // Delete the lines using deleteLines helper\n const newContent = deleteLines(state.buffer, startLine, actualCount);\n\n // Clamp cursor to valid line\n const newCursor = clampCursor(\n {content: newContent} as any,\n new Cursor(startLine, 0)\n );\n\n return withContentAndCursor(state, newContent, newCursor);\n }\n}\n\nexport class Delete extends Operator{\n key = 'Delete';\n\n execute(state: State, context: CommandContext): State {\n\n // If selection exists, delete selection\n if (state.selection) {\n return deleteRangeWithRegister(state, state.selection, context, false);\n }\n //Else, delete character under cursor\n return deleteRangeWithRegister(state, {start: state.cursor, end: new Cursor(state.cursor.line, state.cursor.column + 1)}, context, false);\n }\n}\n","import type {State} from \"./state\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport {Motion} from \"./motion\";\n\n/**\n * Character-capture command base class\n * For commands that need to capture a following character (f, t, r, m, ', \", `)\n */\nexport abstract class CharacterCaptureCommand extends Command {\n public needsFollowingChar = true;\n public acceptsPrecedingCount = true;\n\n // Subclasses implement this instead of execute\n abstract executeWithChar(state: State, char: string, context: CommandContext): State;\n\n execute(state: State, context: CommandContext): State {\n if (!context.char) {\n throw new Error(`${this.key} requires a character`);\n }\n return this.executeWithChar(state, context.char, context);\n }\n}\n\n/**\n * Character-capture motion base class\n * For motions that need to capture a following character (f, t, F, T)\n */\nexport abstract class CharacterCaptureMotion extends Motion {\n public needsFollowingChar = true;\n\n // Subclasses implement this instead of execute\n abstract executeWithChar(state: State, char: string, context: CommandContext): State;\n\n execute(state: State, context: CommandContext): State {\n if (!context.char) {\n throw new Error(`${this.key} requires a character`);\n }\n return this.executeWithChar(state, context.char, context);\n }\n}\n\n/**\n * Prefix command base class\n * For multi-key command sequences (g, z, Ctrl-w, [, ])\n */\nexport abstract class PrefixCommand extends Command {\n public isPrefix = true;\n abstract subcommands: Map<string, Command>;\n\n execute(state: State, context: CommandContext): State {\n throw new Error('Prefix commands should not be executed directly');\n }\n}\n\n/**\n * Count-only command base class\n * For commands that accept counts but not motions/text objects (scroll, screen position)\n */\nexport abstract class CountOnlyCommand extends Command {\n public acceptsPrecedingCount = true;\n public acceptsMotion = false;\n public acceptsTextObject = false;\n}","import {CharacterCaptureCommand} from \"../core/command\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCount, deleteRangeWithRegister} from \"../utils/state-utils\";\nimport {Mode} from \"../types/Modes\";\n\n/**\n * Basic editing commands\n */\n\n// Replace character\nexport class ReplaceChar extends CharacterCaptureCommand {\n key = 'r';\n public acceptsPrecedingCount = true;\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n const count = getCount(context);\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n // Normalize special keys to their actual characters\n if (char === 'Space') char = ' ';\n if (char === 'Enter') char = '\\n';\n\n // Handle newline replacement (r<CR> breaks the line)\n if (char === '\\n') {\n const before = currentLine.slice(0, state.cursor.column);\n const after = currentLine.slice(state.cursor.column + 1);\n lines[state.cursor.line] = before;\n lines.splice(state.cursor.line + 1, 0, after);\n\n const newContent = lines.join('\\n');\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: new Cursor(state.cursor.line, Math.max(0, before.length - 1))\n };\n }\n\n // Replace count characters starting from cursor\n const endColumn = Math.min(state.cursor.column + count, currentLine.length);\n const replacementCount = endColumn - state.cursor.column;\n\n if (replacementCount > 0) {\n const replacement = char.repeat(replacementCount);\n const newLine =\n currentLine.slice(0, state.cursor.column) +\n replacement +\n currentLine.slice(endColumn);\n\n lines[state.cursor.line] = newLine;\n const newContent = lines.join('\\n');\n\n // Cursor should end on the last replaced character\n const newCursor = new Cursor(state.cursor.line, state.cursor.column + replacementCount - 1);\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: newCursor\n };\n }\n\n return state;\n }\n}\n\n// Delete character under cursor\nexport class DeleteChar extends Command {\n key = 'x';\n public acceptsPrecedingCount = true;\n public acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // If selection exists, delete selection (same as d in visual mode)\n if (state.selection) {\n return deleteRangeWithRegister(state, state.selection, context, false);\n }\n\n // Get count (defaults to 1)\n const count = getCount(context);\n\n // Delete count characters starting from cursor position\n const startCursor = state.cursor;\n const endColumn = state.cursor.column + count;\n const endCursor = new Cursor(state.cursor.line, endColumn);\n\n return deleteRangeWithRegister(state, {start: startCursor, end: endCursor}, context, false);\n }\n}\n\n// Delete character before cursor\nexport class DeleteCharBackward extends Command {\n key = 'X';\n public acceptsPrecedingCount = true;\n public acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // Get count (defaults to 1)\n const count = getCount(context);\n\n // Delete count characters before cursor\n const startColumn = Math.max(0, state.cursor.column - count);\n const startCursor = new Cursor(state.cursor.line, startColumn);\n const endCursor = state.cursor;\n\n return deleteRangeWithRegister(state, {start: startCursor, end: endCursor}, context, false);\n }\n}\n\n// Substitute character(s) - delete and enter insert mode\nexport class Substitute extends Command {\n key = 's';\n public acceptsPrecedingCount = true;\n public acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // Get count (defaults to 1)\n const count = getCount(context);\n\n // Delete count characters starting from cursor position\n const startCursor = state.cursor;\n const endColumn = state.cursor.column + count;\n const endCursor = new Cursor(state.cursor.line, endColumn);\n\n // Delete the range and enter insert mode\n const newState = deleteRangeWithRegister(state, {start: startCursor, end: endCursor}, context, false);\n return {\n ...newState,\n mode: Mode.INSERT\n };\n }\n}\n\n// Substitute line - delete entire line content and enter insert mode\nexport class SubstituteLine extends Command {\n key = 'S';\n public acceptsPrecedingCount = true;\n public acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n // Get the indentation of the current line\n const indentMatch = currentLine.match(/^(\\s*)/);\n const indent = indentMatch?.[1] ?? '';\n\n // Delete the line content but keep the line (with indentation)\n lines[state.cursor.line] = indent;\n const newContent = lines.join('\\n');\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: new Cursor(state.cursor.line, indent.length),\n mode: Mode.INSERT\n };\n }\n}\n\n// Join lines\nexport class JoinLines extends Command {\n key = 'J';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = state.cursor.line;\n\n // If on last line, do nothing\n if (currentLine >= lines.length - 1) {\n return state;\n }\n\n // Get count (default joins current with next = 2 lines)\n // In Vim: J/1J joins 2 lines, 2J joins 3 lines, 3J joins 4 lines\n // Count represents number of additional lines to join\n const count = context.count ?? 1;\n const linesToJoin = count + 1; // Total lines = current + count additional\n\n // Can't join more lines than available\n const actualLinesToJoin = Math.min(linesToJoin, lines.length - currentLine);\n\n if (actualLinesToJoin <= 1) {\n return state;\n }\n\n // Join the lines\n let joinedLine = lines[currentLine] ?? '';\n\n // Remove trailing whitespace from first line\n joinedLine = joinedLine.replace(/\\s+$/, '');\n\n const joinPosition = joinedLine.length;\n\n for (let i = 1; i < actualLinesToJoin; i++) {\n const nextLine = lines[currentLine + i] ?? '';\n // Remove leading whitespace from next line\n const trimmedNextLine = nextLine.replace(/^\\s+/, '');\n\n // Add space if both lines have content\n if (joinedLine.length > 0 && trimmedNextLine.length > 0) {\n joinedLine += ' ';\n } else if (nextLine.trim().length === 0) {\n // If next line is empty, just add a space\n joinedLine += ' ';\n }\n\n joinedLine += trimmedNextLine;\n }\n\n // Replace the joined lines with the single joined line\n const newLines = [\n ...lines.slice(0, currentLine),\n joinedLine,\n ...lines.slice(currentLine + actualLinesToJoin)\n ];\n\n const newContent = newLines.join('\\n');\n const newCursor = new Cursor(currentLine, Math.min(joinPosition, joinedLine.length - 1));\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: newCursor\n };\n }\n}\n\n// Join lines without space (gJ)\nexport class JoinLinesNoSpace extends Command {\n key = 'gJ';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = state.cursor.line;\n\n // If on last line, do nothing\n if (currentLine >= lines.length - 1) {\n return state;\n }\n\n // Get count (default is 2, which means join current line with next line)\n const count = context.count ?? 1;\n const linesToJoin = count + 1;\n\n // Can't join more lines than available\n const actualLinesToJoin = Math.min(linesToJoin, lines.length - currentLine);\n\n if (actualLinesToJoin <= 1) {\n return state;\n }\n\n // Join the lines without adding space\n let joinedLine = lines[currentLine] ?? '';\n const joinPosition = joinedLine.length;\n\n for (let i = 1; i < actualLinesToJoin; i++) {\n const nextLine = lines[currentLine + i] ?? '';\n joinedLine += nextLine;\n }\n\n // Replace the joined lines with the single joined line\n const newLines = [\n ...lines.slice(0, currentLine),\n joinedLine,\n ...lines.slice(currentLine + actualLinesToJoin)\n ];\n\n const newContent = newLines.join('\\n');\n const newCursor = new Cursor(currentLine, Math.min(joinPosition, Math.max(0, joinedLine.length - 1)));\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: newCursor\n };\n }\n}\n\n// Undo\nexport class Undo extends Command {\n key = 'u';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n if (!state.undoTree) {\n return state;\n }\n\n const count = context.count ?? 1;\n let newState: State | null = state;\n\n // Perform undo count times\n for (let i = 0; i < count; i++) {\n const undone = state.undoTree.undo();\n if (undone) {\n newState = undone;\n } else {\n break; // Can't undo anymore\n }\n }\n\n return newState || state;\n }\n}\n\n// Redo\nexport class Redo extends Command {\n key = '<C-r>';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n if (!state.undoTree) {\n return state;\n }\n\n const count = context.count ?? 1;\n let newState: State | null = state;\n\n // Perform redo count times\n for (let i = 0; i < count; i++) {\n const redone = state.undoTree.redo();\n if (redone) {\n newState = redone;\n } else {\n break; // Can't redo anymore\n }\n }\n\n return newState || state;\n }\n}","import {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Number increment and decrement operations\n */\n\n/**\n * Find a number at or after the cursor position on the current line\n * Returns {start, end, value} or null if no number found\n */\nfunction findNumber(line: string, startCol: number): { start: number; end: number; value: number } | null {\n // Look for number at or after cursor position\n // Match optional minus sign, then digits\n const regex = /-?\\d+/g;\n regex.lastIndex = 0;\n\n let match;\n while ((match = regex.exec(line)) !== null) {\n const matchStart = match.index;\n const matchEnd = match.index + match[0].length;\n\n // If the match contains or is after the cursor\n if (matchEnd > startCol) {\n return {\n start: matchStart,\n end: matchEnd,\n value: parseInt(match[0], 10)\n };\n }\n }\n\n return null;\n}\n\n/**\n * Increment number under cursor (Ctrl-a)\n */\nexport class IncrementNumber extends Command {\n key = '<C-a>';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n const numberInfo = findNumber(currentLine, state.cursor.column);\n\n if (!numberInfo) {\n // No number found, do nothing\n return state;\n }\n\n const count = context.count ?? 1;\n const newValue = numberInfo.value + count;\n\n // Replace the number in the line\n const newLine =\n currentLine.slice(0, numberInfo.start) +\n newValue.toString() +\n currentLine.slice(numberInfo.end);\n\n lines[state.cursor.line] = newLine;\n const newContent = lines.join('\\n');\n\n // Position cursor at the start of the number\n const newCursor = new Cursor(state.cursor.line, numberInfo.start);\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: newCursor\n };\n }\n}\n\n/**\n * Decrement number under cursor (Ctrl-x)\n */\nexport class DecrementNumber extends Command {\n key = '<C-x>';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n const numberInfo = findNumber(currentLine, state.cursor.column);\n\n if (!numberInfo) {\n // No number found, do nothing\n return state;\n }\n\n const count = context.count ?? 1;\n const newValue = numberInfo.value - count;\n\n // Replace the number in the line\n const newLine =\n currentLine.slice(0, numberInfo.start) +\n newValue.toString() +\n currentLine.slice(numberInfo.end);\n\n lines[state.cursor.line] = newLine;\n const newContent = lines.join('\\n');\n\n // Position cursor at the start of the number\n const newCursor = new Cursor(state.cursor.line, numberInfo.start);\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: newCursor\n };\n }\n}\n","import {Command, type CommandContext} from \"../types/Command\";\nimport {CharacterCaptureCommand} from \"../core/command\";\nimport type {State} from \"../core/state\";\n\n/**\n * Macro commands\n */\n\nexport class RecordMacro extends CharacterCaptureCommand {\n key = 'q';\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n // If currently recording, stop recording\n if (state.recordingRegister) {\n return {\n ...state,\n recordingRegister: null\n };\n }\n\n // Start recording to the specified register\n // Initialize the register with an empty string\n context.registerManager?.set(char, '', false);\n\n return {\n ...state,\n recordingRegister: char\n };\n }\n}\n\nexport class PlayMacro extends CharacterCaptureCommand {\n key = '@';\n public acceptsPrecedingCount = true;\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n const register = context.registerManager?.get(char);\n\n if (!register) {\n return state;\n }\n\n // Store this as the last played macro\n return {\n ...state,\n lastMacroRegister: char\n };\n }\n}\n\nexport class RepeatMacro extends Command {\n key = '@@';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n if (!state.lastMacroRegister) {\n return state;\n }\n\n const register = context.registerManager?.get(state.lastMacroRegister);\n\n if (!register) {\n return state;\n }\n\n // The actual replay will be handled by Session\n return state;\n }\n}\n","import {Operator} from \"../core/operator\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {resolveOperatorRange} from \"../utils/state-utils\";\nimport {getTextInRange, normalizeRange} from \"../utils/range-utils\";\nimport {getLine} from \"../utils/buffer-operations\";\nimport {Mode} from \"../types/Modes\";\n\n/**\n * Yank (copy) operators\n */\n\nexport class y extends Operator {\n key = 'y';\n\n execute(state: State, context: CommandContext): State {\n // If in visual mode, use selection\n let range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Visual mode selections are inclusive on both ends,\n // but getTextInRange expects exclusive end, so increment end column\n if (state.selection && (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK)) {\n range = {\n start: range.start,\n end: {\n line: range.end.line,\n column: range.end.column + 1\n }\n };\n }\n\n // Normalize range to handle backward motions\n const normalizedRange = normalizeRange(range);\n\n // Determine if it's linewise based on visual mode\n const isLinewise = state.mode === Mode.VISUAL_LINE;\n\n // Extract text and store in register\n const text = getTextInRange(state.buffer, normalizedRange);\n context.registerManager?.storeYank(text, isLinewise);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...state,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n // Yank doesn't modify buffer, just return state as-is\n return state;\n }\n}\n\nexport class yy extends Command {\n key = 'yy';\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const count = context.count || 1;\n const startLine = state.cursor.line;\n const endLine = Math.min(startLine + count - 1, lines.length - 1);\n\n // Collect lines to yank\n const linesToYank = [];\n for (let i = startLine; i <= endLine; i++) {\n linesToYank.push(lines[i] ?? '');\n }\n\n const text = linesToYank.join('\\n');\n context.registerManager?.storeYank(text, true);\n return state;\n }\n}\n\nexport class Y extends Operator {\n key = 'Y';\n\n execute(state: State, context: CommandContext): State {\n // Yank from cursor to end of line (traditionally same as yy, but often mapped to y$)\n const line = getLine(state.buffer, state.cursor.line);\n const text = line.slice(state.cursor.column);\n context.registerManager?.storeYank(text, false);\n return state;\n }\n}","import {Operator} from \"../core/operator\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {Mode} from \"../types/Modes\";\nimport {resolveOperatorRange, deleteRangeWithRegister} from \"../utils/state-utils\";\nimport {e as eMotion} from \"../motions/word\";\nimport {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Change operators - delete and enter insert mode\n */\n\nexport class c extends Operator {\n key = 'c';\n\n execute(state: State, context: CommandContext): State {\n // Special case: In Vim, 'cw' behaves like 'ce' when cursor is on a word character\n // This preserves trailing whitespace, matching Vim behavior\n let modifiedContext = context;\n if (context.motion?.key === 'w') {\n // Check if cursor is on a word character (not whitespace)\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const charAtCursor = currentLine[state.cursor.column];\n const isOnWord = charAtCursor && /\\S/.test(charAtCursor);\n\n if (isOnWord) {\n // Use 'e' motion instead of 'w' for change operator\n modifiedContext = {...context, motion: new eMotion()};\n }\n }\n\n // If in visual mode, use selection\n let range = state.selection || resolveOperatorRange(state, modifiedContext);\n if (!range) return state;\n\n // Visual mode selections are inclusive on both ends,\n // but deleteRange expects exclusive end, so increment end column\n if (state.selection && (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK)) {\n range = {\n start: range.start,\n end: {\n line: range.end.line,\n column: range.end.column + 1\n }\n };\n }\n\n // Determine if it's linewise based on visual mode or motion\n const isLinewise = state.mode === Mode.VISUAL_LINE || (modifiedContext.motion?.linewise ?? false);\n\n // Delete the range and store in register\n const newState = deleteRangeWithRegister(state, range, modifiedContext, isLinewise);\n\n // Enter insert mode and clear selection\n return {\n ...newState,\n mode: Mode.INSERT,\n selection: null,\n visualAnchor: null\n };\n }\n}\n\nexport class cc extends Command {\n key = 'cc';\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLineNum = state.cursor.line;\n const count = context.count || 1;\n\n // Calculate how many lines to change (don't go past end of buffer)\n const linesToChange = Math.min(count, lines.length - currentLineNum);\n\n // Store deleted lines in register\n const deletedLines = lines.slice(currentLineNum, currentLineNum + linesToChange);\n context.registerManager?.storeDelete(deletedLines.join('\\n'), true);\n\n // Get the indentation of the first line being changed\n const firstLine = lines[currentLineNum] ?? '';\n const indentMatch = firstLine.match(/^(\\s*)/);\n const indent = indentMatch?.[1] ?? '';\n\n // Replace the lines with a single line containing only the indentation\n lines.splice(currentLineNum, linesToChange, indent);\n const newContent = lines.join('\\n');\n\n // Position cursor at end of indentation and enter insert mode\n return {\n ...state,\n buffer: new Buffer(newContent),\n cursor: new Cursor(currentLineNum, indent.length),\n mode: Mode.INSERT,\n selection: null\n };\n }\n}\n\nexport class C extends Command {\n key = 'C';\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const deletedText = currentLine.substring(state.cursor.column);\n\n // Store deleted text in register\n context.registerManager?.storeDelete(deletedText, false);\n\n // Delete from cursor to end of line\n lines[state.cursor.line] = currentLine.substring(0, state.cursor.column);\n const newContent = lines.join('\\n');\n\n // Enter insert mode at current cursor position\n return {\n ...state,\n buffer: new Buffer(newContent),\n mode: Mode.INSERT,\n selection: null\n };\n }\n}\n\nexport class s extends Command {\n key = 's';\n\n execute(state: State, context: CommandContext): State {\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n\n // Get count (default 1)\n const count = context.count || 1;\n\n // Calculate how many characters to delete\n const deleteCount = Math.min(count, currentLine.length - state.cursor.column);\n const deletedText = currentLine.substring(state.cursor.column, state.cursor.column + deleteCount);\n\n // Store deleted text in register\n context.registerManager?.storeDelete(deletedText, false);\n\n // Delete character(s) from cursor position\n lines[state.cursor.line] =\n currentLine.substring(0, state.cursor.column) +\n currentLine.substring(state.cursor.column + deleteCount);\n const newContent = lines.join('\\n');\n\n // Enter insert mode at current cursor position\n return {\n ...state,\n buffer: new Buffer(newContent),\n mode: Mode.INSERT,\n selection: null\n };\n }\n}\n\nexport class S extends Command {\n key = 'S';\n\n execute(state: State, context: CommandContext): State {\n // S is equivalent to cc - substitute entire line\n const lines = state.buffer.content.split('\\n');\n const currentLineNum = state.cursor.line;\n const count = context.count || 1;\n\n // Calculate how many lines to change (don't go past end of buffer)\n const linesToChange = Math.min(count, lines.length - currentLineNum);\n\n // Store deleted lines in register\n const deletedLines = lines.slice(currentLineNum, currentLineNum + linesToChange);\n context.registerManager?.storeDelete(deletedLines.join('\\n'), true);\n\n // Replace the lines with a single empty line\n lines.splice(currentLineNum, linesToChange, '');\n const newContent = lines.join('\\n');\n\n // Position cursor at start of now-empty line and enter insert mode\n return {\n ...state,\n buffer: new Buffer(newContent),\n cursor: new Cursor(currentLineNum, 0),\n mode: Mode.INSERT,\n selection: null\n };\n }\n}","import {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport type {Register} from \"../registers/register\";\nimport {Cursor} from \"../core/cursor\";\nimport {Buffer} from \"../core/buffer\";\n\n/**\n * Helper: Get the register to paste from (either specified or default)\n */\nfunction getRegisterForPaste(context: CommandContext): Register | null {\n const registerManager = context.registerManager;\n if (!registerManager) return null;\n\n const suppliedRegister = context.register;\n const register = suppliedRegister\n ? registerManager.get(suppliedRegister)\n : registerManager.getDefaultRegister();\n\n return register ?? null;\n}\n\n/**\n * Helper: Paste linewise content\n * @param state Current state\n * @param content Content to paste\n * @param position 'before' = above current line, 'after' = below current line\n */\nfunction pasteLinewise(state: State, content: string, position: 'before' | 'after'): State {\n const lines = state.buffer.content.split('\\n');\n const currentLineIndex = state.cursor.line;\n\n // Handle empty buffer special case\n if (state.buffer.content === '' || (lines.length === 1 && lines[0] === '')) {\n return {\n ...state,\n buffer: new Buffer(content),\n cursor: new Cursor(0, 0)\n };\n }\n\n let newLines: string[];\n let newCursorLine: number;\n\n if (position === 'after') {\n // Paste below current line\n const beforeLines = lines.slice(0, currentLineIndex + 1);\n const afterLines = lines.slice(currentLineIndex + 1);\n newLines = [...beforeLines, content, ...afterLines];\n newCursorLine = currentLineIndex + 1;\n } else {\n // Paste above current line\n const beforeLines = lines.slice(0, currentLineIndex);\n const afterLines = lines.slice(currentLineIndex);\n newLines = [...beforeLines, content, ...afterLines];\n newCursorLine = currentLineIndex;\n }\n\n return {\n ...state,\n buffer: new Buffer(newLines.join('\\n')),\n cursor: new Cursor(newCursorLine, 0)\n };\n}\n\n/**\n * Helper: Paste characterwise content\n * @param state Current state\n * @param content Content to paste\n * @param position 'before' = before cursor, 'after' = after cursor\n */\nfunction pasteCharacterwise(state: State, content: string, position: 'before' | 'after'): State {\n const lines = state.buffer.content.split('\\n');\n const currentLineIndex = state.cursor.line;\n const currentLine = lines[currentLineIndex] ?? '';\n\n let newLine: string;\n let newColumn: number;\n\n if (position === 'after') {\n // Paste after cursor\n const beforeCursor = currentLine.substring(0, state.cursor.column + 1);\n const afterCursor = currentLine.substring(state.cursor.column + 1);\n newLine = beforeCursor + content + afterCursor;\n newColumn = state.cursor.column + content.length;\n } else {\n // Paste before cursor\n const beforeCursor = currentLine.substring(0, state.cursor.column);\n const afterCursor = currentLine.substring(state.cursor.column);\n newLine = beforeCursor + content + afterCursor;\n newColumn = state.cursor.column + content.length - 1;\n }\n\n lines[currentLineIndex] = newLine;\n\n return {\n ...state,\n buffer: new Buffer(lines.join('\\n')),\n cursor: new Cursor(currentLineIndex, newColumn)\n };\n}\n\n/**\n * Paste operators\n */\n\nexport class p extends Command {\n key = 'p';\n acceptsRegister = true;\n acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n // Inserts the contents of the register after the cursor position.\n // If the register contains linewise text, it is inserted below the current line.\n const register = getRegisterForPaste(context);\n if (!register) return state;\n\n const count = context.count || 1;\n let currentState = state;\n\n // Remember the first paste position for cursor placement\n let firstPasteState: State | null = null;\n\n for (let i = 0; i < count; i++) {\n currentState = register.linewise\n ? pasteLinewise(currentState, register.content, 'after')\n : pasteCharacterwise(currentState, register.content, 'after');\n\n // Save the state after first paste to get correct cursor position\n if (i === 0) {\n firstPasteState = currentState;\n }\n }\n\n // Vim puts cursor at the start of the first pasted block\n if (register.linewise && firstPasteState) {\n return {\n ...currentState,\n cursor: firstPasteState.cursor\n };\n }\n\n return currentState;\n }\n}\n\nexport class P extends Command {\n key = 'P';\n acceptsRegister = true;\n acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n // Inserts the contents of the register before the cursor position.\n // If the register contains linewise text, it is inserted above the current line.\n const register = getRegisterForPaste(context);\n if (!register) return state;\n\n const count = context.count || 1;\n let currentState = state;\n\n // Remember the first paste position for cursor placement\n let firstPasteState: State | null = null;\n\n for (let i = 0; i < count; i++) {\n currentState = register.linewise\n ? pasteLinewise(currentState, register.content, 'before')\n : pasteCharacterwise(currentState, register.content, 'before');\n\n // Save the state after first paste to get correct cursor position\n if (i === 0) {\n firstPasteState = currentState;\n }\n }\n\n // Vim puts cursor at the start of the first pasted block\n if (register.linewise && firstPasteState) {\n return {\n ...currentState,\n cursor: firstPasteState.cursor\n };\n }\n\n return currentState;\n }\n}\n\nexport class PutBefore extends Command {\n key = ']p';\n acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // Paste before and adjust indent\n const register = getRegisterForPaste(context);\n if (!register) return state;\n\n const indentManager = context.indentationManager;\n let content = register.content;\n\n // Adjust indent if we have an indentation manager and it's linewise\n if (indentManager && register.linewise) {\n // Get the target indent from the current line\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const targetIndent = indentManager.getLineIndent(currentLine);\n content = indentManager.adjustIndent(content, targetIndent);\n }\n\n return register.linewise\n ? pasteLinewise(state, content, 'before')\n : pasteCharacterwise(state, content, 'before');\n }\n}\n\nexport class PutAfter extends Command {\n key = ']P';\n acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // Paste after and adjust indent\n const register = getRegisterForPaste(context);\n if (!register) return state;\n\n const indentManager = context.indentationManager;\n let content = register.content;\n\n // Adjust indent if we have an indentation manager and it's linewise\n if (indentManager && register.linewise) {\n // Get the target indent from the current line\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const targetIndent = indentManager.getLineIndent(currentLine);\n content = indentManager.adjustIndent(content, targetIndent);\n }\n\n return register.linewise\n ? pasteLinewise(state, content, 'after')\n : pasteCharacterwise(state, content, 'after');\n }\n}\n\nexport class PutBeforeNoIndent extends Command {\n key = '[p';\n acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // Paste before without adjusting indent (same as P)\n const register = getRegisterForPaste(context);\n if (!register) return state;\n\n return register.linewise\n ? pasteLinewise(state, register.content, 'before')\n : pasteCharacterwise(state, register.content, 'before');\n }\n}\n\nexport class PutAfterNoIndent extends Command {\n key = '[P';\n acceptsRegister = true;\n\n execute(state: State, context: CommandContext): State {\n // Paste after without adjusting indent (same as p)\n const register = getRegisterForPaste(context);\n if (!register) return state;\n\n return register.linewise\n ? pasteLinewise(state, register.content, 'after')\n : pasteCharacterwise(state, register.content, 'after');\n }\n}","import {CharacterCaptureMotion} from \"../core/command\";\nimport {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {Cursor} from \"../core/cursor\";\nimport {withCursorHorizontal} from \"../utils/buffer-operations\";\nimport {getLine} from \"../utils/buffer-operations\";\n\n/**\n * Character find motions\n */\n\nexport class f extends CharacterCaptureMotion {\n key = 'f';\n inclusive = true; // f is inclusive when used with operators\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n const line = getLine(state.buffer, state.cursor.line);\n const count = context.count || 1;\n let column = state.cursor.column;\n\n // Repeat the find motion 'count' times\n for (let i = 0; i < count; i++) {\n column++; // Move to next position for search\n let found = false;\n\n // Search forward for char\n while (column < line.length) {\n if (line[column] === char) {\n found = true;\n break;\n }\n column++;\n }\n\n // If not found in this iteration, stay at original position\n if (!found) {\n return state;\n }\n }\n\n return withCursorHorizontal(state, new Cursor(state.cursor.line, column));\n }\n}\n\nexport class F extends CharacterCaptureMotion {\n key = 'F';\n inclusive = true; // F is inclusive when used with operators\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n const line = getLine(state.buffer, state.cursor.line);\n const count = context.count || 1;\n let column = state.cursor.column;\n\n // Repeat the find motion 'count' times\n for (let i = 0; i < count; i++) {\n column--; // Move to previous position for search\n let found = false;\n\n // Search backward for char\n while (column >= 0) {\n if (line[column] === char) {\n found = true;\n break;\n }\n column--;\n }\n\n // If not found in this iteration, stay at original position\n if (!found) {\n return state;\n }\n }\n\n return withCursorHorizontal(state, new Cursor(state.cursor.line, column));\n }\n}\n\nexport class t extends CharacterCaptureMotion {\n key = 't';\n inclusive = true; // t is inclusive when used with operators, but stops one character before the target\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n const line = getLine(state.buffer, state.cursor.line);\n const count = context.count || 1;\n let column = state.cursor.column;\n\n // Repeat the find motion 'count' times\n for (let i = 0; i < count; i++) {\n column++; // Move to next position for search\n let found = false;\n\n // Search forward for char\n while (column < line.length) {\n if (line[column] === char) {\n found = true;\n break;\n }\n column++;\n }\n\n // If not found in this iteration, stay at original position\n if (!found) {\n return state;\n }\n }\n\n // Stop one character BEFORE the target\n return withCursorHorizontal(state, new Cursor(state.cursor.line, column - 1));\n }\n}\n\nexport class T extends CharacterCaptureMotion {\n key = 'T';\n\n executeWithChar(state: State, char: string, context: CommandContext): State {\n const line = getLine(state.buffer, state.cursor.line);\n const count = context.count || 1;\n let column = state.cursor.column;\n\n // Repeat the find motion 'count' times\n for (let i = 0; i < count; i++) {\n column--; // Move to previous position for search\n let found = false;\n\n // Search backward for char\n while (column >= 0) {\n if (line[column] === char) {\n found = true;\n break;\n }\n column--;\n }\n\n // If not found in this iteration, stay at original position\n if (!found) {\n return state;\n }\n }\n\n // Stop one character AFTER the target\n return withCursorHorizontal(state, new Cursor(state.cursor.line, column + 1));\n }\n}\n\nexport class Semicolon extends Motion {\n key = ';';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Repeat last f/F/t/T motion forward\n return state;\n }\n}\n\nexport class Comma extends Motion {\n key = ',';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Repeat last f/F/t/T motion backward\n return state;\n }\n}\n","import {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCount, lineCount} from \"../utils/state-utils\";\nimport {withCursorVertical} from \"../utils/buffer-operations\";\nimport {findFirstNonBlank} from \"../utils/line-navigation\";\n\n/**\n * Screen position motions\n * These accept counts but not motions (count = lines from top/bottom)\n */\n\nexport class H extends Motion {\n key = 'H';\n public inclusive = false;\n\n execute(state: State, context: CommandContext): State {\n // H moves to top of screen (or count lines from top)\n const count = getCount(context);\n // With count, move to (count - 1)th line (1-indexed to 0-indexed)\n // Without count, move to line 0\n const targetLine = count > 1 ? count - 1 : 0;\n\n // Clamp to valid line range\n const maxLine = lineCount(state) - 1;\n const line = Math.min(targetLine, Math.max(0, maxLine));\n\n // Move to first non-blank character of the line\n const newCursor = findFirstNonBlank(state.buffer, new Cursor(line, 0));\n\n return withCursorVertical(state, newCursor, newCursor.column);\n }\n}\n\nexport class M extends Motion {\n key = 'M';\n public inclusive = false;\n\n execute(state: State, _context: CommandContext): State {\n // M moves to middle of screen/buffer\n const totalLines = lineCount(state);\n const middleLine = Math.floor(totalLines / 2);\n\n // Move to first non-blank character of the middle line\n const newCursor = findFirstNonBlank(state.buffer, new Cursor(middleLine, 0));\n\n return withCursorVertical(state, newCursor, newCursor.column);\n }\n}\n\nexport class L extends Motion {\n key = 'L';\n public inclusive = false;\n\n execute(state: State, context: CommandContext): State {\n // L moves to bottom of screen (or count lines from bottom)\n const count = getCount(context);\n const maxLine = lineCount(state) - 1;\n\n // With count, move to (maxLine - count + 1)th line\n // Without count, move to last line\n const targetLine = count > 1 ? maxLine - count + 1 : maxLine;\n\n // Clamp to valid line range\n const line = Math.min(Math.max(0, targetLine), maxLine);\n\n // Move to first non-blank character of the line\n const newCursor = findFirstNonBlank(state.buffer, new Cursor(line, 0));\n\n return withCursorVertical(state, newCursor, newCursor.column);\n }\n}\n","import {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {findPrevWordEnd, findPrevWORDEnd} from \"../utils/text-navigation\";\nimport {repeatCursorMotion, getCount} from \"../utils/state-utils\";\nimport {withCursorHorizontal, getLine} from \"../utils/buffer-operations\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Extended basic motions\n */\n\nexport class ge extends Motion {\n key = 'ge';\n inclusive = true; // ge is inclusive like e\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findPrevWordEnd);\n }\n}\n\nexport class gE extends Motion {\n key = 'gE';\n inclusive = true; // gE is inclusive like E\n\n execute(state: State, context: CommandContext): State {\n return repeatCursorMotion(state, context, findPrevWORDEnd);\n }\n}\n\nexport class LastNonBlank extends Motion {\n key = 'g_';\n inclusive = true; // g_ is inclusive\n\n execute(state: State, context: CommandContext): State {\n const line = getLine(state.buffer, state.cursor.line);\n\n // Find the last non-whitespace character\n let col = line.length - 1;\n while (col >= 0 && /\\s/.test(line[col] ?? '')) {\n col--;\n }\n\n // Clamp to at least column 0\n col = Math.max(0, col);\n\n return withCursorHorizontal(state, new Cursor(state.cursor.line, col));\n }\n}\n\nexport class MiddleOfScreenLine extends Motion {\n key = 'gm';\n\n execute(state: State): State {\n // Move to middle of screen line (visible portion)\n // For now, we'll treat this as middle of the actual line since we don't have viewport info\n const line = getLine(state.buffer, state.cursor.line);\n const middleCol = Math.floor(line.length / 2);\n\n return withCursorHorizontal(state, new Cursor(state.cursor.line, Math.max(0, middleCol)));\n }\n}\n\nexport class MiddleOfLine extends Motion {\n key = 'gM';\n\n execute(state: State): State {\n // Move to middle of line (actual line, not screen line)\n const line = getLine(state.buffer, state.cursor.line);\n const middleCol = Math.floor(line.length / 2);\n\n return withCursorHorizontal(state, new Cursor(state.cursor.line, Math.max(0, middleCol)));\n }\n}\n\nexport class Column extends Motion {\n key = '|';\n\n execute(state: State, context: CommandContext): State {\n // Move to column N (1-indexed from count)\n const count = getCount(context);\n const line = getLine(state.buffer, state.cursor.line);\n\n // Count is 1-indexed, convert to 0-indexed column\n const targetCol = count - 1;\n\n // Clamp to valid range [0, line.length - 1]\n const col = Math.max(0, Math.min(targetCol, Math.max(0, line.length - 1)));\n\n return withCursorHorizontal(state, new Cursor(state.cursor.line, col));\n }\n}\n\nexport class MatchPercent extends Motion {\n key = '%';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n // If count is provided, jump to that percentage of the file\n if (context.count && context.count > 0 && context.count <= 100) {\n const lines = state.buffer.content.split('\\n');\n const targetLine = Math.floor((lines.length - 1) * context.count / 100);\n const line = lines[targetLine];\n if (line) {\n // Move to first non-blank character on that line\n let col = 0;\n while (col < line.length && /\\s/.test(line[col] ?? '')) {\n col++;\n }\n return withCursorHorizontal(state, new Cursor(targetLine, col));\n }\n }\n\n const lines = state.buffer.content.split('\\n');\n const {line, column} = state.cursor;\n\n if (line < 0 || line >= lines.length) {\n return state;\n }\n\n const currentLine = lines[line];\n if (!currentLine) {\n return state;\n }\n\n // Define bracket pairs\n const openBrackets = ['(', '[', '{', '<'];\n const closeBrackets = [')', ']', '}', '>'];\n const bracketPairs: { [key: string]: string } = {\n '(': ')', ')': '(',\n '[': ']', ']': '[',\n '{': '}', '}': '{',\n '<': '>', '>': '<'\n };\n\n let char = column < currentLine.length ? currentLine[column] : null;\n let startCol = column;\n\n // If not on a bracket, find the next bracket on the current line\n if (!char || !bracketPairs[char]) {\n let foundBracket = false;\n for (let col = column; col < currentLine.length; col++) {\n const c = currentLine[col];\n if (c && bracketPairs[c]) {\n char = c;\n startCol = col;\n foundBracket = true;\n break;\n }\n }\n if (!foundBracket) {\n return state;\n }\n }\n\n // Check if current character is a bracket\n const matchingChar = bracketPairs[char!];\n if (!matchingChar) {\n return state;\n }\n\n const isOpenBracket = openBrackets.includes(char!);\n\n // Search direction: forward for opening brackets, backward for closing brackets\n if (isOpenBracket) {\n // Search forward for matching closing bracket\n let depth = 1;\n let searchLine = line;\n let searchCol = startCol + 1;\n\n while (searchLine < lines.length) {\n const searchLineContent = lines[searchLine];\n if (!searchLineContent) break;\n\n while (searchCol < searchLineContent.length) {\n const c = searchLineContent[searchCol];\n\n if (c === char!) {\n depth++;\n } else if (c === matchingChar) {\n depth--;\n if (depth === 0) {\n // Found match\n return {\n ...state,\n cursor: {line: searchLine, column: searchCol}\n };\n }\n }\n searchCol++;\n }\n\n // Move to next line\n searchLine++;\n searchCol = 0;\n }\n } else {\n // Search backward for matching opening bracket\n let depth = 1;\n let searchLine = line;\n let searchCol = column - 1;\n\n while (searchLine >= 0) {\n const searchLineContent = lines[searchLine];\n if (!searchLineContent) break;\n\n while (searchCol >= 0) {\n const c = searchLineContent[searchCol];\n\n if (c === char!) {\n depth++;\n } else if (c === matchingChar) {\n depth--;\n if (depth === 0) {\n // Found match\n return {\n ...state,\n cursor: {line: searchLine, column: searchCol}\n };\n }\n }\n searchCol--;\n }\n\n // Move to previous line\n searchLine--;\n if (searchLine >= 0) {\n const prevLine = lines[searchLine];\n if (prevLine) {\n searchCol = prevLine.length - 1;\n }\n }\n }\n }\n\n // No match found\n return state;\n }\n}\n","import {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {getCount} from \"../utils/state-utils\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Paragraph and sentence motions\n */\n\nexport class OpenBrace extends Motion {\n key = '{';\n\n execute(state: State, context: CommandContext): State {\n // Move to blank line before previous paragraph (or buffer start)\n const lines = state.buffer.content.split('\\n');\n let currentLine = state.cursor.line;\n let count = getCount(context);\n\n while (count > 0 && currentLine > 0) {\n // If starting on a blank line, skip through blank lines first\n if (lines[currentLine]?.trim() === '') {\n while (currentLine > 0 && lines[currentLine]?.trim() === '') {\n currentLine--;\n }\n // Now at content line or line 0\n if (currentLine === 0) {\n break;\n }\n }\n\n // Skip backwards through current paragraph (non-blank lines)\n while (currentLine > 0 && lines[currentLine]?.trim() !== '') {\n currentLine--;\n }\n\n // Now at a blank line (or line 0)\n // This is our target\n count--;\n }\n\n return {\n ...state,\n cursor: new Cursor(currentLine, 0)\n };\n }\n}\n\nexport class CloseBrace extends Motion {\n key = '}';\n\n execute(state: State, context: CommandContext): State {\n // Move to blank line after current paragraph (or buffer end)\n const lines = state.buffer.content.split('\\n');\n let currentLine = state.cursor.line;\n const lastLineIndex = lines.length - 1;\n let count = getCount(context);\n\n while (count > 0 && currentLine < lastLineIndex) {\n // If starting on a blank line, skip through blank lines first\n if (lines[currentLine]?.trim() === '') {\n while (currentLine < lastLineIndex && lines[currentLine]?.trim() === '') {\n currentLine++;\n }\n // Now at content line or last line\n if (currentLine === lastLineIndex) {\n break;\n }\n }\n\n // Skip forward through current paragraph (non-blank lines)\n while (currentLine < lastLineIndex && lines[currentLine]?.trim() !== '') {\n currentLine++;\n }\n\n // Now at a blank line (or last line)\n // This is our target\n count--;\n }\n\n return {\n ...state,\n cursor: new Cursor(currentLine, 0)\n };\n }\n}\n\nexport class OpenParen extends Motion {\n key = '(';\n\n execute(state: State, context: CommandContext): State {\n // Move to beginning of previous sentence\n const content = state.buffer.content;\n let count = getCount(context);\n const lines = content.split('\\n');\n\n // Convert cursor to absolute position\n let pos = 0;\n for (let i = 0; i < state.cursor.line; i++) {\n pos += (lines[i]?.length ?? 0) + 1; // +1 for newline\n }\n pos += state.cursor.column;\n\n while (count > 0 && pos > 0) {\n // Move backward to find sentence boundary\n // Skip whitespace\n while (pos > 0 && /\\s/.test(content[pos - 1] ?? '')) {\n pos--;\n }\n\n // Find sentence end marker (., !, ?)\n let foundSentence = false;\n while (pos > 0) {\n pos--;\n const char = content[pos];\n if (char === '.' || char === '!' || char === '?') {\n // Skip past the punctuation and any following whitespace\n pos++;\n while (pos < content.length && /\\s/.test(content[pos] ?? '')) {\n pos++;\n }\n foundSentence = true;\n break;\n }\n }\n\n if (!foundSentence && pos === 0) {\n // Reached the beginning of the buffer\n break;\n }\n\n count--;\n }\n\n // Convert absolute position back to line/column\n let line = 0;\n let col = 0;\n let currentPos = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const lineLength = (lines[i]?.length ?? 0) + 1; // +1 for newline\n if (currentPos + lineLength > pos) {\n line = i;\n col = pos - currentPos;\n break;\n }\n currentPos += lineLength;\n }\n\n // Clamp to line length (without newline)\n const lineContent = lines[line] ?? '';\n col = Math.min(col, Math.max(0, lineContent.length - 1));\n\n return {\n ...state,\n cursor: new Cursor(line, Math.max(0, col))\n };\n }\n}\n\nexport class CloseParen extends Motion {\n key = ')';\n\n execute(state: State, context: CommandContext): State {\n // Move to beginning of next sentence\n const content = state.buffer.content;\n let count = getCount(context);\n const lines = content.split('\\n');\n\n // Convert cursor to absolute position\n let pos = 0;\n for (let i = 0; i < state.cursor.line; i++) {\n pos += (lines[i]?.length ?? 0) + 1; // +1 for newline\n }\n pos += state.cursor.column;\n\n while (count > 0 && pos < content.length) {\n // Find next sentence end marker (., !, ?)\n let foundSentence = false;\n while (pos < content.length) {\n const char = content[pos];\n if (char === '.' || char === '!' || char === '?') {\n // Skip past the punctuation and any following whitespace\n pos++;\n while (pos < content.length && /\\s/.test(content[pos] ?? '')) {\n pos++;\n }\n foundSentence = true;\n break;\n }\n pos++;\n }\n\n if (!foundSentence) {\n // Reached the end of the buffer\n break;\n }\n\n count--;\n }\n\n // Convert absolute position back to line/column\n let line = 0;\n let col = 0;\n let currentPos = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const lineLength = (lines[i]?.length ?? 0) + 1; // +1 for newline\n if (currentPos + lineLength > pos) {\n line = i;\n col = pos - currentPos;\n break;\n }\n currentPos += lineLength;\n }\n\n // Clamp to line length (without newline)\n const lineContent = lines[line] ?? '';\n col = Math.min(col, Math.max(0, lineContent.length - 1));\n if (line >= lines.length) {\n line = lines.length - 1;\n col = Math.max(0, (lines[line]?.length ?? 1) - 1);\n }\n\n return {\n ...state,\n cursor: new Cursor(line, Math.max(0, col))\n };\n }\n}\n\n/**\n * Section motions\n */\n\nexport class PrevSection extends Motion {\n key = '[[';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Move to previous section/function start\n return state;\n }\n}\n\nexport class NextSection extends Motion {\n key = ']]';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Move to next section/function start\n return state;\n }\n}\n\nexport class PrevSectionEnd extends Motion {\n key = '[]';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Move to end of previous section\n return state;\n }\n}\n\nexport class NextSectionEnd extends Motion {\n key = '][';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Move to end of next section\n return state;\n }\n}\n","import {Motion} from \"../core/motion\";\nimport type {State} from \"../core/state\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport {Cursor} from \"../core/cursor\";\nimport {Mode} from \"../types/Modes\";\nimport {withCursorHorizontal} from \"../utils/buffer-operations\";\n\n/**\n * Re-export character find motions from find.ts\n */\nexport {f, F, t, T, Semicolon, Comma} from \"./find\";\n\n/**\n * Helper function to get word under cursor\n * Returns the word and its boundaries\n */\nfunction getWordAtCursor(state: State): { word: string; start: number; end: number } {\n const lines = state.buffer.content.split('\\n');\n const line = lines[state.cursor.line];\n if (!line) return { word: '', start: 0, end: 0 };\n\n const col = state.cursor.column;\n\n // Find word boundaries\n let start = col;\n let end = col;\n\n // Move start backwards to word boundary\n while (start > 0 && /\\w/.test(line[start - 1] ?? '')) {\n start--;\n }\n\n // Move end forwards to word boundary\n while (end < line.length && /\\w/.test(line[end] ?? '')) {\n end++;\n }\n\n return { word: line.slice(start, end), start, end };\n}\n\n/**\n * Search for a pattern in the buffer\n */\nfunction searchInBuffer(\n state: State,\n pattern: string,\n isForward: boolean,\n wholeWord: boolean,\n count: number = 1,\n skipCurrentWord: { start: number; end: number } | null = null\n): Cursor | null {\n const lines = state.buffer.content.split('\\n');\n const startLine = state.cursor.line;\n const startCol = state.cursor.column;\n\n // Create regex\n let regexPattern = wholeWord ? `\\\\b${escapeRegex(pattern)}\\\\b` : escapeRegex(pattern);\n const regex = new RegExp(regexPattern, 'g');\n\n let matchesFound = 0;\n\n if (isForward) {\n // Search forward from current position\n // First, search rest of current line\n const currentLine = lines[startLine];\n if (currentLine) {\n regex.lastIndex = startCol + 1; // Start after current position\n let match;\n while ((match = regex.exec(currentLine)) !== null) {\n matchesFound++;\n if (matchesFound === count) {\n return new Cursor(startLine, match.index);\n }\n }\n }\n\n // Search subsequent lines\n for (let i = startLine + 1; i < lines.length; i++) {\n const line = lines[i] ?? '';\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n matchesFound++;\n if (matchesFound === count) {\n return new Cursor(i, match.index);\n }\n }\n }\n\n // Wrap to beginning\n for (let i = 0; i <= startLine; i++) {\n const line = lines[i] ?? '';\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n if (i === startLine && match.index >= startCol) {\n // Don't match current position again\n break;\n }\n matchesFound++;\n if (matchesFound === count) {\n return new Cursor(i, match.index);\n }\n }\n }\n } else {\n // Search backward - collect all matches in reverse order\n const allMatches: Array<{line: number; col: number}> = [];\n\n // First collect matches before current position (in document order)\n for (let i = 0; i <= startLine; i++) {\n const line = lines[i] ?? '';\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n // Skip if this is the current word we're on\n if (skipCurrentWord && i === startLine &&\n match.index >= skipCurrentWord.start && match.index < skipCurrentWord.end) {\n continue;\n }\n if (i < startLine || (i === startLine && match.index < startCol)) {\n allMatches.push({line: i, col: match.index});\n }\n }\n }\n\n // Then collect matches after current position for wrapping (in document order)\n for (let i = startLine; i < lines.length; i++) {\n const line = lines[i] ?? '';\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n // Skip if this is the current word we're on\n if (skipCurrentWord && i === startLine &&\n match.index >= skipCurrentWord.start && match.index < skipCurrentWord.end) {\n continue;\n }\n if (i > startLine || (i === startLine && match.index >= startCol)) {\n allMatches.push({line: i, col: match.index});\n }\n }\n }\n\n // For backward search, we want matches in reverse order\n // Starting from the match just before current position\n if (allMatches.length > 0) {\n // Find matches before current position\n const matchesBeforeCursor = allMatches.filter(m =>\n m.line < startLine || (m.line === startLine && m.col < startCol)\n );\n\n // If we have matches before cursor, search backward from there\n if (matchesBeforeCursor.length >= count) {\n // Get nth match from the end of matches before cursor\n const targetMatch = matchesBeforeCursor[matchesBeforeCursor.length - count];\n if (targetMatch) {\n return new Cursor(targetMatch.line, targetMatch.col);\n }\n } else if (allMatches.length >= count) {\n // Wrap around - need to go from end of buffer\n const remainingCount = count - matchesBeforeCursor.length;\n const targetMatch = allMatches[allMatches.length - remainingCount];\n if (targetMatch) {\n return new Cursor(targetMatch.line, targetMatch.col);\n }\n }\n }\n\n // If no matches found (all were skipped), search again without skipping\n // This handles the case where the word only appears once\n if (skipCurrentWord && allMatches.length === 0) {\n return searchInBuffer(state, pattern, isForward, wholeWord, count, null);\n }\n }\n\n return null;\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Search motions\n */\n\nexport class Star extends Motion {\n key = '*';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const wordInfo = getWordAtCursor(state);\n if (!wordInfo.word) return state;\n\n const count = context.count || 1;\n const newCursor = searchInBuffer(state, wordInfo.word, true, true, count);\n\n if (newCursor) {\n return {\n ...withCursorHorizontal(state, newCursor),\n lastSearch: { pattern: wordInfo.word, isForward: true }\n };\n }\n\n return {\n ...state,\n lastSearch: { pattern: wordInfo.word, isForward: true }\n };\n }\n}\n\nexport class Hash extends Motion {\n key = '#';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const wordInfo = getWordAtCursor(state);\n if (!wordInfo.word) return state;\n\n const count = context.count || 1;\n // Pass word boundaries to skip current word in backward search\n const newCursor = searchInBuffer(state, wordInfo.word, false, true, count, wordInfo);\n\n if (newCursor) {\n return {\n ...withCursorHorizontal(state, newCursor),\n lastSearch: { pattern: wordInfo.word, isForward: false }\n };\n }\n\n return {\n ...state,\n lastSearch: { pattern: wordInfo.word, isForward: false }\n };\n }\n}\n\nexport class gStar extends Motion {\n key = 'g*';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const wordInfo = getWordAtCursor(state);\n if (!wordInfo.word) return state;\n\n const count = context.count || 1;\n const newCursor = searchInBuffer(state, wordInfo.word, true, false, count);\n\n if (newCursor) {\n return {\n ...withCursorHorizontal(state, newCursor),\n lastSearch: { pattern: wordInfo.word, isForward: true }\n };\n }\n\n return {\n ...state,\n lastSearch: { pattern: wordInfo.word, isForward: true }\n };\n }\n}\n\nexport class gHash extends Motion {\n key = 'g#';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n const wordInfo = getWordAtCursor(state);\n if (!wordInfo.word) return state;\n\n const count = context.count || 1;\n // Pass word boundaries to skip current word in backward search\n const newCursor = searchInBuffer(state, wordInfo.word, false, false, count, wordInfo);\n\n if (newCursor) {\n return {\n ...withCursorHorizontal(state, newCursor),\n lastSearch: { pattern: wordInfo.word, isForward: false }\n };\n }\n\n return {\n ...state,\n lastSearch: { pattern: wordInfo.word, isForward: false }\n };\n }\n}\n\nexport class n extends Motion {\n key = 'n';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n if (!state.lastSearch) {\n return state;\n }\n\n const count = context.count || 1;\n const newCursor = searchInBuffer(\n state,\n state.lastSearch.pattern,\n state.lastSearch.isForward,\n false,\n count\n );\n\n if (newCursor) {\n return withCursorHorizontal(state, newCursor);\n }\n\n return state;\n }\n}\n\nexport class N extends Motion {\n key = 'N';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n if (!state.lastSearch) {\n return state;\n }\n\n const count = context.count || 1;\n const newCursor = searchInBuffer(\n state,\n state.lastSearch.pattern,\n !state.lastSearch.isForward, // Opposite direction\n false,\n count\n );\n\n if (newCursor) {\n return withCursorHorizontal(state, newCursor);\n }\n\n return state;\n }\n}\n\nexport class SearchForward extends Command {\n key = '/';\n\n execute(state: State, context: CommandContext): State {\n // Enter command mode for search\n return {\n ...state,\n mode: Mode.COMMAND,\n commandLine: '/'\n };\n }\n}\n\nexport class SearchBackward extends Command {\n key = '?';\n\n execute(state: State, context: CommandContext): State {\n // Enter command mode for search\n return {\n ...state,\n mode: Mode.COMMAND,\n commandLine: '?'\n };\n }\n}\n","import {CountOnlyCommand} from \"../core/command\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {Cursor} from \"../core/cursor\";\nimport {getCount, lineCount} from \"../utils/state-utils\";\nimport {withCursorVertical, withCursorAndViewport, withViewport, clampCursorNormalMode} from \"../utils/buffer-operations\";\n\n/**\n * Scrolling commands\n * These accept counts but not motions/text objects\n *\n * Scroll commands adjust both the viewport and cursor position.\n * Default page size is 24 lines, half-page is 12 lines.\n */\n\nconst PAGE_SIZE = 24;\nconst HALF_PAGE_SIZE = 12;\n\n/**\n * Keep cursor within viewport bounds\n */\nfunction ensureCursorInViewport(state: State, cursor: Cursor, topLine: number): Cursor {\n const bottomLine = topLine + state.viewport.height - 1;\n\n // If cursor is above viewport, move it to top\n if (cursor.line < topLine) {\n return new Cursor(topLine, cursor.column);\n }\n\n // If cursor is below viewport, move it to bottom\n if (cursor.line > bottomLine) {\n return new Cursor(bottomLine, cursor.column);\n }\n\n return cursor;\n}\n\nexport class ScrollHalfPageDown extends CountOnlyCommand {\n key = '<C-d>';\n\n execute(state: State, context: CommandContext): State {\n // Scroll viewport and cursor half page down\n const count = getCount(context);\n const scrollAmount = HALF_PAGE_SIZE * count;\n const maxLine = lineCount(state) - 1;\n\n const newTopLine = Math.min(state.viewport.topLine + scrollAmount, maxLine);\n const newCursorLine = Math.min(state.cursor.line + scrollAmount, maxLine);\n\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const newCursor = clampCursorNormalMode(state.buffer, new Cursor(newCursorLine, desiredCol));\n\n return withCursorAndViewport(state, newCursor, newTopLine, desiredCol);\n }\n}\n\nexport class ScrollHalfPageUp extends CountOnlyCommand {\n key = '<C-u>';\n\n execute(state: State, context: CommandContext): State {\n // Scroll viewport and cursor half page up\n const count = getCount(context);\n const scrollAmount = HALF_PAGE_SIZE * count;\n\n const newTopLine = Math.max(state.viewport.topLine - scrollAmount, 0);\n const newCursorLine = Math.max(state.cursor.line - scrollAmount, 0);\n\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const newCursor = clampCursorNormalMode(state.buffer, new Cursor(newCursorLine, desiredCol));\n\n return withCursorAndViewport(state, newCursor, newTopLine, desiredCol);\n }\n}\n\nexport class ScrollPageDown extends CountOnlyCommand {\n key = '<C-f>';\n\n execute(state: State, context: CommandContext): State {\n // Scroll viewport and cursor full page down\n const count = getCount(context);\n const scrollAmount = PAGE_SIZE * count;\n const maxLine = lineCount(state) - 1;\n\n const newTopLine = Math.min(state.viewport.topLine + scrollAmount, maxLine);\n const newCursorLine = Math.min(state.cursor.line + scrollAmount, maxLine);\n\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const newCursor = clampCursorNormalMode(state.buffer, new Cursor(newCursorLine, desiredCol));\n\n return withCursorAndViewport(state, newCursor, newTopLine, desiredCol);\n }\n}\n\nexport class ScrollPageUp extends CountOnlyCommand {\n key = '<C-b>';\n\n execute(state: State, context: CommandContext): State {\n // Scroll viewport and cursor full page up\n const count = getCount(context);\n const scrollAmount = PAGE_SIZE * count;\n\n const newTopLine = Math.max(state.viewport.topLine - scrollAmount, 0);\n const newCursorLine = Math.max(state.cursor.line - scrollAmount, 0);\n\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const newCursor = clampCursorNormalMode(state.buffer, new Cursor(newCursorLine, desiredCol));\n\n return withCursorAndViewport(state, newCursor, newTopLine, desiredCol);\n }\n}\n\nexport class ScrollCursorCenter extends CountOnlyCommand {\n key = 'zz';\n\n execute(state: State, _context: CommandContext): State {\n // Position cursor line at center of viewport\n const halfHeight = Math.floor(state.viewport.height / 2);\n const newTopLine = Math.max(0, state.cursor.line - halfHeight);\n\n return withViewport(state, newTopLine);\n }\n}\n\nexport class ScrollCursorTop extends CountOnlyCommand {\n key = 'zt';\n\n execute(state: State, _context: CommandContext): State {\n // Position cursor line at top of viewport\n return withViewport(state, state.cursor.line);\n }\n}\n\nexport class ScrollCursorBottom extends CountOnlyCommand {\n key = 'zb';\n\n execute(state: State, _context: CommandContext): State {\n // Position cursor line at bottom of viewport\n const newTopLine = Math.max(0, state.cursor.line - state.viewport.height + 1);\n\n return withViewport(state, newTopLine);\n }\n}\n\nexport class ScrollLineDown extends CountOnlyCommand {\n key = '<C-e>';\n\n execute(state: State, context: CommandContext): State {\n // Scroll viewport down (shows more of bottom of file)\n // If cursor is at top of viewport, don't scroll (to keep cursor visible)\n const count = getCount(context);\n\n // Don't scroll if cursor is at the top of viewport\n // This keeps the cursor from going off-screen\n if (state.cursor.line === state.viewport.topLine) {\n return state;\n }\n\n const maxLine = lineCount(state) - 1;\n const newTopLine = Math.min(state.viewport.topLine + count, maxLine);\n\n // Cursor stays at same line unless it goes above viewport\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const adjustedCursor = ensureCursorInViewport(state, state.cursor, newTopLine);\n const newCursor = clampCursorNormalMode(state.buffer, new Cursor(adjustedCursor.line, desiredCol));\n\n return withCursorAndViewport(state, newCursor, newTopLine, desiredCol);\n }\n}\n\nexport class ScrollLineUp extends CountOnlyCommand {\n key = '<C-y>';\n\n execute(state: State, context: CommandContext): State {\n // Scroll viewport up (shows more of top of file)\n // Cursor stays in place unless it would go off bottom of screen\n const count = getCount(context);\n const newTopLine = Math.max(state.viewport.topLine - count, 0);\n\n // If cursor would be below viewport, move it up to stay in viewport\n const desiredCol = state.desiredColumn ?? state.cursor.column;\n const adjustedCursor = ensureCursorInViewport(state, state.cursor, newTopLine);\n const newCursor = clampCursorNormalMode(state.buffer, new Cursor(adjustedCursor.line, desiredCol));\n\n return withCursorAndViewport(state, newCursor, newTopLine, desiredCol);\n }\n}\n","import {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {Mode} from \"../types/Modes\";\nimport {getLines} from \"../utils/buffer-operations\";\n\n/**\n * Visual mode commands\n */\n\nexport class VisualChar extends Command {\n key = 'v';\n\n execute(state: State, context: CommandContext): State {\n // If already in character-wise visual mode, toggle back to normal\n if (state.mode === Mode.VISUAL) {\n return {\n ...state,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null,\n lastVisualSelection: state.selection ? { range: state.selection, mode: state.mode } : state.lastVisualSelection\n };\n }\n\n // If in other visual modes, switch to character-wise\n if (state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...state,\n mode: Mode.VISUAL,\n // Keep the same anchor and selection\n };\n }\n\n // Enter character-wise visual mode\n // Selection starts at current cursor position\n return {\n ...state,\n mode: Mode.VISUAL,\n visualAnchor: state.cursor,\n selection: { start: state.cursor, end: state.cursor }\n };\n }\n}\n\nexport class VisualLine extends Command {\n key = 'V';\n\n execute(state: State, context: CommandContext): State {\n // If already in visual line mode, toggle back to normal\n if (state.mode === Mode.VISUAL_LINE) {\n return {\n ...state,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null,\n lastVisualSelection: state.selection ? { range: state.selection, mode: state.mode } : state.lastVisualSelection\n };\n }\n\n // If in other visual modes, switch to line mode\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK) {\n const lines = getLines(state.buffer);\n const lineStart = { line: state.cursor.line, column: 0 };\n const lineEnd = {\n line: state.cursor.line,\n column: Math.max(0, (lines[state.cursor.line]?.length ?? 1) - 1)\n };\n\n return {\n ...state,\n mode: Mode.VISUAL_LINE,\n visualAnchor: lineStart,\n selection: { start: lineStart, end: lineEnd }\n };\n }\n\n // Enter line-wise visual mode\n const lines = getLines(state.buffer);\n const lineStart = { line: state.cursor.line, column: 0 };\n const lineEnd = {\n line: state.cursor.line,\n column: Math.max(0, (lines[state.cursor.line]?.length ?? 1) - 1)\n };\n\n return {\n ...state,\n mode: Mode.VISUAL_LINE,\n visualAnchor: lineStart,\n selection: { start: lineStart, end: lineEnd }\n };\n }\n}\n\nexport class VisualBlock extends Command {\n key = '<C-v>';\n\n execute(state: State, context: CommandContext): State {\n // If already in visual block mode, toggle back to normal\n if (state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...state,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null,\n lastVisualSelection: state.selection ? { range: state.selection, mode: state.mode } : state.lastVisualSelection\n };\n }\n\n // If in other visual modes, switch to block mode\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE) {\n return {\n ...state,\n mode: Mode.VISUAL_BLOCK,\n visualAnchor: state.visualAnchor || state.cursor,\n selection: state.selection || { start: state.cursor, end: state.cursor }\n };\n }\n\n // Enter block-wise visual mode\n return {\n ...state,\n mode: Mode.VISUAL_BLOCK,\n visualAnchor: state.cursor,\n selection: { start: state.cursor, end: state.cursor }\n };\n }\n}\n\nexport class ReselectVisual extends Command {\n key = 'gv';\n\n execute(state: State, context: CommandContext): State {\n // Only works in normal mode\n if (state.mode !== Mode.NORMAL) {\n return state;\n }\n\n // Check if there's a previous visual selection\n if (!state.lastVisualSelection) {\n return state;\n }\n\n const { range, mode } = state.lastVisualSelection;\n\n // Restore the visual selection\n return {\n ...state,\n mode,\n cursor: range.end,\n visualAnchor: range.start,\n selection: range\n };\n }\n}\n\nexport class MoveToOtherEnd extends Command {\n key = 'o';\n\n execute(state: State, context: CommandContext): State {\n // Only works in visual modes\n if (state.mode !== Mode.VISUAL && state.mode !== Mode.VISUAL_LINE && state.mode !== Mode.VISUAL_BLOCK) {\n return state;\n }\n\n if (!state.visualAnchor || !state.selection) {\n return state;\n }\n\n // Swap cursor and anchor\n const newCursor = state.visualAnchor;\n const newAnchor = state.cursor;\n\n return {\n ...state,\n cursor: newCursor,\n visualAnchor: newAnchor,\n selection: { start: newAnchor, end: newCursor }\n };\n }\n}\n\nexport class MoveToOtherCorner extends Command {\n key = 'O';\n\n execute(state: State, context: CommandContext): State {\n // Only works in visual block mode\n if (state.mode !== Mode.VISUAL_BLOCK) {\n return state;\n }\n\n if (!state.visualAnchor || !state.selection) {\n return state;\n }\n\n // In block mode, O moves to the diagonal opposite corner\n // If anchor is (line1, col1) and cursor is (line2, col2),\n // swap the line but keep the column, creating a diagonal movement\n const newCursor = {\n line: state.visualAnchor.line,\n column: state.cursor.column\n };\n\n const newAnchor = {\n line: state.cursor.line,\n column: state.visualAnchor.column\n };\n\n return {\n ...state,\n cursor: newCursor,\n visualAnchor: newAnchor,\n selection: { start: newAnchor, end: newCursor }\n };\n }\n}\n\nexport class ExitVisual extends Command {\n key = '<Esc>';\n\n execute(state: State, context: CommandContext): State {\n // Only handle Escape in visual modes\n if (state.mode !== Mode.VISUAL && state.mode !== Mode.VISUAL_LINE && state.mode !== Mode.VISUAL_BLOCK) {\n return state;\n }\n\n // Save current selection for gv command\n const lastVisualSelection = state.selection ? {\n range: state.selection,\n mode: state.mode\n } : state.lastVisualSelection;\n\n // Exit visual mode\n return {\n ...state,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null,\n lastVisualSelection\n };\n }\n}\n","import {Operator} from \"../core/operator\";\nimport {Command} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {Mode} from \"../types/Modes\";\nimport {getTextInRange, normalizeRange, replaceRange} from \"../utils/range-utils\";\nimport {withBufferContent} from \"../utils/buffer-operations\";\nimport {resolveOperatorRange} from \"../utils/state-utils\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Case change operators\n */\n\n// Visual mode case commands (work directly on selection)\nexport class VisualToggleCase extends Command {\n key = '~';\n\n execute(state: State, context: CommandContext): State {\n if (!state.selection) return state;\n\n // Visual selections are inclusive, so increment end column\n const range = {\n start: state.selection.start,\n end: {\n line: state.selection.end.line,\n column: state.selection.end.column + 1\n }\n };\n const normalizedRange = normalizeRange(range);\n const text = getTextInRange(state.buffer, normalizedRange);\n const toggled = text.split('').map(ch => {\n if (ch === ch.toUpperCase()) return ch.toLowerCase();\n return ch.toUpperCase();\n }).join('');\n\n const newContent = replaceRange(state.buffer, normalizedRange, toggled);\n\n const newState = withBufferContent(state, newContent);\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n}\n\nexport class VisualUppercase extends Command {\n key = 'U';\n\n execute(state: State, context: CommandContext): State {\n if (!state.selection) return state;\n\n // Visual selections are inclusive, so increment end column\n const range = {\n start: state.selection.start,\n end: {\n line: state.selection.end.line,\n column: state.selection.end.column + 1\n }\n };\n const normalizedRange = normalizeRange(range);\n const text = getTextInRange(state.buffer, normalizedRange);\n const upper = text.toUpperCase();\n\n const newContent = replaceRange(state.buffer, normalizedRange, upper);\n\n const newState = withBufferContent(state, newContent);\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n}\n\nexport class VisualLowercase extends Command {\n key = 'u';\n\n execute(state: State, context: CommandContext): State {\n if (!state.selection) return state;\n\n // Visual selections are inclusive, so increment end column\n const range = {\n start: state.selection.start,\n end: {\n line: state.selection.end.line,\n column: state.selection.end.column + 1\n }\n };\n const normalizedRange = normalizeRange(range);\n const text = getTextInRange(state.buffer, normalizedRange);\n const lower = text.toLowerCase();\n\n const newContent = replaceRange(state.buffer, normalizedRange, lower);\n\n const newState = withBufferContent(state, newContent);\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n}\n\nexport class ToggleCase extends Command {\n key = '~';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n // Toggle case of character under cursor (and move cursor right)\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line];\n\n if (!currentLine || state.cursor.column >= currentLine.length) {\n return state;\n }\n\n const count = context.count ?? 1;\n const startCol = state.cursor.column;\n const endCol = Math.min(state.cursor.column + count, currentLine.length);\n\n // Toggle case of characters\n const before = currentLine.slice(0, startCol);\n const toToggle = currentLine.slice(startCol, endCol);\n const after = currentLine.slice(endCol);\n\n const toggled = toToggle.split('').map(ch => {\n if (ch === ch.toUpperCase()) return ch.toLowerCase();\n return ch.toUpperCase();\n }).join('');\n\n lines[state.cursor.line] = before + toggled + after;\n const newContent = lines.join('\\n');\n\n // Move cursor to the right after toggling\n const newCursor = new Cursor(\n state.cursor.line,\n Math.min(endCol, currentLine.length - 1)\n );\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(newContent),\n cursor: newCursor\n };\n }\n}\n\nexport class Lowercase extends Operator {\n key = 'gu';\n\n execute(state: State, context: CommandContext): State {\n // Make text lowercase using motion or visual selection\n const range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Adjust for inclusive visual selection\n let adjustedRange = range;\n if (state.selection && (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK)) {\n adjustedRange = {\n start: range.start,\n end: {\n line: range.end.line,\n column: range.end.column + 1\n }\n };\n }\n\n const normalizedRange = normalizeRange(adjustedRange);\n const text = getTextInRange(state.buffer, normalizedRange);\n const lower = text.toLowerCase();\n const newContent = replaceRange(state.buffer, normalizedRange, lower);\n\n const newState = withBufferContent(state, newContent);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n return newState;\n }\n}\n\nexport class Uppercase extends Operator {\n key = 'gU';\n\n execute(state: State, context: CommandContext): State {\n // Make text uppercase using motion or visual selection\n const range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Adjust for inclusive visual selection\n let adjustedRange = range;\n if (state.selection && (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK)) {\n adjustedRange = {\n start: range.start,\n end: {\n line: range.end.line,\n column: range.end.column + 1\n }\n };\n }\n\n const normalizedRange = normalizeRange(adjustedRange);\n const text = getTextInRange(state.buffer, normalizedRange);\n const upper = text.toUpperCase();\n const newContent = replaceRange(state.buffer, normalizedRange, upper);\n\n const newState = withBufferContent(state, newContent);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n return newState;\n }\n}\n\nexport class ToggleCaseOperator extends Operator {\n key = 'g~';\n\n execute(state: State, context: CommandContext): State {\n // Toggle case using motion or visual selection\n const range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Adjust for inclusive visual selection\n let adjustedRange = range;\n if (state.selection && (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_BLOCK)) {\n adjustedRange = {\n start: range.start,\n end: {\n line: range.end.line,\n column: range.end.column + 1\n }\n };\n }\n\n const normalizedRange = normalizeRange(adjustedRange);\n const text = getTextInRange(state.buffer, normalizedRange);\n const toggled = text.split('').map(ch => {\n if (ch === ch.toUpperCase()) return ch.toLowerCase();\n return ch.toUpperCase();\n }).join('');\n const newContent = replaceRange(state.buffer, normalizedRange, toggled);\n\n const newState = withBufferContent(state, newContent);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n return newState;\n }\n}\n\nexport class LowercaseLine extends Command {\n key = 'guu';\n\n execute(state: State): State {\n // Make current line lowercase\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line];\n\n if (!currentLine) return state;\n\n lines[state.cursor.line] = currentLine.toLowerCase();\n const newContent = lines.join('\\n');\n\n return withBufferContent(state, newContent);\n }\n}\n\nexport class UppercaseLine extends Command {\n key = 'gUU';\n\n execute(state: State): State {\n // Make current line uppercase\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line];\n\n if (!currentLine) return state;\n\n lines[state.cursor.line] = currentLine.toUpperCase();\n const newContent = lines.join('\\n');\n\n return withBufferContent(state, newContent);\n }\n}\n\nexport class ToggleCaseLine extends Command {\n key = 'g~~';\n\n execute(state: State): State {\n // Toggle case of current line\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line];\n\n if (!currentLine) return state;\n\n const toggled = currentLine.split('').map(ch => {\n if (ch === ch.toUpperCase()) return ch.toLowerCase();\n return ch.toUpperCase();\n }).join('');\n\n lines[state.cursor.line] = toggled;\n const newContent = lines.join('\\n');\n\n return withBufferContent(state, newContent);\n }\n}\n","import {Operator} from \"../core/operator\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {Mode} from \"../types/Modes\";\nimport {withBufferContent} from \"../utils/buffer-operations\";\nimport {Buffer} from \"../core/buffer\";\nimport {resolveOperatorRange} from \"../utils/state-utils\";\n\n/**\n * Indentation operators\n */\n\nexport class ShiftRight extends Operator {\n key = '>';\n\n execute(state: State, context: CommandContext): State {\n // Get range from either selection (visual mode) or motion/text object (normal mode)\n let range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Indent lines from start.line to end.line (inclusive)\n const startLine = Math.min(range.start.line, range.end.line);\n const endLine = Math.max(range.start.line, range.end.line);\n\n const lines = state.buffer.content.split('\\n');\n const indentString = context.indentationManager?.getIndentString(1) ?? ' ';\n\n for (let i = startLine; i <= endLine; i++) {\n lines[i] = indentString + lines[i];\n }\n\n const newContent = lines.join('\\n');\n const newState = withBufferContent(state, newContent);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n return newState;\n }\n}\n\nexport class ShiftLeft extends Operator {\n key = '<';\n\n execute(state: State, context: CommandContext): State {\n // Get range from either selection (visual mode) or motion/text object (normal mode)\n let range = state.selection || resolveOperatorRange(state, context);\n if (!range) return state;\n\n // Outdent lines from start.line to end.line (inclusive)\n const startLine = Math.min(range.start.line, range.end.line);\n const endLine = Math.max(range.start.line, range.end.line);\n\n const lines = state.buffer.content.split('\\n');\n const indentSize = context.indentationManager?.getConfig().indentSize ?? 4;\n\n for (let i = startLine; i <= endLine; i++) {\n const line = lines[i] ?? '';\n // Remove one level of indentation\n // Try to remove a tab first\n if (line.startsWith('\\t')) {\n lines[i] = line.slice(1);\n }\n // Otherwise remove up to indentSize spaces\n else {\n const match = line.match(/^( +)/);\n if (match && match[1]) {\n const spacesToRemove = Math.min(match[1].length, indentSize);\n lines[i] = line.slice(spacesToRemove);\n }\n }\n }\n\n const newContent = lines.join('\\n');\n const newState = withBufferContent(state, newContent);\n\n // Exit visual mode if we were in it\n if (state.mode === Mode.VISUAL || state.mode === Mode.VISUAL_LINE || state.mode === Mode.VISUAL_BLOCK) {\n return {\n ...newState,\n mode: Mode.NORMAL,\n selection: null,\n visualAnchor: null\n };\n }\n\n return newState;\n }\n}\n\nexport class AutoIndent extends Operator {\n key = '=';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Auto-indent lines\n return state;\n }\n}\n\nexport class ShiftRightLine extends Operator {\n key = '>>';\n public acceptsMotion = false;\n public acceptsTextObject = false;\n\n execute(state: State, context: CommandContext): State {\n // Get count (number of indent levels to add)\n const count = context.count ?? 1;\n\n const lines = state.buffer.content.split('\\n');\n const indentString = context.indentationManager?.getIndentString(1) ?? ' ';\n\n // Indent the current line 'count' times\n const indentation = indentString.repeat(count);\n lines[state.cursor.line] = indentation + lines[state.cursor.line];\n\n const newContent = lines.join('\\n');\n return withBufferContent(state, newContent);\n }\n}\n\nexport class ShiftLeftLine extends Operator {\n key = '<<';\n public acceptsMotion = false;\n public acceptsTextObject = false;\n\n execute(state: State, context: CommandContext): State{\n // Get count (number of indent levels to remove)\n const count = context.count ?? 1;\n\n const lines = state.buffer.content.split('\\n');\n const indentSize = context.indentationManager?.getConfig().indentSize ?? 4;\n let line = lines[state.cursor.line] ?? '';\n\n // Remove 'count' levels of indentation\n for (let i = 0; i < count; i++) {\n // Try to remove a tab first\n if (line.startsWith('\\t')) {\n line = line.slice(1);\n }\n // Otherwise remove up to indentSize spaces\n else {\n const match = line.match(/^( +)/);\n if (match && match[1]) {\n const spacesToRemove = Math.min(match[1].length, indentSize);\n line = line.slice(spacesToRemove);\n } else {\n // No more indentation to remove\n break;\n }\n }\n }\n\n lines[state.cursor.line] = line;\n const newContent = lines.join('\\n');\n return withBufferContent(state, newContent);\n }\n}\n\nexport class AutoIndentLine extends Operator {\n key = '==';\n public acceptsMotion = false;\n public acceptsTextObject = false;\n\n execute(state: State, context: CommandContext): State {\n // TODO: Auto-indent current line\n return state;\n }\n}\n","import type {State} from \"../core/state\";\nimport type {Buffer} from \"../core/buffer\";\nimport type {Cursor} from \"../core/cursor\";\nimport {\n getCharAt,\n isWordChar,\n isWhitespace,\n skipWhitespace,\n findPrevWordStart,\n findNextWordEnd,\n findPrevWORDStart,\n findNextWORDEnd,\n isPunctuation,\n moveLeft,\n moveRight\n} from \"../utils/text-navigation\";\nimport {expandRangeOuter} from \"../utils/range-utils\";\nimport type {Range} from \"../types/Range\";\nimport {TextObject} from \"../types/TextObject\";\nimport {skipWhile} from \"../utils/search\";\nimport {isAtBufferStart} from \"../utils/cursor-state\";\n\n/**\n * Helper to find the start of the current word under cursor\n * Different from findPrevWordStart which finds the previous word\n */\nfunction findWordStart(buffer: Buffer, cursor: Cursor): Cursor {\n const char = getCharAt(buffer, cursor);\n\n // If on whitespace, find previous word\n if (isWhitespace(char)) {\n return findPrevWordStart(buffer, cursor);\n }\n\n // If on word char or punctuation, skip backward to find start\n if (isWordChar(char)) {\n const pos = skipWhile(buffer, cursor, isWordChar, false);\n // skipWhile returns first non-word char (or buffer start)\n // If not at buffer start, move right to get past the non-word char\n if (!isAtBufferStart(pos)) {\n return moveRight(buffer, pos);\n }\n return pos;\n }\n\n if (isPunctuation(char)) {\n const pos = skipWhile(buffer, cursor, (c) => isPunctuation(c) && c === char, false);\n // skipWhile returns first non-punct char (or buffer start)\n // If not at buffer start, move right to get past the non-punct char\n if (!isAtBufferStart(pos)) {\n return moveRight(buffer, pos);\n }\n return pos;\n }\n\n return cursor;\n}\n\n/**\n * Helper to find the end of the current word under cursor\n * Returns position AFTER the last character (exclusive end for ranges)\n */\nfunction findWordEnd(buffer: Buffer, cursor: Cursor): Cursor {\n const char = getCharAt(buffer, cursor);\n\n // If on whitespace, findNextWordEnd will handle it\n if (isWhitespace(char)) {\n const nextEnd = findNextWordEnd(buffer, cursor);\n // findNextWordEnd returns inclusive, so move one past\n return moveRight(buffer, nextEnd);\n }\n\n // If on word/punctuation, skip to find end (exclusive)\n if (isWordChar(char)) {\n return skipWhile(buffer, cursor, isWordChar, true);\n }\n\n if (isPunctuation(char)) {\n return skipWhile(buffer, cursor, (c) => isPunctuation(c) && c === char, true);\n }\n\n return cursor;\n}\n\nexport class WordTextObject extends TextObject {\n key = 'w';\n\n getRange(state: State, variant: 'inner' | 'outer'): Range {\n const start = findWordStart(state.buffer, state.cursor);\n const end = findWordEnd(state.buffer, state.cursor);\n\n const range = { start, end };\n\n if (variant === 'outer') {\n return expandRangeOuter(state.buffer, range);\n }\n\n return range;\n }\n}\n\n/**\n * WORD text objects (whitespace-separated)\n */\n\n/**\n * Helper to find the start of the current WORD under cursor\n * Different from findPrevWORDStart which finds the previous WORD\n */\nfunction findWORDStart(buffer: Buffer, cursor: Cursor): Cursor {\n const char = getCharAt(buffer, cursor);\n\n // If on whitespace, find previous WORD\n if (isWhitespace(char)) {\n return findPrevWORDStart(buffer, cursor);\n }\n\n // If on non-whitespace, skip backward to find WORD start\n const pos = skipWhile(buffer, cursor, (c) => c !== '' && !isWhitespace(c), false);\n\n // skipWhile returns first whitespace char (or buffer start)\n // If not at buffer start, move right to get past the whitespace\n if (!isAtBufferStart(pos)) {\n return moveRight(buffer, pos);\n }\n\n return pos;\n}\n\n/**\n * Helper to find the end of the current WORD under cursor\n * Returns position AFTER the last character (exclusive end for ranges)\n */\nfunction findWORDEnd(buffer: Buffer, cursor: Cursor): Cursor {\n const char = getCharAt(buffer, cursor);\n\n // If on whitespace, findNextWORDEnd will handle it\n if (isWhitespace(char)) {\n const nextEnd = findNextWORDEnd(buffer, cursor);\n // findNextWORDEnd returns inclusive, so move one past\n return moveRight(buffer, nextEnd);\n }\n\n // If on non-whitespace, skip forward to find WORD end (exclusive)\n return skipWhile(buffer, cursor, (c) => c !== '' && !isWhitespace(c), true);\n}\n\nexport class InnerWORD extends TextObject {\n key = 'iW';\n\n getRange(state: State, variant: 'inner' | 'outer'): Range | null {\n const start = findWORDStart(state.buffer, state.cursor);\n const end = findWORDEnd(state.buffer, state.cursor);\n return { start, end };\n }\n}\n\nexport class AroundWORD extends TextObject {\n key = 'aW';\n\n getRange(state: State, variant: 'inner' | 'outer'): Range | null {\n const start = findWORDStart(state.buffer, state.cursor);\n const end = findWORDEnd(state.buffer, state.cursor);\n const range = { start, end };\n return expandRangeOuter(state.buffer, range);\n }\n}","import type {State} from \"../core/state\";\nimport type {Buffer} from \"../core/buffer\";\nimport type {Cursor} from \"../core/cursor\";\nimport {Cursor as CursorClass} from \"../core/cursor\";\nimport type {Range} from \"../types/Range\";\nimport {TextObject} from \"../types/TextObject\";\nimport {getCharAt, isWhitespace} from \"../utils/text-navigation\";\nimport {moveLeft, moveRight} from \"../utils/cursor-movement\";\nimport {isAtBufferStart, isAtBufferEnd} from \"../utils/cursor-state\";\nimport {expandRangeOuter} from \"../utils/range-utils\";\n\n/**\n * Sentence and paragraph text objects\n */\n\n/**\n * Check if character is sentence ending punctuation\n */\nfunction isSentenceEnd(char: string): boolean {\n return char === '.' || char === '!' || char === '?';\n}\n\n/**\n * Find the start of the current sentence\n */\nfunction findSentenceStart(buffer: Buffer, cursor: Cursor): Cursor {\n let current = cursor;\n\n // Move backward to find sentence start\n while (!isAtBufferStart(current)) {\n const char = getCharAt(buffer, current);\n const prevChar = isAtBufferStart(current) ? '' : getCharAt(buffer, moveLeft(buffer, current));\n\n // Sentence starts after sentence-ending punctuation followed by whitespace\n if (prevChar && isSentenceEnd(prevChar) && isWhitespace(char)) {\n // Skip past the whitespace\n while (!isAtBufferEnd(buffer, current) && isWhitespace(getCharAt(buffer, current))) {\n current = moveRight(buffer, current);\n }\n return current;\n }\n\n current = moveLeft(buffer, current);\n }\n\n // Reached buffer start - skip any leading whitespace\n while (!isAtBufferEnd(buffer, current) && isWhitespace(getCharAt(buffer, current))) {\n current = moveRight(buffer, current);\n }\n\n return current;\n}\n\n/**\n * Find the end of the current sentence\n */\nfunction findSentenceEnd(buffer: Buffer, cursor: Cursor): Cursor {\n let current = cursor;\n\n // Move forward to find sentence end\n while (!isAtBufferEnd(buffer, current)) {\n const char = getCharAt(buffer, current);\n\n if (isSentenceEnd(char)) {\n // Check if followed by whitespace or end of buffer\n const next = moveRight(buffer, current);\n if (isAtBufferEnd(buffer, next) || isWhitespace(getCharAt(buffer, next))) {\n return current;\n }\n }\n\n current = moveRight(buffer, current);\n }\n\n return current;\n}\n\n/**\n * Check if a line is blank (only whitespace)\n */\nfunction isBlankLine(buffer: Buffer, lineNum: number): boolean {\n const lines = buffer.content.split('\\n');\n const line = lines[lineNum] ?? '';\n return line.trim().length === 0;\n}\n\n/**\n * Find the start of the current paragraph\n */\nfunction findParagraphStart(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = buffer.content.split('\\n');\n let lineNum = cursor.line;\n\n // If on blank line, skip to previous non-blank\n while (lineNum > 0 && isBlankLine(buffer, lineNum)) {\n lineNum--;\n }\n\n // Move backward to find paragraph start (first blank line or buffer start)\n while (lineNum > 0) {\n if (isBlankLine(buffer, lineNum - 1)) {\n break;\n }\n lineNum--;\n }\n\n return new CursorClass(lineNum, 0);\n}\n\n/**\n * Find the end of the current paragraph\n */\nfunction findParagraphEnd(buffer: Buffer, cursor: Cursor): Cursor {\n const lines = buffer.content.split('\\n');\n let lineNum = cursor.line;\n\n // If on blank line, skip to previous non-blank (consistent with findParagraphStart)\n while (lineNum > 0 && isBlankLine(buffer, lineNum)) {\n lineNum--;\n }\n\n // Move forward to find paragraph end (first blank line or buffer end)\n while (lineNum < lines.length - 1) {\n if (isBlankLine(buffer, lineNum + 1)) {\n break;\n }\n lineNum++;\n }\n\n const line = lines[lineNum] ?? '';\n return new CursorClass(lineNum, line.length);\n}\n\nexport class InnerSentence extends TextObject {\n key = 'is';\n\n getRange(state: State, variant: 'inner' | 'outer'): Range | null {\n const start = findSentenceStart(state.buffer, state.cursor);\n const end = findSentenceEnd(state.buffer, state.cursor);\n return { start, end };\n }\n}\n\nexport class AroundSentence extends TextObject {\n key = 'as';\n\n getRange(state: State, variant: 'inner' | 'outer'): Range | null {\n const start = findSentenceStart(state.buffer, state.cursor);\n const end = findSentenceEnd(state.buffer, state.cursor);\n const range = { start, end };\n\n // Expand to include trailing whitespace\n return expandRangeOuter(state.buffer, range);\n }\n}\n\nexport class ParagraphTextObject extends TextObject {\n key = 'p';\n\n getRange(state: State, variant: 'inner' | 'outer'): Range | null {\n let start = findParagraphStart(state.buffer, state.cursor);\n let end = findParagraphEnd(state.buffer, state.cursor);\n\n if (variant === 'outer') {\n // Expand to include trailing blank lines\n const lines = state.buffer.content.split('\\n');\n let endLine = end.line;\n while (endLine < lines.length - 1 && isBlankLine(state.buffer, endLine + 1)) {\n endLine++;\n }\n\n // If no trailing blank lines, include leading ones\n if (endLine === end.line) {\n let startLine = start.line;\n while (startLine > 0 && isBlankLine(state.buffer, startLine - 1)) {\n startLine--;\n }\n start = new CursorClass(startLine, 0);\n } else {\n end = new CursorClass(endLine, (lines[endLine] ?? '').length);\n }\n }\n\n return { start, end };\n }\n}\n\n// Backwards compatibility aliases\nexport class InnerParagraph extends ParagraphTextObject {}\nexport class AroundParagraph extends ParagraphTextObject {}\n","import {CountOnlyCommand} from \"../core/command\";\nimport {Operator} from \"../core/operator\";\nimport type {State} from \"../core/state\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * Miscellaneous commands\n *\n * Note: JoinLines, JoinLinesNoSpace, IncrementNumber, and DecrementNumber\n * are implemented in basic-edit.ts and number-ops.ts respectively.\n * The stubs here are kept for reference but should not be used.\n */\n\nexport class JoinLines extends CountOnlyCommand {\n key = 'J';\n\n execute(state: State): State {\n // Implemented in basic-edit.ts\n return state;\n }\n}\n\nexport class JoinLinesNoSpace extends CountOnlyCommand {\n key = 'gJ';\n\n execute(state: State): State {\n // Implemented in basic-edit.ts\n return state;\n }\n}\n\nexport class RepeatLastChange extends Command {\n key = '.';\n public acceptsPrecedingCount = true;\n\n execute(state: State, context: CommandContext): State {\n // Repeat the last command that made a change\n if (!state.lastCommand) {\n return state;\n }\n\n // TODO: This would need to be implemented in the session layer\n // to replay the last command. For now, we just preserve the state.\n // The session would need to:\n // 1. Store the last command and its context\n // 2. On '.', replay that command with the stored context\n // 3. Use the new count if provided, otherwise use original count\n\n return state;\n }\n}\n\nexport class JumpForward extends Command {\n key = '<C-i>';\n\n execute(state: State): State {\n // Jump forward in jump list\n const result = state.jumpListManager.jumpForward();\n\n if (result.position === null) {\n // Can't jump forward or back at most recent position\n return state;\n }\n\n return {\n ...state,\n cursor: result.position,\n jumpListManager: result.manager\n };\n }\n}\n\nexport class JumpBackward extends Command {\n key = '<C-o>';\n\n execute(state: State): State {\n // Jump backward in jump list\n const result = state.jumpListManager.jumpBackward();\n\n if (result.position === null) {\n // Can't jump backward\n return state;\n }\n\n return {\n ...state,\n cursor: result.position,\n jumpListManager: result.manager\n };\n }\n}\n\nexport class IncrementNumber extends CountOnlyCommand {\n key = '<C-a>';\n\n execute(state: State): State {\n // Implemented in number-ops.ts\n return state;\n }\n}\n\nexport class DecrementNumber extends CountOnlyCommand {\n key = '<C-x>';\n\n execute(state: State): State {\n // Implemented in number-ops.ts\n return state;\n }\n}\n\nexport class IncrementNumbersVisual extends Command {\n key = 'g<C-a>';\n\n execute(state: State, context: CommandContext): State {\n // Increment numbers in visual selection (each by count)\n if (!state.selection) {\n return state;\n }\n\n const count = context.count ?? 1;\n const lines = state.buffer.content.split('\\n');\n const {start, end} = state.selection;\n\n // Process each line in the selection\n for (let lineNum = start.line; lineNum <= end.line; lineNum++) {\n const line = lines[lineNum];\n if (!line) continue;\n\n // Find first number on this line\n const numberMatch = line.match(/-?\\d+/);\n if (!numberMatch || numberMatch.index === undefined) continue;\n\n const oldValue = parseInt(numberMatch[0], 10);\n const newValue = oldValue + count;\n\n // Replace the number\n lines[lineNum] =\n line.slice(0, numberMatch.index) +\n newValue.toString() +\n line.slice(numberMatch.index + numberMatch[0].length);\n }\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(lines.join('\\n'))\n };\n }\n}\n\nexport class DecrementNumbersVisual extends Command {\n key = 'g<C-x>';\n\n execute(state: State, context: CommandContext): State {\n // Decrement numbers in visual selection (each by count)\n if (!state.selection) {\n return state;\n }\n\n const count = context.count ?? 1;\n const lines = state.buffer.content.split('\\n');\n const {start, end} = state.selection;\n\n // Process each line in the selection\n for (let lineNum = start.line; lineNum <= end.line; lineNum++) {\n const line = lines[lineNum];\n if (!line) continue;\n\n // Find first number on this line\n const numberMatch = line.match(/-?\\d+/);\n if (!numberMatch || numberMatch.index === undefined) continue;\n\n const oldValue = parseInt(numberMatch[0], 10);\n const newValue = oldValue - count;\n\n // Replace the number\n lines[lineNum] =\n line.slice(0, numberMatch.index) +\n newValue.toString() +\n line.slice(numberMatch.index + numberMatch[0].length);\n }\n\n return {\n ...state,\n buffer: new (state.buffer.constructor as any)(lines.join('\\n'))\n };\n }\n}\n\nexport class FilterLine extends Command {\n key = '!!';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Filter current line through external command\n return state;\n }\n}\n\nexport class FilterMotion extends Operator {\n key = '!';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Filter motion through external command\n return state;\n }\n}\n\nexport class LookupKeyword extends Command {\n key = 'K';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Lookup keyword under cursor\n return state;\n }\n}\n\nexport class ShowASCII extends Command {\n key = 'ga';\n\n execute(state: State): State {\n // Show ASCII/Unicode value of character under cursor\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const char = currentLine[state.cursor.column];\n\n if (!char) {\n // No character under cursor\n return {\n ...state,\n commandLine: 'NUL'\n };\n }\n\n const codePoint = char.codePointAt(0);\n if (codePoint === undefined) {\n return state;\n }\n\n // Format: <x> 123, Hex 7b, Oct 173\n const dec = codePoint;\n const hex = codePoint.toString(16).toUpperCase();\n const oct = codePoint.toString(8);\n const charDisplay = char === ' ' ? 'Space' : char;\n\n const message = `<${charDisplay}> ${dec}, Hex ${hex}, Oct ${oct}`;\n\n return {\n ...state,\n commandLine: message\n };\n }\n}\n\nexport class ShowUTF8 extends Command {\n key = 'g8';\n\n execute(state: State): State {\n // Show UTF-8 encoding of character under cursor\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line] ?? '';\n const char = currentLine[state.cursor.column];\n\n if (!char) {\n return state;\n }\n\n // Get UTF-8 byte sequence\n const encoder = new TextEncoder();\n const bytes = encoder.encode(char);\n\n // Format as hex bytes\n const hexBytes = Array.from(bytes)\n .map(b => b.toString(16).toUpperCase().padStart(2, '0'))\n .join(' ');\n\n const message = `UTF-8: ${hexBytes}`;\n\n return {\n ...state,\n commandLine: message\n };\n }\n}\n\nexport class RedrawScreen extends Command {\n key = '<C-l>';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Redraw screen\n return state;\n }\n}\n\nexport class SuspendVim extends Command {\n key = '<C-z>';\n\n execute(state: State, context: CommandContext): State {\n // TODO: Suspend Vim\n return state;\n }\n}\n","import {Operator} from \"../core/operator\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {Cursor} from \"../core/cursor\";\nimport {resolveOperatorRange} from \"../utils/state-utils\";\n\n/**\n * Folding commands\n */\n\nexport class CreateFold extends Operator {\n key = 'zf';\n\n execute(state: State, context: CommandContext): State {\n // Create fold from motion range or visual selection\n const range = state.selection || resolveOperatorRange(state, context);\n if (!range) {\n return state;\n }\n\n const startLine = range.start.line;\n const endLine = range.end.line;\n\n // Need at least 2 lines to fold\n if (startLine >= endLine) {\n return state;\n }\n\n const newFoldManager = state.foldManager.createFold(startLine, endLine);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class DeleteFold extends Command {\n key = 'zd';\n\n execute(state: State): State {\n // Delete fold under cursor\n const newFoldManager = state.foldManager.deleteFold(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class DeleteFoldsRecursive extends Command {\n key = 'zD';\n\n execute(state: State): State {\n // Delete folds recursively under cursor\n const newFoldManager = state.foldManager.deleteFoldRecursive(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class OpenFold extends Command {\n key = 'zo';\n\n execute(state: State): State {\n // Open fold under cursor\n const newFoldManager = state.foldManager.openFold(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class OpenFoldsRecursive extends Command {\n key = 'zO';\n\n execute(state: State): State {\n // Open folds recursively under cursor\n const newFoldManager = state.foldManager.openFoldRecursive(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class CloseFold extends Command {\n key = 'zc';\n\n execute(state: State): State {\n // Close fold under cursor\n const newFoldManager = state.foldManager.closeFold(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class CloseFoldsRecursive extends Command {\n key = 'zC';\n\n execute(state: State): State {\n // Close folds recursively under cursor\n const newFoldManager = state.foldManager.closeFoldRecursive(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class ToggleFold extends Command {\n key = 'za';\n\n execute(state: State): State {\n // Toggle fold under cursor\n const newFoldManager = state.foldManager.toggleFold(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class ToggleFoldsRecursive extends Command {\n key = 'zA';\n\n execute(state: State): State {\n // Toggle folds recursively under cursor\n const newFoldManager = state.foldManager.toggleFoldRecursive(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class OpenAllFolds extends Command {\n key = 'zR';\n\n execute(state: State): State {\n // Open all folds\n const newFoldManager = state.foldManager.openAllFolds();\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class CloseAllFolds extends Command {\n key = 'zM';\n\n execute(state: State): State {\n // Close all folds\n const newFoldManager = state.foldManager.closeAllFolds();\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class ReduceFolding extends Command {\n key = 'zr';\n\n execute(state: State): State {\n // Reduce folding (open one level)\n // Find the maximum level of currently closed folds\n const folds = state.foldManager.getFolds();\n const closedLevels = folds\n .filter(f => f.isClosed)\n .map(f => f.level);\n\n if (closedLevels.length === 0) {\n return state; // No closed folds\n }\n\n const maxClosedLevel = Math.max(...closedLevels);\n const newFoldManager = state.foldManager.openFoldsToLevel(maxClosedLevel);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class MoreFolding extends Command {\n key = 'zm';\n\n execute(state: State): State {\n // More folding (close one level)\n // Find the minimum level of currently open folds\n const folds = state.foldManager.getFolds();\n const openLevels = folds\n .filter(f => !f.isClosed)\n .map(f => f.level);\n\n if (openLevels.length === 0) {\n return state; // No open folds\n }\n\n const minOpenLevel = Math.min(...openLevels);\n const newFoldManager = state.foldManager.closeFoldsFromLevel(minOpenLevel);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class ViewCursorLine extends Command {\n key = 'zv';\n\n execute(state: State): State {\n // Open folds to view cursor line\n const newFoldManager = state.foldManager.openToViewLine(state.cursor.line);\n\n return {\n ...state,\n foldManager: newFoldManager\n };\n }\n}\n\nexport class NextFold extends Command {\n key = 'zj';\n\n execute(state: State): State {\n // Move to next fold\n const nextFold = state.foldManager.findNextFold(state.cursor.line);\n\n if (!nextFold) {\n return state;\n }\n\n return {\n ...state,\n cursor: new Cursor(nextFold.startLine, 0)\n };\n }\n}\n\nexport class PrevFold extends Command {\n key = 'zk';\n\n execute(state: State): State {\n // Move to previous fold\n const prevFold = state.foldManager.findPrevFold(state.cursor.line);\n\n if (!prevFold) {\n return state;\n }\n\n return {\n ...state,\n cursor: new Cursor(prevFold.startLine, 0)\n };\n }\n}\n","import {CharacterCaptureCommand} from \"../core/command\";\nimport type {State} from \"../core/state\";\nimport type {CommandContext} from \"../types/Command\";\nimport {Cursor} from \"../core/cursor\";\nimport {findFirstNonBlank} from \"../utils/text-navigation\";\nimport {clampCursor} from \"../utils/buffer-operations\";\n\n/**\n * Mark commands\n * All mark commands need to capture a character (the mark name)\n */\n\nexport class SetMark extends CharacterCaptureCommand {\n key = 'm';\n\n executeWithChar(state: State, char: string): State {\n // Set mark at current cursor position\n const newMarkManager = state.markManager.setMark(char, state.cursor);\n\n return {\n ...state,\n markManager: newMarkManager\n };\n }\n}\n\nexport class JumpToMarkLine extends CharacterCaptureCommand {\n key = \"'\";\n\n executeWithChar(state: State, char: string): State {\n // Jump to first non-blank character of line containing mark\n const mark = state.markManager.getMark(char);\n\n if (!mark) {\n // Mark not set\n return {\n ...state,\n commandLine: `Mark '${char}' not set`\n };\n }\n\n // Jump to the line and find first non-blank character\n const targetLine = Math.max(0, Math.min(mark.position.line, state.buffer.content.split('\\n').length - 1));\n const cursor = findFirstNonBlank(state.buffer, new Cursor(targetLine, 0));\n\n // Set automatic mark ` (position before jump)\n const newMarkManager = state.markManager.setAutomaticMark('`', state.cursor);\n\n return {\n ...state,\n cursor,\n markManager: newMarkManager,\n commandLine: ''\n };\n }\n}\n\nexport class JumpToMarkExact extends CharacterCaptureCommand {\n key = '`';\n\n executeWithChar(state: State, char: string): State {\n // Jump to exact position of mark (line and column)\n const mark = state.markManager.getMark(char);\n\n if (!mark) {\n // Mark not set\n return {\n ...state,\n commandLine: `Mark \\`${char}\\` not set`\n };\n }\n\n // Clamp the mark position to valid buffer bounds\n const cursor = clampCursor(state.buffer, mark.position);\n\n // Set automatic mark ` (position before jump)\n const newMarkManager = state.markManager.setAutomaticMark('`', state.cursor);\n\n return {\n ...state,\n cursor,\n markManager: newMarkManager,\n commandLine: ''\n };\n }\n}\n","import {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\nimport {Buffer} from \"../core/buffer\";\nimport {Cursor} from \"../core/cursor\";\n\n/**\n * File operation commands\n * These are typically triggered by ex commands (:e, :w, :q, etc.)\n */\n\nexport class EditFile extends Command {\n key = ':e'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n // Get filename from command line argument\n const filename = context.args?.trim();\n\n if (!filename) {\n return {\n ...state,\n commandLine: 'E471: Argument required'\n };\n }\n\n // Open or create the file\n const newFileSystem = state.fileSystem.openFile(filename);\n const currentFile = newFileSystem.getCurrentFile();\n\n if (!currentFile) {\n return state;\n }\n\n // Update buffer and reset cursor\n return {\n ...state,\n fileSystem: newFileSystem,\n buffer: currentFile.buffer,\n cursor: new Cursor(0, 0),\n commandLine: `\"${filename}\" ${currentFile.buffer.content.split('\\n').length}L`\n };\n }\n}\n\nexport class WriteFile extends Command {\n key = ':w'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const currentPath = state.fileSystem.getCurrentPath();\n\n // If no current file, need a filename argument\n if (!currentPath && !context.args) {\n return {\n ...state,\n commandLine: 'E32: No file name'\n };\n }\n\n const filename = context.args?.trim() || currentPath;\n\n if (!filename) {\n return {\n ...state,\n commandLine: 'E32: No file name'\n };\n }\n\n // Check if readonly\n if (state.fileSystem.isCurrentReadonly()) {\n return {\n ...state,\n commandLine: `E45: 'readonly' option is set (add ! to override)`\n };\n }\n\n // Update the file system with current buffer\n let newFileSystem = state.fileSystem;\n\n // If writing to a different file, open it first\n if (filename !== currentPath) {\n newFileSystem = newFileSystem.openFile(filename, state.buffer.content);\n }\n\n // Update buffer and save\n newFileSystem = newFileSystem.updateCurrentBuffer(state.buffer, false);\n newFileSystem = newFileSystem.saveCurrentFile();\n\n const lines = state.buffer.content.split('\\n').length;\n const chars = state.buffer.content.length;\n\n return {\n ...state,\n fileSystem: newFileSystem,\n commandLine: `\"${filename}\" ${lines}L, ${chars}C written`\n };\n }\n}\n\nexport class QuitFile extends Command {\n key = ':q'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const result = state.fileSystem.closeCurrentFile();\n\n if (!result.success) {\n return {\n ...state,\n commandLine: result.message || 'Cannot quit'\n };\n }\n\n const newFile = result.manager.getCurrentFile();\n\n // If no more files, could indicate quit vim\n if (!newFile) {\n return {\n ...state,\n fileSystem: result.manager,\n commandLine: 'All files closed'\n };\n }\n\n // Switch to next file\n return {\n ...state,\n fileSystem: result.manager,\n buffer: newFile.buffer,\n cursor: new Cursor(0, 0),\n commandLine: `Now editing: ${result.manager.getCurrentPath()}`\n };\n }\n}\n\nexport class ForceQuitFile extends Command {\n key = ':q!'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const result = state.fileSystem.forceCloseCurrentFile();\n\n if (!result.success) {\n return state;\n }\n\n const newFile = result.manager.getCurrentFile();\n\n // If no more files, could indicate quit vim\n if (!newFile) {\n return {\n ...state,\n fileSystem: result.manager,\n commandLine: 'All files closed'\n };\n }\n\n // Switch to next file\n return {\n ...state,\n fileSystem: result.manager,\n buffer: newFile.buffer,\n cursor: new Cursor(0, 0),\n commandLine: `Now editing: ${result.manager.getCurrentPath()}`\n };\n }\n}\n\nexport class WriteQuitFile extends Command {\n key = ':wq'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n // First write\n const writeCmd = new WriteFile();\n const afterWrite = writeCmd.execute(state, context);\n\n // Check if write failed\n if (afterWrite.commandLine?.startsWith('E')) {\n return afterWrite;\n }\n\n // Then quit\n const quitCmd = new QuitFile();\n return quitCmd.execute(afterWrite, context);\n }\n}\n\nexport class WriteAndQuit extends Command {\n key = 'ZZ';\n\n execute(state: State, context: CommandContext): State {\n // Equivalent to :wq\n const wqCmd = new WriteQuitFile();\n return wqCmd.execute(state, context);\n }\n}\n\nexport class QuitWithoutSaving extends Command {\n key = 'ZQ';\n\n execute(state: State, context: CommandContext): State {\n // Equivalent to :q!\n const forceQuitCmd = new ForceQuitFile();\n return forceQuitCmd.execute(state, context);\n }\n}\n\nexport class QuitAll extends Command {\n key = ':qa'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n // Check if any files are modified\n const allPaths = state.fileSystem.getAllPaths();\n for (const path of allPaths) {\n const fileSystem = state.fileSystem.switchToFile(path);\n if (fileSystem.isCurrentModified()) {\n return {\n ...state,\n commandLine: 'E37: No write since last change (add ! to override)'\n };\n }\n }\n\n return {\n ...state,\n commandLine: 'All files closed (quit all)'\n };\n }\n}\n\nexport class ForceQuitAll extends Command {\n key = ':qa!'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n return {\n ...state,\n commandLine: 'All files closed (force quit all)'\n };\n }\n}\n\nexport class WriteQuitAll extends Command {\n key = ':wqa'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n return {\n ...state,\n commandLine: 'All files written and closed'\n };\n }\n}\n\nexport class NextBuffer extends Command {\n key = ':bn'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const nextPath = state.fileSystem.getNextFilePath();\n\n if (!nextPath) {\n return {\n ...state,\n commandLine: 'No other buffer'\n };\n }\n\n // Save current buffer state\n const updatedFileSystem = state.fileSystem.updateCurrentBuffer(state.buffer);\n const newFileSystem = updatedFileSystem.switchToFile(nextPath);\n const newFile = newFileSystem.getCurrentFile();\n\n if (!newFile) {\n return state;\n }\n\n return {\n ...state,\n fileSystem: newFileSystem,\n buffer: newFile.buffer,\n cursor: new Cursor(0, 0),\n commandLine: `\"${nextPath}\"`\n };\n }\n}\n\nexport class PreviousBuffer extends Command {\n key = ':bp'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const prevPath = state.fileSystem.getPreviousFilePath();\n\n if (!prevPath) {\n return {\n ...state,\n commandLine: 'No other buffer'\n };\n }\n\n // Save current buffer state\n const updatedFileSystem = state.fileSystem.updateCurrentBuffer(state.buffer);\n const newFileSystem = updatedFileSystem.switchToFile(prevPath);\n const newFile = newFileSystem.getCurrentFile();\n\n if (!newFile) {\n return state;\n }\n\n return {\n ...state,\n fileSystem: newFileSystem,\n buffer: newFile.buffer,\n cursor: new Cursor(0, 0),\n commandLine: `\"${prevPath}\"`\n };\n }\n}\n\nexport class ListBuffers extends Command {\n key = ':ls'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const allPaths = state.fileSystem.getAllPaths();\n const currentPath = state.fileSystem.getCurrentPath();\n\n if (allPaths.length === 0) {\n return {\n ...state,\n commandLine: 'No buffers'\n };\n }\n\n const bufferList = allPaths.map((path, index) => {\n const isCurrent = path === currentPath;\n const fileSystem = state.fileSystem.switchToFile(path);\n const modified = fileSystem.isCurrentModified() ? '+' : ' ';\n const marker = isCurrent ? '%a' : ' ';\n return `${index + 1} ${marker}${modified} \"${path}\"`;\n }).join('\\n');\n\n return {\n ...state,\n commandLine: bufferList\n };\n }\n}\n\nexport class BufferDelete extends Command {\n key = ':bd'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n const result = state.fileSystem.closeCurrentFile();\n\n if (!result.success) {\n return {\n ...state,\n commandLine: result.message || 'Cannot delete buffer'\n };\n }\n\n const newFile = result.manager.getCurrentFile();\n\n if (!newFile) {\n return {\n ...state,\n fileSystem: result.manager,\n commandLine: 'Buffer deleted'\n };\n }\n\n return {\n ...state,\n fileSystem: result.manager,\n buffer: newFile.buffer,\n cursor: new Cursor(0, 0),\n commandLine: 'Buffer deleted'\n };\n }\n}\n\nexport class ShowFileInfo extends Command {\n key = '<C-g>';\n\n execute(state: State, context: CommandContext): State {\n const currentPath = state.fileSystem.getCurrentPath();\n const lines = state.buffer.content.split('\\n');\n const currentLine = state.cursor.line + 1;\n const totalLines = lines.length;\n const percentage = Math.round((currentLine / totalLines) * 100);\n const modified = state.fileSystem.isCurrentModified() ? '[Modified]' : '';\n const readonly = state.fileSystem.isCurrentReadonly() ? '[RO]' : '';\n\n const filename = currentPath || '[No Name]';\n const info = `\"${filename}\" ${readonly} ${modified} line ${currentLine} of ${totalLines} --${percentage}%--`;\n\n return {\n ...state,\n commandLine: info\n };\n }\n}\n\nexport class GotoFile extends Command {\n key = 'gf';\n\n execute(state: State, context: CommandContext): State {\n // Get word under cursor as filename\n const lines = state.buffer.content.split('\\n');\n const currentLine = lines[state.cursor.line];\n\n if (!currentLine) {\n return {\n ...state,\n commandLine: 'E446: No file name under cursor'\n };\n }\n\n // Simple word extraction\n let start = state.cursor.column;\n let end = state.cursor.column;\n\n while (start > 0 && /[a-zA-Z0-9_\\-./]/.test(currentLine[start - 1] ?? '')) {\n start--;\n }\n\n while (end < currentLine.length && /[a-zA-Z0-9_\\-./]/.test(currentLine[end] ?? '')) {\n end++;\n }\n\n const filename = currentLine.slice(start, end);\n\n if (!filename) {\n return {\n ...state,\n commandLine: 'E446: No file name under cursor'\n };\n }\n\n // Open the file\n const editCmd = new EditFile();\n return editCmd.execute(state, { args: filename });\n }\n}\n","import {Command, type CommandContext} from \"../types/Command\";\nimport type {State} from \"../core/state\";\n\n/**\n * Window management commands\n * These handle window splits, navigation, and closing\n * Most are triggered by Ctrl-W combinations\n */\n\nexport class SplitHorizontal extends Command {\n key = '<C-w>s';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.splitHorizontal();\n\n return {\n ...state,\n windowManager: newWindowManager,\n commandLine: 'Window split horizontally'\n };\n }\n}\n\nexport class SplitHorizontalEx extends Command {\n key = ':sp'; // Ex command alias\n\n execute(state: State, context: CommandContext): State {\n const cmd = new SplitHorizontal();\n return cmd.execute(state, {});\n }\n}\n\nexport class SplitVertical extends Command {\n key = '<C-w>v';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.splitVertical();\n\n return {\n ...state,\n windowManager: newWindowManager,\n commandLine: 'Window split vertically'\n };\n }\n}\n\nexport class SplitVerticalEx extends Command {\n key = ':vsp'; // Ex command alias\n\n execute(state: State, context: CommandContext): State {\n const cmd = new SplitVertical();\n return cmd.execute(state, {});\n }\n}\n\nexport class CloseWindow extends Command {\n key = '<C-w>c';\n\n execute(state: State, context: CommandContext): State {\n const result = state.windowManager.closeActiveWindow();\n\n if (!result.success) {\n return {\n ...state,\n commandLine: result.message || 'Cannot close window'\n };\n }\n\n return {\n ...state,\n windowManager: result.manager,\n commandLine: 'Window closed'\n };\n }\n}\n\nexport class CloseWindowEx extends Command {\n key = ':close'; // Ex command alias\n\n execute(state: State, context: CommandContext): State {\n const cmd = new CloseWindow();\n return cmd.execute(state, {});\n }\n}\n\nexport class CloseOtherWindows extends Command {\n key = '<C-w>o';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.closeOtherWindows();\n\n return {\n ...state,\n windowManager: newWindowManager,\n commandLine: 'All other windows closed'\n };\n }\n}\n\nexport class CloseOtherWindowsEx extends Command {\n key = ':only'; // Ex command alias\n\n execute(state: State, context: CommandContext): State {\n const cmd = new CloseOtherWindows();\n return cmd.execute(state, {});\n }\n}\n\nexport class CycleWindow extends Command {\n key = '<C-w>w';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.cycleWindow();\n const activeWindow = newWindowManager.getActiveWindow();\n\n return {\n ...state,\n windowManager: newWindowManager,\n commandLine: activeWindow ? `Window ${activeWindow.id}` : ''\n };\n }\n}\n\nexport class MoveWindowLeft extends Command {\n key = '<C-w>h';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.navigateWindow('h');\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class MoveWindowDown extends Command {\n key = '<C-w>j';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.navigateWindow('j');\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class MoveWindowUp extends Command {\n key = '<C-w>k';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.navigateWindow('k');\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class MoveWindowRight extends Command {\n key = '<C-w>l';\n\n execute(state: State, context: CommandContext): State {\n const newWindowManager = state.windowManager.navigateWindow('l');\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class WindowIncreaseHeight extends Command {\n key = '<C-w>+';\n\n execute(state: State, context: CommandContext): State {\n const activeWindow = state.windowManager.getActiveWindow();\n\n if (!activeWindow) {\n return state;\n }\n\n const newWindowManager = state.windowManager.updateActiveWindow({\n height: activeWindow.height + 1\n });\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class WindowDecreaseHeight extends Command {\n key = '<C-w>-';\n\n execute(state: State, context: CommandContext): State {\n const activeWindow = state.windowManager.getActiveWindow();\n\n if (!activeWindow || activeWindow.height <= 1) {\n return state;\n }\n\n const newWindowManager = state.windowManager.updateActiveWindow({\n height: activeWindow.height - 1\n });\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class WindowIncreaseWidth extends Command {\n key = '<C-w>>';\n\n execute(state: State, context: CommandContext): State {\n const activeWindow = state.windowManager.getActiveWindow();\n\n if (!activeWindow) {\n return state;\n }\n\n const newWindowManager = state.windowManager.updateActiveWindow({\n width: activeWindow.width + 1\n });\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class WindowDecreaseWidth extends Command {\n key = '<C-w><';\n\n execute(state: State, context: CommandContext): State {\n const activeWindow = state.windowManager.getActiveWindow();\n\n if (!activeWindow || activeWindow.width <= 1) {\n return state;\n }\n\n const newWindowManager = state.windowManager.updateActiveWindow({\n width: activeWindow.width - 1\n });\n\n return {\n ...state,\n windowManager: newWindowManager\n };\n }\n}\n\nexport class EqualizeWindows extends Command {\n key = '<C-w>=';\n\n execute(state: State, context: CommandContext): State {\n // Simple implementation: just report action\n return {\n ...state,\n commandLine: 'Windows resized to equal size'\n };\n }\n}\n\nexport class WindowRotateDown extends Command {\n key = '<C-w>r';\n\n execute(state: State, context: CommandContext): State {\n // Rotate window contents downward/rightward\n return {\n ...state,\n commandLine: 'Windows rotated'\n };\n }\n}\n\nexport class WindowRotateUp extends Command {\n key = '<C-w>R';\n\n execute(state: State, context: CommandContext): State {\n // Rotate window contents upward/leftward\n return {\n ...state,\n commandLine: 'Windows rotated'\n };\n }\n}\n\nexport class WindowExchange extends Command {\n key = '<C-w>x';\n\n execute(state: State, context: CommandContext): State {\n // Exchange current window with next\n return {\n ...state,\n commandLine: 'Windows exchanged'\n };\n }\n}\n\nexport class WindowMoveToTop extends Command {\n key = '<C-w>K';\n\n execute(state: State, context: CommandContext): State {\n return {\n ...state,\n commandLine: 'Window moved to top'\n };\n }\n}\n\nexport class WindowMoveToBottom extends Command {\n key = '<C-w>J';\n\n execute(state: State, context: CommandContext): State {\n return {\n ...state,\n commandLine: 'Window moved to bottom'\n };\n }\n}\n\nexport class WindowMoveToLeftmost extends Command {\n key = '<C-w>H';\n\n execute(state: State, context: CommandContext): State {\n return {\n ...state,\n commandLine: 'Window moved to left'\n };\n }\n}\n\nexport class WindowMoveToRightmost extends Command {\n key = '<C-w>L';\n\n execute(state: State, context: CommandContext): State {\n return {\n ...state,\n commandLine: 'Window moved to right'\n };\n }\n}\n\nexport class NewWindow extends Command {\n key = ':new'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n // Split horizontally and open new empty buffer\n const newWindowManager = state.windowManager.splitHorizontal();\n const newFileSystem = state.fileSystem.openFile('[No Name]', '');\n const newFile = newFileSystem.getCurrentFile();\n\n if (!newFile) {\n return state;\n }\n\n return {\n ...state,\n windowManager: newWindowManager,\n fileSystem: newFileSystem,\n buffer: newFile.buffer,\n commandLine: 'New window created'\n };\n }\n}\n\nexport class NewWindowVertical extends Command {\n key = ':vnew'; // Ex command\n\n execute(state: State, context: CommandContext): State {\n // Split vertically and open new empty buffer\n const newWindowManager = state.windowManager.splitVertical();\n const newFileSystem = state.fileSystem.openFile('[No Name]', '');\n const newFile = newFileSystem.getCurrentFile();\n\n if (!newFile) {\n return state;\n }\n\n return {\n ...state,\n windowManager: newWindowManager,\n fileSystem: newFileSystem,\n buffer: newFile.buffer,\n commandLine: 'New vertical window created'\n };\n }\n}\n","import {Mode} from \"../types/Modes\";\nimport type {Motion} from \"./motion\";\nimport {createEmptyState, type State} from \"./state\";\nimport {Cursor} from \"./cursor\";\nimport {\n handleInsertEscape,\n handleInsertBackspace,\n handleInsertEnter,\n handleInsertSpace,\n handleInsertArrowLeft,\n handleInsertArrowRight,\n handleInsertArrowUp,\n handleInsertArrowDown,\n handleInsertCharacter\n} from \"./insert\";\nimport {w, e, b, W, E, B} from \"../motions/word\";\nimport {\n h,\n l,\n j,\n k,\n G,\n gg,\n zero,\n dollar,\n caret,\n Backspace,\n End,\n Home,\n ArrowLeft,\n ArrowRight,\n ArrowDown, ArrowUp, Enter\n} from \"../motions/basic\";\nimport {RegisterManager} from \"../registers/manager\";\nimport {UndoStack} from \"../history/undotree\";\nimport {Change} from \"../history/change\";\nimport {IndentationManager} from \"./indent-manager\";\nimport {ConfigManager} from \"./config-manager\";\nimport {\n Colon,\n InsertAtCursor,\n InsertAtLineStart,\n AppendAfterCursor,\n AppendAtLineEnd,\n OpenLineBelow,\n OpenLineAbove\n} from \"../commands/mode-commands\";\nimport {d, dd, Delete} from \"../operators/delete\";\nimport {DeleteChar, DeleteCharBackward, ReplaceChar, Substitute, SubstituteLine, JoinLines, JoinLinesNoSpace} from \"../commands/basic-edit\";\nimport {IncrementNumber, DecrementNumber} from \"../commands/number-ops\";\nimport {RecordMacro, PlayMacro, RepeatMacro} from \"../commands/macros\";\nimport {TextObject} from \"../types/TextObject\";\nimport {Command, type CommandContext} from \"../types/Command\";\nimport {y, yy} from \"../operators/yank\";\nimport {c, cc} from \"../operators/change\";\nimport {p, P} from \"../operators/paste\";\nimport {F, f, T, t} from \"../motions/find\";\nimport {H, M, L} from \"../motions/screen\";\nimport {MatchPercent, ge, gE, LastNonBlank, MiddleOfScreenLine, MiddleOfLine, Column} from \"../motions/extended\";\nimport {OpenBrace, CloseBrace, OpenParen, CloseParen} from \"../motions/paragraph\";\nimport {Star, Hash, gStar, gHash, n, N, SearchForward, SearchBackward} from \"../motions/search\";\nimport {\n ScrollHalfPageDown,\n ScrollHalfPageUp,\n ScrollPageDown,\n ScrollPageUp,\n ScrollCursorCenter,\n ScrollCursorTop,\n ScrollCursorBottom,\n ScrollLineDown,\n ScrollLineUp\n} from \"../commands/scroll\";\nimport {\n VisualChar,\n VisualLine,\n VisualBlock,\n ExitVisual,\n MoveToOtherEnd,\n MoveToOtherCorner,\n ReselectVisual\n} from \"../commands/visual\";\nimport {\n VisualToggleCase,\n VisualUppercase,\n VisualLowercase,\n ToggleCase,\n Lowercase,\n Uppercase,\n ToggleCaseOperator,\n LowercaseLine,\n UppercaseLine,\n ToggleCaseLine\n} from \"../operators/case\";\nimport {\n ShiftRight,\n ShiftLeft,\n ShiftRightLine,\n ShiftLeftLine\n} from \"../operators/indent\";\nimport {WordTextObject, InnerWORD, AroundWORD} from \"../textobjects/word\";\nimport {ParagraphTextObject} from \"../textobjects/sentence\";\nimport {\n ShowASCII,\n ShowUTF8,\n IncrementNumbersVisual,\n DecrementNumbersVisual,\n JumpForward,\n JumpBackward\n} from \"../commands/misc\";\nimport {\n CreateFold,\n DeleteFold,\n DeleteFoldsRecursive,\n OpenFold,\n OpenFoldsRecursive,\n CloseFold,\n CloseFoldsRecursive,\n ToggleFold,\n ToggleFoldsRecursive,\n OpenAllFolds,\n CloseAllFolds,\n ReduceFolding,\n MoreFolding,\n ViewCursorLine,\n NextFold,\n PrevFold\n} from \"../commands/fold\";\nimport {\n SetMark,\n JumpToMarkLine,\n JumpToMarkExact\n} from \"../commands/marks\";\nimport {\n EditFile,\n WriteFile,\n QuitFile,\n ForceQuitFile,\n WriteQuitFile,\n WriteAndQuit,\n QuitWithoutSaving,\n QuitAll,\n ForceQuitAll,\n WriteQuitAll,\n NextBuffer,\n PreviousBuffer,\n ListBuffers,\n BufferDelete,\n ShowFileInfo,\n GotoFile\n} from \"../commands/file\";\nimport {\n SplitHorizontal,\n SplitHorizontalEx,\n SplitVertical,\n SplitVerticalEx,\n CloseWindow,\n CloseWindowEx,\n CloseOtherWindows,\n CloseOtherWindowsEx,\n CycleWindow,\n MoveWindowLeft,\n MoveWindowDown,\n MoveWindowUp,\n MoveWindowRight,\n WindowIncreaseHeight,\n WindowDecreaseHeight,\n WindowIncreaseWidth,\n WindowDecreaseWidth,\n EqualizeWindows,\n WindowRotateDown,\n WindowRotateUp,\n WindowExchange,\n WindowMoveToTop,\n WindowMoveToBottom,\n WindowMoveToLeftmost,\n WindowMoveToRightmost,\n NewWindow,\n NewWindowVertical\n} from \"../commands/window\";\n\nexport interface CommandHistoryEntry {\n keys: string;\n timestamp: number;\n}\n\ninterface MatchResult {\n command: Command;\n context: CommandContext;\n isComplete: boolean; // full match vs partial (still typing)\n}\n\nexport class Session {\n private commands: Map<Mode, Command[]> = new Map();\n private motions: Map<string, Motion> = new Map();\n private textObjects: Map<string, TextObject> = new Map();\n private keyBuffer: string[] = [];\n private isPlayingMacro: boolean = false;\n public state: State = createEmptyState();\n\n public registerManager: RegisterManager = new RegisterManager();\n public undoStack: UndoStack = new UndoStack();\n public commandHistory: CommandHistoryEntry[] = [];\n public indentationManager: IndentationManager = new IndentationManager();\n public configManager: ConfigManager = new ConfigManager();\n\n constructor() {\n this.loadStandardVimCommands();\n // Auto-detect indentation from initial buffer if it has content\n if (this.state.buffer.content.length > 0) {\n const detected = this.indentationManager.detectIndentation(this.state.buffer);\n this.indentationManager.setConfig(detected);\n }\n\n // Sync indent config with vim config\n this.syncIndentConfig();\n this.configManager.onChange('*', (key) => {\n if (['tabstop', 'shiftwidth', 'expandtab'].includes(key)) {\n this.syncIndentConfig();\n }\n });\n }\n\n private syncIndentConfig(): void {\n this.indentationManager.setConfig({\n useSpaces: this.configManager.get('expandtab'),\n indentSize: this.configManager.get('shiftwidth')\n });\n }\n public setState(state: State): void {\n this.state = state;\n }\n public getState(): State {\n return this.state;\n }\n public getPendingKeys(): string {\n return this.keyBuffer.join('');\n }\n public getCommandLine(): string {\n return this.state.commandLine;\n }\n public getRegisters(): Map<string, { content: string; linewise: boolean }> {\n const all = this.registerManager.getAll();\n const result = new Map<string, { content: string; linewise: boolean }>();\n for (const [name, reg] of all) {\n result.set(name, { content: reg.content, linewise: reg.linewise });\n }\n return result;\n }\n public getUndoStack(): UndoStack {\n return this.undoStack;\n }\n public getCommandHistory(): CommandHistoryEntry[] {\n return this.commandHistory;\n }\n\n /**\n * Convenience method to set cursor position directly.\n * Automatically clamps to valid buffer bounds.\n */\n public setCursor(line: number, column: number): void {\n const lines = this.state.buffer.content.split('\\n');\n const maxLine = Math.max(0, lines.length - 1);\n const clampedLine = Math.max(0, Math.min(line, maxLine));\n\n const lineContent = lines[clampedLine] ?? '';\n const maxCol = Math.max(0, lineContent.length - 1);\n const clampedCol = Math.max(0, Math.min(column, maxCol));\n\n this.state = {\n ...this.state,\n cursor: new Cursor(clampedLine, clampedCol),\n desiredColumn: null\n };\n }\n\n /**\n * Convenience method to enter VISUAL mode with a selection.\n * Automatically clamps coordinates to valid buffer bounds.\n */\n public setSelection(startLine: number, startCol: number, endLine: number, endCol: number): void {\n const lines = this.state.buffer.content.split('\\n');\n const maxLine = Math.max(0, lines.length - 1);\n\n // Clamp start position\n const clampedStartLine = Math.max(0, Math.min(startLine, maxLine));\n const startLineContent = lines[clampedStartLine] ?? '';\n const maxStartCol = Math.max(0, startLineContent.length - 1);\n const clampedStartCol = Math.max(0, Math.min(startCol, maxStartCol));\n\n // Clamp end position\n const clampedEndLine = Math.max(0, Math.min(endLine, maxLine));\n const endLineContent = lines[clampedEndLine] ?? '';\n const maxEndCol = Math.max(0, endLineContent.length - 1);\n const clampedEndCol = Math.max(0, Math.min(endCol, maxEndCol));\n\n this.state = {\n ...this.state,\n cursor: new Cursor(clampedEndLine, clampedEndCol),\n selection: {\n start: new Cursor(clampedStartLine, clampedStartCol),\n end: new Cursor(clampedEndLine, clampedEndCol)\n },\n mode: Mode.VISUAL,\n desiredColumn: null\n };\n }\n\n /**\n * Convenience method to clear selection and return to NORMAL mode.\n */\n public clearSelection(): void {\n this.state = {\n ...this.state,\n selection: null,\n mode: Mode.NORMAL\n };\n }\n\n /**\n * Convenience method to set the mode.\n * Note: Use clearSelection() to exit VISUAL mode, or setCursor() to maintain cursor position.\n */\n public setMode(mode: Mode): void {\n this.state = {\n ...this.state,\n mode: mode,\n // Clear selection when exiting visual modes\n selection: (mode === Mode.VISUAL || mode === Mode.VISUAL_LINE || mode === Mode.VISUAL_BLOCK)\n ? this.state.selection\n : null\n };\n }\n\n /**\n * Normalize a key string to Vim format.\n * This is useful for testing or when you have key strings that need normalization.\n *\n * Examples:\n * - normalizeKey(\"Ctrl+f\") -> \"<C-f>\"\n * - normalizeKey(\"Alt+x\") -> \"<A-x>\"\n * - normalizeKey(\"Escape\") -> \"<Esc>\"\n */\n public static normalizeKey(key: string): string {\n // Already in Vim format\n if (key.startsWith('<') && key.endsWith('>')) {\n return key;\n }\n\n // Handle Ctrl+ or Ctrl- prefix\n if (key.startsWith('Ctrl+')) {\n const char = key.slice(5).toLowerCase();\n return '<C-' + char + '>';\n }\n if (key.startsWith('Ctrl-')) {\n const char = key.slice(5).toLowerCase();\n return '<C-' + char + '>';\n }\n\n // Handle Alt+ prefix\n if (key.startsWith('Alt+')) {\n const char = key.slice(4).toLowerCase();\n return '<A-' + char + '>';\n }\n\n // Handle Meta+ or Cmd+ prefix\n if (key.startsWith('Meta+') || key.startsWith('Cmd+')) {\n const char = key.slice(key.indexOf('+') + 1).toLowerCase();\n return '<D-' + char + '>';\n }\n\n // Handle special keys\n if (key === 'Escape' || key === 'Esc') return '<Esc>';\n if (key === ' ') return 'Space';\n\n return key;\n }\n\n /**\n * Handle a raw keyboard event from the browser.\n * Converts browser KeyboardEvent to Vim-style key notation.\n *\n * Key format conventions:\n * - Single keys: 'a', 'B', '1', '$', etc.\n * - Ctrl combinations: '<C-f>', '<C-w>', etc.\n * - Alt combinations: '<A-x>', '<A-k>', etc.\n * - Command/Meta: '<D-s>', '<D-c>', etc.\n * - Special keys: '<Esc>', 'Space', 'Enter', 'Backspace', etc.\n * - Arrow keys: 'ArrowUp', 'ArrowDown', etc.\n */\n public handleRawKeyEvent(event: KeyboardEvent): void {\n let key = event.key;\n\n // Handle Ctrl combinations - convert to Vim format <C-x>\n if (event.ctrlKey && !event.altKey && !event.metaKey) {\n // Handle single character Ctrl combinations\n if (key.length === 1) {\n // Normalize to lowercase for consistency\n key = '<C-' + key.toLowerCase() + '>';\n }\n // Handle special keys with Ctrl\n else if (key === 'ArrowUp') key = '<C-Up>';\n else if (key === 'ArrowDown') key = '<C-Down>';\n else if (key === 'ArrowLeft') key = '<C-Left>';\n else if (key === 'ArrowRight') key = '<C-Right>';\n else if (key === 'Home') key = '<C-Home>';\n else if (key === 'End') key = '<C-End>';\n else if (key === 'PageUp') key = '<C-PageUp>';\n else if (key === 'PageDown') key = '<C-PageDown>';\n else if (key === 'Backspace') key = '<C-Backspace>';\n else if (key === 'Delete') key = '<C-Delete>';\n else if (key === 'Tab') key = '<C-Tab>';\n else if (key === 'Enter') key = '<C-Enter>';\n // For other Ctrl combinations, keep original if not single char\n }\n // Handle Alt combinations - convert to Vim format <A-x>\n else if (event.altKey && !event.ctrlKey && !event.metaKey) {\n if (key.length === 1) {\n key = '<A-' + key.toLowerCase() + '>';\n }\n else if (key === 'ArrowUp') key = '<A-Up>';\n else if (key === 'ArrowDown') key = '<A-Down>';\n else if (key === 'ArrowLeft') key = '<A-Left>';\n else if (key === 'ArrowRight') key = '<A-Right>';\n }\n // Handle Meta/Cmd combinations - convert to Vim format <D-x>\n else if (event.metaKey && !event.ctrlKey && !event.altKey) {\n if (key.length === 1) {\n // Use <D-x> for Command/Meta key (D for \"command\" in Vim)\n key = '<D-' + key.toLowerCase() + '>';\n }\n }\n // Handle Shift combinations for special keys\n else if (event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) {\n // Shift+Arrow keys\n if (key === 'ArrowUp') key = '<S-Up>';\n else if (key === 'ArrowDown') key = '<S-Down>';\n else if (key === 'ArrowLeft') key = '<S-Left>';\n else if (key === 'ArrowRight') key = '<S-Right>';\n else if (key === 'Tab') key = '<S-Tab>';\n // For letters, Shift is handled naturally by key being uppercase\n // For numbers/symbols, Shift is handled naturally by key being the shifted char\n }\n\n // Normalize special keys\n if (key === ' ') key = 'Space';\n else if (key === '<Esc>') key = '<Esc>';\n\n this.handleKey(key);\n }\n public handleKey(key: string): void {\n // Normalize key to Vim format (handles 'Escape' -> '<Esc>', etc.)\n key = Session.normalizeKey(key);\n\n // Handle INSERT mode separately\n if (this.state.mode === Mode.INSERT) {\n this.handleInsertMode(key);\n return;\n }\n\n // Handle COMMAND mode separately\n if (this.state.mode === Mode.COMMAND) {\n this.handleCommandMode(key);\n return;\n }\n\n // Handle undo: u in normal mode\n if (key === 'u' && this.keyBuffer.length === 0 && this.state.mode === Mode.NORMAL) {\n const prevState = this.undoStack.undo();\n if (prevState) {\n this.state = prevState;\n }\n this.commandHistory.push({ keys: 'u', timestamp: Date.now() });\n return;\n }\n\n // Handle redo: <C-r> in normal mode\n if (key === '<C-r>' && this.keyBuffer.length === 0 && this.state.mode === Mode.NORMAL) {\n const nextState = this.undoStack.redo();\n if (nextState) {\n this.state = nextState;\n }\n this.commandHistory.push({ keys: '<C-r>', timestamp: Date.now() });\n return;\n }\n\n this.keyBuffer.push(key);\n const input = this.keyBuffer.join('');\n\n console.log('[DEBUG] handleKey - input:', input, 'keyBuffer:', this.keyBuffer);\n const result = this.match(input, this.keyBuffer);\n console.log('[DEBUG] handleKey - match result:', result ? (result === 'partial' ? 'partial' : `complete: ${result.command.key}`) : 'null');\n\n if (result && result !== 'partial' && result.isComplete) {\n const stateBefore = this.state;\n\n // Inject register manager and indentation manager into context\n result.context.registerManager = this.registerManager;\n result.context.indentationManager = this.indentationManager;\n\n console.log('[DEBUG] Executing command:', result.command.key, 'with context:', {\n count: result.context.count,\n motion: result.context.motion?.key,\n char: result.context.char\n });\n this.state = result.command.execute(this.state, result.context);\n\n // Handle visual mode: if cursor moved due to a motion, update selection\n if ((stateBefore.mode === Mode.VISUAL || stateBefore.mode === Mode.VISUAL_LINE || stateBefore.mode === Mode.VISUAL_BLOCK) &&\n this.state.mode === stateBefore.mode && // Still in same visual mode\n stateBefore.visualAnchor &&\n (this.state.cursor.line !== stateBefore.cursor.line || this.state.cursor.column !== stateBefore.cursor.column)) {\n\n // Update selection based on visual mode type\n if (this.state.mode === Mode.VISUAL) {\n // Character-wise: selection from anchor to cursor\n this.state = {\n ...this.state,\n selection: { start: stateBefore.visualAnchor, end: this.state.cursor },\n visualAnchor: stateBefore.visualAnchor\n };\n } else if (this.state.mode === Mode.VISUAL_LINE) {\n // Line-wise: expand to full lines\n const lines = this.state.buffer.content.split('\\n');\n const startLine = Math.min(stateBefore.visualAnchor.line, this.state.cursor.line);\n const endLine = Math.max(stateBefore.visualAnchor.line, this.state.cursor.line);\n const startCol = 0;\n const endCol = Math.max(0, (lines[endLine]?.length ?? 1) - 1);\n\n this.state = {\n ...this.state,\n selection: {\n start: { line: startLine, column: startCol },\n end: { line: endLine, column: endCol }\n },\n visualAnchor: stateBefore.visualAnchor\n };\n } else if (this.state.mode === Mode.VISUAL_BLOCK) {\n // Block-wise: rectangular selection\n this.state = {\n ...this.state,\n selection: { start: stateBefore.visualAnchor, end: this.state.cursor },\n visualAnchor: stateBefore.visualAnchor\n };\n }\n }\n\n // If an operator was executed in visual mode, save the selection and return to normal mode\n if ((stateBefore.mode === Mode.VISUAL || stateBefore.mode === Mode.VISUAL_LINE || stateBefore.mode === Mode.VISUAL_BLOCK) &&\n this.state.mode === Mode.NORMAL && !this.state.selection) {\n // Operator executed, save last visual selection\n if (stateBefore.selection) {\n this.state = {\n ...this.state,\n lastVisualSelection: { range: stateBefore.selection, mode: stateBefore.mode }\n };\n }\n }\n\n // Push to undo stack if state changed\n if (this.state !== stateBefore &&\n (this.state.buffer.content !== stateBefore.buffer.content ||\n this.state.cursor.line !== stateBefore.cursor.line ||\n this.state.cursor.column !== stateBefore.cursor.column)) {\n this.undoStack.push(new Change(\n stateBefore,\n this.state,\n input,\n Date.now(),\n ));\n }\n\n // Record keystroke if we're recording a macro\n // Don't record the 'q' command that starts/stops recording\n // Don't record keystrokes during macro playback\n if (!this.isPlayingMacro &&\n stateBefore.recordingRegister &&\n this.state.recordingRegister && // Still recording after execution\n result.command.key !== 'q') {\n const currentMacro = this.registerManager.get(stateBefore.recordingRegister);\n const newMacro = (currentMacro?.content || '') + input;\n this.registerManager.set(stateBefore.recordingRegister, newMacro, false);\n }\n\n // Handle macro playback if PlayMacro or RepeatMacro was executed\n if (result.command instanceof PlayMacro || result.command instanceof RepeatMacro) {\n let registerToPlay: string | null = null;\n\n if (result.command instanceof PlayMacro) {\n // For @, use the captured character (register name)\n registerToPlay = result.context.char ?? null;\n } else {\n // For @@, use the last played macro register\n registerToPlay = stateBefore.lastMacroRegister;\n }\n\n if (registerToPlay) {\n const macroContent = this.registerManager.get(registerToPlay);\n if (macroContent?.content) {\n const count = result.context.count ?? 1;\n this.playMacro(macroContent.content, count);\n }\n }\n }\n\n // Log to command history\n this.commandHistory.push({ keys: input, timestamp: Date.now() });\n\n this.keyBuffer = [];\n } else if (result === null) {\n // No possible match, reset\n this.keyBuffer = [];\n }\n // else partial match, keep buffering\n }\n\n private handleInsertMode(key: string): void {\n // Handle Escape - return to normal mode\n if (key === '<Esc>') {\n this.state = handleInsertEscape(this.state);\n return;\n }\n\n const stateBefore = this.state;\n\n // Handle Backspace\n if (key === 'Backspace') {\n this.state = handleInsertBackspace(this.state);\n }\n // Handle Enter (both 'Enter' key and '\\n' literal newline)\n else if (key === 'Enter' || key === '\\n') {\n this.state = handleInsertEnter(this.state, this.indentationManager);\n }\n // Handle Space\n else if (key === 'Space') {\n this.state = handleInsertSpace(this.state);\n }\n // Handle arrow keys - allow cursor movement in insert mode\n else if (key === 'ArrowLeft') {\n this.state = handleInsertArrowLeft(this.state);\n }\n else if (key === 'ArrowRight') {\n this.state = handleInsertArrowRight(this.state);\n }\n else if (key === 'ArrowUp') {\n this.state = handleInsertArrowUp(this.state);\n }\n else if (key === 'ArrowDown') {\n this.state = handleInsertArrowDown(this.state);\n }\n // Handle regular character insertion\n else if (key.length === 1) {\n this.state = handleInsertCharacter(this.state, key);\n }\n\n // Push to undo stack if buffer changed\n if (this.state.buffer.content !== stateBefore.buffer.content) {\n this.undoStack.push(new Change(\n stateBefore,\n this.state,\n key,\n Date.now(),\n ));\n }\n }\n\n private handleCommandMode(key: string): void {\n // Handle Escape - return to normal mode and clear command line\n if (key === '<Esc>') {\n this.state = {\n ...this.state,\n mode: Mode.NORMAL,\n commandLine: ''\n };\n return;\n }\n\n // Handle Backspace - delete last character\n if (key === 'Backspace') {\n if (this.state.commandLine.length > 1) {\n // Delete last character (keep at least the ':')\n this.state = {\n ...this.state,\n commandLine: this.state.commandLine.slice(0, -1)\n };\n } else {\n // If only ':' remains, exit command mode\n this.state = {\n ...this.state,\n mode: Mode.NORMAL,\n commandLine: ''\n };\n }\n return;\n }\n\n // Handle Enter - execute command\n if (key === 'Enter') {\n // Strip the leading ':' before executing\n const commandText = this.state.commandLine.slice(1);\n this.executeCommand(commandText);\n this.state = {\n ...this.state,\n mode: Mode.NORMAL,\n commandLine: ''\n };\n return;\n }\n\n // Handle regular character - append to command line\n if (key.length === 1) {\n this.state = {\n ...this.state,\n commandLine: this.state.commandLine + key\n };\n }\n }\n\n private executeCommand(command: string): void {\n // Parse and execute ex commands\n const cmd = command.trim();\n\n // Handle set commands (e.g., :set number, :set tabstop=4)\n const setMatch = cmd.match(/^set\\s+(.+)$/);\n if (setMatch) {\n const setCommand = setMatch[1]!.trim();\n this.configManager.parseSetCommand(setCommand);\n return;\n }\n\n // Handle quit commands\n if (cmd === 'q' || cmd === 'quit') {\n // TODO: Implement quit functionality\n return;\n }\n\n // Handle write commands\n if (cmd === 'w' || cmd === 'write') {\n // TODO: Implement write functionality\n return;\n }\n\n // Handle write-quit\n if (cmd === 'wq' || cmd === 'x') {\n // TODO: Implement write-quit functionality\n return;\n }\n\n // Handle line navigation (e.g., :10 to go to line 10)\n const lineMatch = cmd.match(/^(\\d+)$/);\n if (lineMatch) {\n const targetLine = parseInt(lineMatch[1]!, 10) - 1; // Convert to 0-indexed\n const lines = this.state.buffer.content.split('\\n');\n if (targetLine >= 0 && targetLine < lines.length) {\n this.state = {\n ...this.state,\n cursor: new Cursor(targetLine, 0),\n desiredColumn: null\n };\n }\n return;\n }\n\n // Unknown command - silently ignore for now\n // TODO: Add error message handling\n }\n\n private match(input: string, keyBuffer: string[]): MatchResult | null | 'partial' {\n let partialMatch: 'partial' | null = null;\n\n // Check motions first\n for (const motion of this.motions.values()) {\n const result = this.tryMatch(motion, input, keyBuffer);\n if (result === 'partial') {\n partialMatch = 'partial';\n } else if (result) {\n return result; // Complete match, return immediately\n }\n }\n\n // Then check commands for current mode\n const commands = this.commands.get(this.state.mode) ?? [];\n for (const cmd of commands) {\n const result = this.tryMatch(cmd, input, keyBuffer);\n if (result === 'partial') {\n partialMatch = 'partial';\n } else if (result) {\n return result; // Complete match, return immediately\n }\n }\n\n // Return partial match only if no complete match was found\n return partialMatch;\n }\n\n private tryMatch(cmd: Command, input: string, keyBuffer: string[]): MatchResult | null | 'partial' {\n let pos = 0;\n let keyIndex = 0;\n const context: CommandContext = {};\n\n // 1. Parse optional register prefix (before count!)\n if (cmd.acceptsRegister && input[pos] === '\"') {\n pos++;\n if (pos >= input.length) return 'partial';\n const reg = input[pos];\n if (reg) context.register = reg;\n pos++;\n }\n\n // 2. Try to parse optional count\n if (cmd.acceptsPrecedingCount) {\n const countMatch = input.slice(pos).match(/^([1-9][0-9]*)/);\n if (countMatch && countMatch[1]) {\n context.count = parseInt(countMatch[1], 10);\n pos += countMatch[0].length;\n }\n }\n\n // 3. Match the command key\n if (!input.slice(pos).startsWith(cmd.key)) {\n // Check if it COULD match (partial)\n if (cmd.key.startsWith(input.slice(pos))) {\n return 'partial';\n }\n return null;\n }\n pos += cmd.key.length;\n\n // 4. Handle prefix commands (g, z, Ctrl-w, etc.)\n if (cmd.isPrefix) {\n if (pos >= input.length) return 'partial';\n\n // Try to match subcommand\n const remaining = input.slice(pos);\n const prefixCmd = cmd as any; // PrefixCommand\n if (prefixCmd.subcommands) {\n for (const [subkey, subcmd] of prefixCmd.subcommands) {\n if (remaining.startsWith(subkey)) {\n // Found matching subcommand\n return { command: subcmd, context, isComplete: pos + subkey.length === input.length };\n }\n if (subkey.startsWith(remaining)) {\n return 'partial';\n }\n }\n }\n return null;\n }\n\n // 5. Handle character capture (f, t, r, m, ', \", `)\n if (cmd.needsFollowingChar) {\n // Calculate which key index we're at by counting consumed characters\n keyIndex = 0;\n let consumed = 0;\n while (keyIndex < keyBuffer.length && consumed < pos) {\n consumed += keyBuffer[keyIndex]!.length;\n keyIndex++;\n }\n\n // The next key is the character to capture\n if (keyIndex >= keyBuffer.length) return 'partial';\n const char = keyBuffer[keyIndex];\n if (char) context.char = char;\n return { command: cmd, context, isComplete: true };\n }\n\n // 6. Nothing left to parse - command is complete\n if (!cmd.acceptsMotion && !cmd.acceptsTextObject) {\n return pos === input.length\n ? { command: cmd, context, isComplete: true }\n : null;\n }\n\n // 7. In visual mode, operators don't need a motion - they use the selection\n if ((this.state.mode === Mode.VISUAL || this.state.mode === Mode.VISUAL_LINE || this.state.mode === Mode.VISUAL_BLOCK) && pos === input.length) {\n return { command: cmd, context, isComplete: true };\n }\n\n // 8. Need more input for motion or text object\n if (pos >= input.length) {\n return 'partial';\n }\n\n // 9. Try text object first: [ia] + textobject key\n if (cmd.acceptsTextObject) {\n const variant = input[pos];\n if (variant === 'i' || variant === 'a') {\n pos++;\n if (pos >= input.length) return 'partial';\n\n const toKey = input[pos] ?? '';\n const textObject = this.textObjects.get(toKey);\n if (textObject) {\n context.textObject = textObject;\n context.variant = variant === 'i' ? 'inner' : 'outer';\n pos++;\n return { command: cmd, context, isComplete: true };\n }\n }\n }\n\n // 10. Try motion\n if (cmd.acceptsMotion) {\n // Reset pos if we tried text object and failed\n const motionStart = context.textObject ? pos : pos;\n let remaining = input.slice(motionStart);\n\n // Parse optional count before the motion (for things like d2w)\n const motionCountMatch = remaining.match(/^([1-9][0-9]*)/);\n if (motionCountMatch && motionCountMatch[1]) {\n // If operator already has a count, multiply them (2d3w = delete 6 words)\n const motionCount = parseInt(motionCountMatch[1], 10);\n context.count = context.count ? context.count * motionCount : motionCount;\n remaining = remaining.slice(motionCountMatch[0].length);\n }\n\n for (const [motionKey, motion] of this.motions) {\n if (remaining === motionKey) {\n // Motion key matches, check if it needs a following character\n if (motion.needsFollowingChar) {\n // Calculate current position in keyBuffer\n let keyIndex = 0;\n let consumed = 0;\n const currentPos = motionStart + (input.slice(motionStart).length - remaining.length) + motionKey.length;\n while (keyIndex < keyBuffer.length && consumed < currentPos) {\n consumed += keyBuffer[keyIndex]!.length;\n keyIndex++;\n }\n\n // The next key is the character to capture\n if (keyIndex >= keyBuffer.length) return 'partial';\n const char = keyBuffer[keyIndex];\n if (char) context.char = char;\n }\n context.motion = motion;\n return { command: cmd, context, isComplete: true };\n }\n if (motionKey.startsWith(remaining)) {\n return 'partial';\n }\n }\n }\n return null;\n }\n\n private playMacro(macroContent: string, count: number): void {\n // Set flag to prevent recording during macro playback\n const wasPlayingMacro = this.isPlayingMacro;\n this.isPlayingMacro = true;\n\n try {\n // Play the macro 'count' times\n for (let i = 0; i < count; i++) {\n // Process the macro as a fresh key sequence\n // We need to simulate typing each character\n const savedKeyBuffer = this.keyBuffer;\n this.keyBuffer = [];\n\n let j = 0;\n while (j < macroContent.length) {\n let key: string;\n\n // Check for multi-character keys like <C-a>, <Esc>, etc.\n if (macroContent[j] === '<') {\n const closeIdx = macroContent.indexOf('>', j);\n if (closeIdx !== -1) {\n key = macroContent.slice(j, closeIdx + 1);\n j = closeIdx + 1;\n } else {\n key = macroContent[j]!;\n j++;\n }\n } else {\n key = macroContent[j]!;\n j++;\n }\n\n // Process this key through the normal pipeline\n this.keyBuffer.push(key);\n const input = this.keyBuffer.join('');\n const result = this.match(input, this.keyBuffer);\n\n if (result && result !== 'partial' && result.isComplete) {\n // Command matched and complete, execute it\n result.context.registerManager = this.registerManager;\n result.context.indentationManager = this.indentationManager;\n this.state = result.command.execute(this.state, result.context);\n this.keyBuffer = [];\n } else if (result === null) {\n // No match, reset\n this.keyBuffer = [];\n }\n // else partial match, continue buffering\n }\n\n // Restore key buffer\n this.keyBuffer = savedKeyBuffer;\n }\n } finally {\n // Always reset the flag\n this.isPlayingMacro = wasPlayingMacro;\n }\n }\n\n // Registration helpers\n addMotion(motion: Motion): void {\n this.motions.set(motion.key, motion);\n }\n\n addTextObject(textObject: TextObject): void {\n this.textObjects.set(textObject.key, textObject);\n }\n\n addCommand(mode: Mode, command: Command): void {\n const cmds = this.commands.get(mode) ?? [];\n cmds.push(command);\n this.commands.set(mode, cmds);\n }\n\n loadStandardVimCommands(): void {\n // Helper to add motion to both NORMAL and all visual modes\n const addMotionAllModes = (motion: Motion) => {\n this.addMotion(motion);\n this.addCommand(Mode.VISUAL, motion);\n this.addCommand(Mode.VISUAL_LINE, motion);\n this.addCommand(Mode.VISUAL_BLOCK, motion);\n };\n\n // Word motions\n addMotionAllModes(new w());\n addMotionAllModes(new e());\n addMotionAllModes(new b());\n addMotionAllModes(new W());\n addMotionAllModes(new E());\n addMotionAllModes(new B());\n\n // Basic motions\n addMotionAllModes(new h());\n addMotionAllModes(new Backspace());\n addMotionAllModes(new ArrowLeft());\n\n addMotionAllModes(new l());\n addMotionAllModes(new ArrowRight());\n\n addMotionAllModes(new j());\n addMotionAllModes(new ArrowDown());\n addMotionAllModes(new Enter());\n\n addMotionAllModes(new k());\n addMotionAllModes(new ArrowUp());\n\n addMotionAllModes(new G());\n addMotionAllModes(new gg());\n\n // Line motions\n addMotionAllModes(new zero());\n\n addMotionAllModes(new dollar());\n addMotionAllModes(new End());\n\n addMotionAllModes(new caret());\n\n // Screen motions (must be before Home to avoid partial match conflict)\n addMotionAllModes(new H());\n addMotionAllModes(new M());\n addMotionAllModes(new L());\n\n addMotionAllModes(new Home());\n\n //Find motions\n addMotionAllModes(new t());\n addMotionAllModes(new T());\n addMotionAllModes(new f());\n addMotionAllModes(new F());\n\n // Extended motions\n addMotionAllModes(new MatchPercent());\n addMotionAllModes(new ge());\n addMotionAllModes(new gE());\n addMotionAllModes(new LastNonBlank());\n addMotionAllModes(new MiddleOfScreenLine());\n addMotionAllModes(new MiddleOfLine());\n addMotionAllModes(new Column());\n\n // Search motions\n addMotionAllModes(new Star());\n addMotionAllModes(new Hash());\n addMotionAllModes(new gStar());\n addMotionAllModes(new gHash());\n addMotionAllModes(new n());\n addMotionAllModes(new N());\n\n // Paragraph and sentence motions\n addMotionAllModes(new OpenBrace());\n addMotionAllModes(new CloseBrace());\n addMotionAllModes(new OpenParen());\n addMotionAllModes(new CloseParen());\n\n // Delete, Change, Yank, Paste Operators\n this.addCommand(Mode.NORMAL, new d())\n this.addCommand(Mode.NORMAL, new dd())\n this.addCommand(Mode.NORMAL, new Delete())\n this.addCommand(Mode.NORMAL, new DeleteChar())\n this.addCommand(Mode.NORMAL, new DeleteCharBackward())\n this.addCommand(Mode.NORMAL, new ReplaceChar())\n this.addCommand(Mode.NORMAL, new Substitute())\n this.addCommand(Mode.NORMAL, new SubstituteLine())\n this.addCommand(Mode.NORMAL, new JoinLines())\n this.addCommand(Mode.NORMAL, new JoinLinesNoSpace())\n this.addCommand(Mode.NORMAL, new IncrementNumber())\n this.addCommand(Mode.NORMAL, new DecrementNumber())\n this.addCommand(Mode.NORMAL, new RecordMacro())\n this.addCommand(Mode.NORMAL, new PlayMacro())\n this.addCommand(Mode.NORMAL, new RepeatMacro())\n\n this.addCommand(Mode.NORMAL, new y())\n this.addCommand(Mode.NORMAL, new yy())\n\n this.addCommand(Mode.NORMAL, new c())\n this.addCommand(Mode.NORMAL, new cc())\n\n this.addCommand(Mode.NORMAL, new p())\n this.addCommand(Mode.NORMAL, new P())\n\n // Mode transition commands\n this.addCommand(Mode.NORMAL, new Colon());\n this.addCommand(Mode.NORMAL, new SearchForward());\n this.addCommand(Mode.NORMAL, new SearchBackward());\n this.addCommand(Mode.NORMAL, new InsertAtCursor());\n this.addCommand(Mode.NORMAL, new InsertAtLineStart());\n this.addCommand(Mode.NORMAL, new AppendAfterCursor());\n this.addCommand(Mode.NORMAL, new AppendAtLineEnd());\n this.addCommand(Mode.NORMAL, new OpenLineBelow());\n this.addCommand(Mode.NORMAL, new OpenLineAbove());\n\n // Scroll commands\n this.addCommand(Mode.NORMAL, new ScrollPageDown());\n this.addCommand(Mode.NORMAL, new ScrollPageUp());\n this.addCommand(Mode.NORMAL, new ScrollHalfPageDown());\n this.addCommand(Mode.NORMAL, new ScrollHalfPageUp());\n this.addCommand(Mode.NORMAL, new ScrollLineDown());\n this.addCommand(Mode.NORMAL, new ScrollLineUp());\n this.addCommand(Mode.NORMAL, new ScrollCursorCenter());\n this.addCommand(Mode.NORMAL, new ScrollCursorTop());\n this.addCommand(Mode.NORMAL, new ScrollCursorBottom());\n\n // Visual mode commands\n this.addCommand(Mode.NORMAL, new VisualChar());\n this.addCommand(Mode.NORMAL, new VisualLine());\n this.addCommand(Mode.NORMAL, new VisualBlock());\n this.addCommand(Mode.NORMAL, new ReselectVisual());\n\n // Visual mode toggles (v, V, <C-v> in visual mode toggles back to normal)\n this.addCommand(Mode.VISUAL, new VisualChar());\n this.addCommand(Mode.VISUAL, new VisualLine());\n this.addCommand(Mode.VISUAL, new VisualBlock());\n this.addCommand(Mode.VISUAL_LINE, new VisualChar());\n this.addCommand(Mode.VISUAL_LINE, new VisualLine());\n this.addCommand(Mode.VISUAL_LINE, new VisualBlock());\n this.addCommand(Mode.VISUAL_BLOCK, new VisualChar());\n this.addCommand(Mode.VISUAL_BLOCK, new VisualLine());\n this.addCommand(Mode.VISUAL_BLOCK, new VisualBlock());\n\n // Visual mode specific commands\n this.addCommand(Mode.VISUAL, new ExitVisual());\n this.addCommand(Mode.VISUAL_LINE, new ExitVisual());\n this.addCommand(Mode.VISUAL_BLOCK, new ExitVisual());\n this.addCommand(Mode.VISUAL, new MoveToOtherEnd());\n this.addCommand(Mode.VISUAL_LINE, new MoveToOtherEnd());\n this.addCommand(Mode.VISUAL_BLOCK, new MoveToOtherEnd());\n this.addCommand(Mode.VISUAL_BLOCK, new MoveToOtherCorner());\n\n // Operators work in visual modes\n this.addCommand(Mode.VISUAL, new d());\n this.addCommand(Mode.VISUAL_LINE, new d());\n this.addCommand(Mode.VISUAL_BLOCK, new d());\n this.addCommand(Mode.VISUAL, new y());\n this.addCommand(Mode.VISUAL_LINE, new y());\n this.addCommand(Mode.VISUAL_BLOCK, new y());\n this.addCommand(Mode.VISUAL, new c());\n this.addCommand(Mode.VISUAL_LINE, new c());\n this.addCommand(Mode.VISUAL_BLOCK, new c());\n\n // Case operators in visual modes\n this.addCommand(Mode.VISUAL, new VisualToggleCase());\n this.addCommand(Mode.VISUAL_LINE, new VisualToggleCase());\n this.addCommand(Mode.VISUAL_BLOCK, new VisualToggleCase());\n this.addCommand(Mode.VISUAL, new VisualUppercase());\n this.addCommand(Mode.VISUAL_LINE, new VisualUppercase());\n this.addCommand(Mode.VISUAL_BLOCK, new VisualUppercase());\n this.addCommand(Mode.VISUAL, new VisualLowercase());\n this.addCommand(Mode.VISUAL_LINE, new VisualLowercase());\n this.addCommand(Mode.VISUAL_BLOCK, new VisualLowercase());\n\n // Case operators in normal mode\n this.addCommand(Mode.NORMAL, new ToggleCase());\n this.addCommand(Mode.NORMAL, new Lowercase());\n this.addCommand(Mode.NORMAL, new Uppercase());\n this.addCommand(Mode.NORMAL, new ToggleCaseOperator());\n this.addCommand(Mode.NORMAL, new LowercaseLine());\n this.addCommand(Mode.NORMAL, new UppercaseLine());\n this.addCommand(Mode.NORMAL, new ToggleCaseLine());\n\n // Miscellaneous commands\n this.addCommand(Mode.NORMAL, new ShowASCII());\n this.addCommand(Mode.NORMAL, new ShowUTF8());\n\n // Visual number operations\n this.addCommand(Mode.VISUAL, new IncrementNumbersVisual());\n this.addCommand(Mode.VISUAL_LINE, new IncrementNumbersVisual());\n this.addCommand(Mode.VISUAL_BLOCK, new IncrementNumbersVisual());\n this.addCommand(Mode.VISUAL, new DecrementNumbersVisual());\n this.addCommand(Mode.VISUAL_LINE, new DecrementNumbersVisual());\n this.addCommand(Mode.VISUAL_BLOCK, new DecrementNumbersVisual());\n\n // Indent/outdent operators in normal mode (register >> and << before > and <)\n this.addCommand(Mode.NORMAL, new ShiftRightLine());\n this.addCommand(Mode.NORMAL, new ShiftLeftLine());\n this.addCommand(Mode.NORMAL, new ShiftRight());\n this.addCommand(Mode.NORMAL, new ShiftLeft());\n\n // Indent/outdent operators in visual modes\n this.addCommand(Mode.VISUAL, new ShiftRight());\n this.addCommand(Mode.VISUAL_LINE, new ShiftRight());\n this.addCommand(Mode.VISUAL_BLOCK, new ShiftRight());\n this.addCommand(Mode.VISUAL, new ShiftLeft());\n this.addCommand(Mode.VISUAL_LINE, new ShiftLeft());\n this.addCommand(Mode.VISUAL_BLOCK, new ShiftLeft());\n\n // Fold commands in normal mode\n this.addCommand(Mode.NORMAL, new CreateFold());\n this.addCommand(Mode.NORMAL, new DeleteFold());\n this.addCommand(Mode.NORMAL, new DeleteFoldsRecursive());\n this.addCommand(Mode.NORMAL, new OpenFold());\n this.addCommand(Mode.NORMAL, new OpenFoldsRecursive());\n this.addCommand(Mode.NORMAL, new CloseFold());\n this.addCommand(Mode.NORMAL, new CloseFoldsRecursive());\n this.addCommand(Mode.NORMAL, new ToggleFold());\n this.addCommand(Mode.NORMAL, new ToggleFoldsRecursive());\n this.addCommand(Mode.NORMAL, new OpenAllFolds());\n this.addCommand(Mode.NORMAL, new CloseAllFolds());\n this.addCommand(Mode.NORMAL, new ReduceFolding());\n this.addCommand(Mode.NORMAL, new MoreFolding());\n this.addCommand(Mode.NORMAL, new ViewCursorLine());\n this.addCommand(Mode.NORMAL, new NextFold());\n this.addCommand(Mode.NORMAL, new PrevFold());\n\n // Fold creation in visual modes\n this.addCommand(Mode.VISUAL, new CreateFold());\n this.addCommand(Mode.VISUAL_LINE, new CreateFold());\n this.addCommand(Mode.VISUAL_BLOCK, new CreateFold());\n\n // Mark commands in normal mode\n this.addCommand(Mode.NORMAL, new SetMark());\n this.addCommand(Mode.NORMAL, new JumpToMarkLine());\n this.addCommand(Mode.NORMAL, new JumpToMarkExact());\n\n // Jump list navigation\n this.addCommand(Mode.NORMAL, new JumpBackward());\n this.addCommand(Mode.NORMAL, new JumpForward());\n\n // File commands\n this.addCommand(Mode.NORMAL, new WriteAndQuit());\n this.addCommand(Mode.NORMAL, new QuitWithoutSaving());\n this.addCommand(Mode.NORMAL, new ShowFileInfo());\n this.addCommand(Mode.NORMAL, new GotoFile());\n\n // Window commands\n this.addCommand(Mode.NORMAL, new SplitHorizontal());\n this.addCommand(Mode.NORMAL, new SplitVertical());\n this.addCommand(Mode.NORMAL, new CloseWindow());\n this.addCommand(Mode.NORMAL, new CloseOtherWindows());\n this.addCommand(Mode.NORMAL, new CycleWindow());\n this.addCommand(Mode.NORMAL, new MoveWindowLeft());\n this.addCommand(Mode.NORMAL, new MoveWindowDown());\n this.addCommand(Mode.NORMAL, new MoveWindowUp());\n this.addCommand(Mode.NORMAL, new MoveWindowRight());\n this.addCommand(Mode.NORMAL, new WindowIncreaseHeight());\n this.addCommand(Mode.NORMAL, new WindowDecreaseHeight());\n this.addCommand(Mode.NORMAL, new WindowIncreaseWidth());\n this.addCommand(Mode.NORMAL, new WindowDecreaseWidth());\n this.addCommand(Mode.NORMAL, new EqualizeWindows());\n this.addCommand(Mode.NORMAL, new WindowRotateDown());\n this.addCommand(Mode.NORMAL, new WindowRotateUp());\n this.addCommand(Mode.NORMAL, new WindowExchange());\n this.addCommand(Mode.NORMAL, new WindowMoveToTop());\n this.addCommand(Mode.NORMAL, new WindowMoveToBottom());\n this.addCommand(Mode.NORMAL, new WindowMoveToLeftmost());\n this.addCommand(Mode.NORMAL, new WindowMoveToRightmost());\n\n // Allow colon in visual modes as well\n this.addCommand(Mode.VISUAL, new Colon());\n this.addCommand(Mode.VISUAL_LINE, new Colon());\n this.addCommand(Mode.VISUAL_BLOCK, new Colon());\n\n // Register text objects\n this.addTextObject(new WordTextObject()); // iw, aw\n this.addTextObject(new InnerWORD()); // iW\n this.addTextObject(new AroundWORD()); // aW\n this.addTextObject(new ParagraphTextObject()); // ip, ap\n }\n\n}\n","// Dynamic pattern definitions that expand to regex at match time\nexport class PatternRegistry {\n private patterns: Map<string, () => string> = new Map();\n\n // Register a dynamic pattern (e.g., 'motion' -> regex matching all motion keys)\n register(name: string, regexProvider: () => string) {\n this.patterns.set(name, regexProvider);\n }\n\n // Expand pattern string like 'd%motion%' to a RegExp\n expand(pattern: string): RegExp {\n let expanded = this.escapeRegex(pattern);\n for (const [name, provider] of this.patterns) {\n const placeholder = this.escapeRegex(`%${name}%`);\n expanded = expanded.replace(new RegExp(placeholder, 'g'), `(?<${name}>${provider()})`);\n }\n return new RegExp(`^${expanded}$`);\n }\n\n private escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n}"],"mappings":"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","names":["Mode","b","f","path","currentLine","currentLine","b","currentLine","lastLine","c","lineCount","currentLine","b","key","currentLine","currentLine","currentLine","currentLine","isOnWord","currentLine","lines","line","currentLine","c","currentLine","currentLine","lines","lineStart","lineEnd","currentLine","c","currentLine","b","f","currentLine","keyIndex","j"]}
|