Getting vim motion architecture started. deleteWord added. Changing deleteLine to use it.

This commit is contained in:
Dustin Swan 2026-03-18 19:29:53 -06:00
parent 78fa27f70a
commit a3b815b449
No known key found for this signature in database
GPG key ID: 30D46587E2100467
2 changed files with 60 additions and 17 deletions

View file

@ -31,6 +31,59 @@ textEditor = name \
state.{ cursorRow = newRow2, cursorCol = newCol2 }; state.{ cursorRow = newRow2, cursorCol = newCol2 };
charKind = ch \
ch == " " | True \ Space
| False \ (isWordChar ch
| True \ Word
| False \ Punct);
skipWhile = pred lines row col \
line = nth row lines ~ unwrapOr "";
col >= len line
| True \ (row + 1 < len lines
| True \ skipWhile pred lines (row + 1) 0
| False \ { row = row, col = col })
| False \ (pred (nth col line ~ unwrapOr "")
| True \ skipWhile pred lines row (col + 1)
| False \ { row = row, col = col });
nextWordStart = lines row col \
line = nth row lines ~ unwrapOr "";
kind = charKind (nth col line ~ unwrapOr " ");
pos = skipWhile (ch \ charKind ch == kind) lines row col;
skipWhile (ch \ ch == " ") lines pos.row pos.col;
resolveMotion = motion state \
from = { row = state.cursorRow, col = state.cursorCol };
to = motion
| Word \ nextWordStart state.lines from.row from.col
| WholeLine \ from;
{ from = from, to = to };
deleteLine = state \
newLines = [...(take (state.cursorRow) state.lines), ...(drop (state.cursorRow + 1) state.lines)];
{ state = state.{ lines = newLines, emit = [] } };
deleteRange = state from to \
line = nth from.row state.lines ~ unwrapOr "";
toCol = to.row > from.row
| True \ len line
| False \ to.col;
newLine = (slice line 0 from.col) & (slice line toCol (len line));
state.{ lines = updateAt from.row (_ \ newLine) state.lines, cursorCol = from.col };
applyOperator = operator motion state \
target = resolveMotion motion state;
stateSnapshot = { lines = state.lines, cursorRow = state.cursorRow, cursorCol = state.cursorCol };
newState = operator
| Delete \ (motion
| WholeLine \ deleteLine state
| _ \ { state = deleteRange state target.from target.to, emit = [] });
{ state = clampCursor newState.state.{ undoStack = [stateSnapshot, ...state.undoStack], pending = None }, emit = newState.emit };
moveCursor = motion state \
state.{ cursorCol = motion.to.col, cursorRow = motion.to.row };
write = state \ write = state \
content = join "\n" state.lines; content = join "\n" state.lines;
{ state = state, emit = [rebindAt [buffersKey, name] content] }; { state = state, emit = [rebindAt [buffersKey, name] content] };
@ -82,19 +135,6 @@ textEditor = name \
emit = [] emit = []
}; };
deleteLine = state \
stateSnapshot = { lines = state.lines, cursorRow = state.cursorRow, cursorCol = state.cursorCol };
newUndoStack = [stateSnapshot, ...state.undoStack];
newLines = [...(take (state.cursorRow) state.lines), ...(drop (state.cursorRow + 1) state.lines)];
{
state = clampCursor state.{
lines = newLines,
undoStack = newUndoStack,
pending = None
},
emit = []
};
escape = state \ { state = state.{ mode = Normal }, emit = [] }; escape = state \ { state = state.{ mode = Normal }, emit = [] };
undo = state \ state.undoStack undo = state \ state.undoStack
@ -233,10 +273,13 @@ textEditor = name \
| Key { key = "d", ctrl = True } \ scrollHalfDown state ctx | Key { key = "d", ctrl = True } \ scrollHalfDown state ctx
| Key { key = "u", ctrl = True } \ scrollHalfUp state ctx | Key { key = "u", ctrl = True } \ scrollHalfUp state ctx
| Key { key = "u" } \ undo state | Key { key = "u" } \ undo state
| Key { key = "d" } \ (state.pending
| Some "d" \ deleteLine state
| _ \ { state = state.{ pending = Some "d" }, emit = [] })
| Key { key = "r", ctrl = True } \ redo state | Key { key = "r", ctrl = True } \ redo state
| Key { key = "d" } \ (state.pending
| Some Delete \ applyOperator Delete WholeLine state
| _ \ { state = state.{ pending = Some Delete }, emit = [] })
| Key { key = "w" } \ (state.pending
| None \ withScroll { state = moveCursor (resolveMotion Word state) state, emit = [] }
| Some Delete \ withScroll (applyOperator Delete Word state))
| Key { key = "W", ctrl = True, shift = True } \ write state | Key { key = "W", ctrl = True, shift = True } \ write state
| Key { key = "A", ctrl = True, shift = True } \ apply state | Key { key = "A", ctrl = True, shift = True } \ apply state
# any other key or event # any other key or event

View file

@ -107,7 +107,7 @@ os =
ui.rect { w = titleBarHeight, h = titleBarHeight, color = "rgba(255,255,255,0.2)" }, ui.rect { w = titleBarHeight, h = titleBarHeight, color = "rgba(255,255,255,0.2)" },
# button text # button text
ui.positioned { ui.positioned {
x = 10, y = 5, child = text "x" x = 12, y = 5, child = text "x"
} }
] ]
} }