Getting vim motion architecture started. deleteWord added. Changing deleteLine to use it.
This commit is contained in:
parent
78fa27f70a
commit
a3b815b449
2 changed files with 60 additions and 17 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue