Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
6.3 kB · 199 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200/** * Vim Mode State Machine Types * * This file defines the complete state machine for vim input handling. * The types ARE the documentation - reading them tells you how the system works. * * State Diagram: * ``` * VimState * ┌──────────────────────────────┬──────────────────────────────────────┐ * │ INSERT │ NORMAL │ * │ (tracks insertedText) │ (CommandState machine) │ * │ │ │ * │ │ idle ──┬─[d/c/y]──► operator │ * │ │ ├─[1-9]────► count │ * │ │ ├─[fFtT]───► find │ * │ │ ├─[g]──────► g │ * │ │ ├─[r]──────► replace │ * │ │ └─[><]─────► indent │ * │ │ │ * │ │ operator ─┬─[motion]──► execute │ * │ │ ├─[0-9]────► operatorCount│ * │ │ ├─[ia]─────► operatorTextObj * │ │ └─[fFtT]───► operatorFind │ * └──────────────────────────────┴──────────────────────────────────────┘ * ``` */
// ============================================================================// Core Types// ============================================================================
export type Operator = 'delete' | 'change' | 'yank'
export type FindType = 'f' | 'F' | 't' | 'T'
export type TextObjScope = 'inner' | 'around'
// ============================================================================// State Machine Types// ============================================================================
/** * Complete vim state. Mode determines what data is tracked. * * INSERT mode: Track text being typed (for dot-repeat) * NORMAL mode: Track command being parsed (state machine) */export type VimState = | { mode: 'INSERT'; insertedText: string } | { mode: 'NORMAL'; command: CommandState }
/** * Command state machine for NORMAL mode. * * Each state knows exactly what input it's waiting for. * TypeScript ensures exhaustive handling in switches. */export type CommandState = | { type: 'idle' } | { type: 'count'; digits: string } | { type: 'operator'; op: Operator; count: number } | { type: 'operatorCount'; op: Operator; count: number; digits: string } | { type: 'operatorFind'; op: Operator; count: number; find: FindType } | { type: 'operatorTextObj' op: Operator count: number scope: TextObjScope } | { type: 'find'; find: FindType; count: number } | { type: 'g'; count: number } | { type: 'operatorG'; op: Operator; count: number } | { type: 'replace'; count: number } | { type: 'indent'; dir: '>' | '<'; count: number }
/** * Persistent state that survives across commands. * This is the "memory" of vim - what gets recalled for repeats and pastes. */export type PersistentState = { lastChange: RecordedChange | null lastFind: { type: FindType; char: string } | null register: string registerIsLinewise: boolean}
/** * Recorded change for dot-repeat. * Captures everything needed to replay a command. */export type RecordedChange = | { type: 'insert'; text: string } | { type: 'operator' op: Operator motion: string count: number } | { type: 'operatorTextObj' op: Operator objType: string scope: TextObjScope count: number } | { type: 'operatorFind' op: Operator find: FindType char: string count: number } | { type: 'replace'; char: string; count: number } | { type: 'x'; count: number } | { type: 'toggleCase'; count: number } | { type: 'indent'; dir: '>' | '<'; count: number } | { type: 'openLine'; direction: 'above' | 'below' } | { type: 'join'; count: number }
// ============================================================================// Key Groups - Named constants, no magic strings// ============================================================================
export const OPERATORS = { d: 'delete', c: 'change', y: 'yank',} as const satisfies Record<string, Operator>
export function isOperatorKey(key: string): key is keyof typeof OPERATORS { return key in OPERATORS}
export const SIMPLE_MOTIONS = new Set([ 'h', 'l', 'j', 'k', // Basic movement 'w', 'b', 'e', 'W', 'B', 'E', // Word motions '0', '^', '$', // Line positions])
export const FIND_KEYS = new Set(['f', 'F', 't', 'T'])
export const TEXT_OBJ_SCOPES = { i: 'inner', a: 'around',} as const satisfies Record<string, TextObjScope>
export function isTextObjScopeKey( key: string,): key is keyof typeof TEXT_OBJ_SCOPES { return key in TEXT_OBJ_SCOPES}
export const TEXT_OBJ_TYPES = new Set([ 'w', 'W', // Word/WORD '"', "'", '`', // Quotes '(', ')', 'b', // Parens '[', ']', // Brackets '{', '}', 'B', // Braces '<', '>', // Angle brackets])
export const MAX_VIM_COUNT = 10000
// ============================================================================// State Factories// ============================================================================
export function createInitialVimState(): VimState { return { mode: 'INSERT', insertedText: '' }}
export function createInitialPersistentState(): PersistentState { return { lastChange: null, lastFind: null, register: '', registerIsLinewise: false, }}