From d135526386a11106e4f483b29277ec989b5394c8 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Tue, 2 Sep 2025 12:33:02 +0100 Subject: [PATCH] refactoring, and fix bug in 'y^' motion. (When cursor is after first-non-space-character, copy from first-non-space-character to cursor. Otherwise, copy spaces at beginning until first-non-space-character.) --- fcore/normal-mode/normal-mode.sml | 88 +++++++++++++++---------------- fcore/normal-mode/normal-yank.sml | 87 ++++++++++++++++++++++++++++++ shf.mlb | 1 + 3 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 fcore/normal-mode/normal-yank.sml diff --git a/fcore/normal-mode/normal-mode.sml b/fcore/normal-mode/normal-mode.sml index ec71bec..8642b50 100644 --- a/fcore/normal-mode/normal-mode.sml +++ b/fcore/normal-mode/normal-mode.sml @@ -241,40 +241,21 @@ struct fun parseYankTerminal (str, count, app, chrCmd, time) = case chrCmd of - #"y" => - let - open DrawMsg - open MailboxType - - val {buffer, cursorIdx, ...} = app - - val buffer = LineGap.goToIdx (cursorIdx, buffer) - val low = Cursor.vi0 (buffer, cursorIdx) - - val buffer = LineGap.goToIdx (low, buffer) - val high = Cursor.viDlrForDelete (buffer, low, 1) - - val buffer = LineGap.goToIdx (high, buffer) - val length = high - low - val str = LineGap.substring (low, length, buffer) - - val msg = YANK str - val mode = NORMAL_MODE "" - in - NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) - end - | #"0" => - let val f = fn (buffer, cursorIdx, _) => Cursor.vi0 (buffer, cursorIdx) - in yankWhenMovingBack (app, f, 1) - end - | #"w" => yankWhenMovingForward (app, Cursor.nextWord, count) - | #"W" => yankWhenMovingForward (app, Cursor.nextWORD, count) - | #"b" => yankWhenMovingBack (app, Cursor.prevWord, count) - | #"B" => yankWhenMovingBack (app, Cursor.prevWORD, count) - | #"e" => yankWhenMovingForward (app, Cursor.endOfWordForDelete, count) - | #"E" => yankWhenMovingForward (app, Cursor.endOfWORDForDelete, count) - - | #"$" => yankWhenMovingForward (app, Cursor.viDlr, 1) + (* motions like yh / yj / yk / yl are not really needed. + * Vim supports them, but I never use them. + * I also don't need yx (yank a character and then remove it) + * because I never do that. *) + #"y" => NormalYank.yankLine (app, count) + | #"0" => NormalYank.yankToStartOfLine app + | #"w" => NormalYank.yankWhenMovingForward (app, Cursor.nextWord, count) + | #"W" => NormalYank.yankWhenMovingForward (app, Cursor.nextWORD, count) + | #"b" => NormalYank.yankWhenMovingBack (app, Cursor.prevWord, count) + | #"B" => NormalYank.yankWhenMovingBack (app, Cursor.prevWORD, count) + | #"e" => + NormalYank.yankWhenMovingForward (app, Cursor.endOfWordForDelete, count) + | #"E" => + NormalYank.yankWhenMovingForward (app, Cursor.endOfWORDForDelete, count) + | #"$" => NormalYank.yankWhenMovingForward (app, Cursor.viDlr, 1) | #"^" => let open DrawMsg @@ -283,19 +264,36 @@ struct val {buffer, cursorIdx, ...} = app val buffer = LineGap.goToIdx (cursorIdx, buffer) - val low = Cursor.vi0 (buffer, cursorIdx) + val otherIdx = Cursor.vi0 (buffer, cursorIdx) - val buffer = LineGap.goToIdx (low, buffer) - val high = Cursor.firstNonSpaceChr (buffer, low) - - val buffer = LineGap.goToIdx (high, buffer) - val length = high - low - val str = LineGap.substring (low, length, buffer) - - val msg = YANK str - val mode = NORMAL_MODE "" + val buffer = LineGap.goToIdx (otherIdx, buffer) + val otherIdx = Cursor.firstNonSpaceChr (buffer, otherIdx) in - NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + if cursorIdx > otherIdx then + (* yanking backwards from cursorIdx *) + let + val () = print "272\n" + val length = cursorIdx - otherIdx + 1 + val buffer = LineGap.goToIdx (otherIdx, buffer) + + val str = LineGap.substring (otherIdx, length, buffer) + val msg = YANK str + val mode = NORMAL_MODE "" + in + NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + end + else if cursorIdx < otherIdx then + (* yanking forward from cursorIdx *) + let + val length = otherIdx - cursorIdx + val str = LineGap.substring (cursorIdx, length, buffer) + val msg = YANK str + val mode = NORMAL_MODE "" + in + NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + end + else + NormalFinish.clearMode app end | #"G" => let diff --git a/fcore/normal-mode/normal-yank.sml b/fcore/normal-mode/normal-yank.sml new file mode 100644 index 0000000..3b3b65e --- /dev/null +++ b/fcore/normal-mode/normal-yank.sml @@ -0,0 +1,87 @@ +structure NormalYank = +struct + open AppType + open DrawMsg + open MailboxType + + fun yankLine (app: app_type, count) = + let + open DrawMsg + open MailboxType + + val {buffer, cursorIdx, ...} = app + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val low = Cursor.vi0 (buffer, cursorIdx) + + val buffer = LineGap.goToIdx (low, buffer) + val high = Cursor.viDlrForDelete (buffer, low, count) + + val buffer = LineGap.goToIdx (high, buffer) + val length = high - low + val str = LineGap.substring (low, length, buffer) + + val msg = YANK str + val mode = NORMAL_MODE "" + in + NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + end + + fun yankToStartOfLine (app: app_type) = + let + open DrawMsg + open MailboxType + + val {buffer, cursorIdx, ...} = app + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val low = Cursor.vi0 (buffer, cursorIdx) + + val length = cursorIdx - low + val str = LineGap.substring (low, length, buffer) + + val msg = YANK str + val mode = NORMAL_MODE "" + in + NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + end + + fun yankWhenMovingBack (app: app_type, fMove, count) = + let + open DrawMsg + open MailboxType + + val {buffer, cursorIdx, ...} = app + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val low = fMove (buffer, cursorIdx, count) + + val length = cursorIdx - low + val str = LineGap.substring (low, length, buffer) + + val msg = YANK str + val mode = NORMAL_MODE "" + in + NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + end + + fun yankWhenMovingForward (app: app_type, fMove, count) = + let + open DrawMsg + open MailboxType + + val {buffer, cursorIdx, ...} = app + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val high = fMove (buffer, cursorIdx, count) + + val buffer = LineGap.goToIdx (high, buffer) + val length = high - cursorIdx + val str = LineGap.substring (cursorIdx, length, buffer) + + val msg = YANK str + val mode = NORMAL_MODE "" + in + NormalModeWith.modeAndBuffer (app, buffer, mode, [DRAW msg]) + end +end diff --git a/shf.mlb b/shf.mlb index 7c5e51a..52d7419 100644 --- a/shf.mlb +++ b/shf.mlb @@ -45,6 +45,7 @@ fcore/normal-mode/normal-search-finish.sml fcore/move.sml fcore/normal-mode/normal-move.sml +fcore/normal-mode/normal-yank.sml fcore/normal-mode/normal-delete.sml fcore/normal-mode/normal-mode.sml fcore/normal-mode/normal-search-mode.sml