From c080b913aef5eb5e149419745ccdddcee1ca25dc Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 8 Nov 2024 18:36:02 +0000 Subject: [PATCH] reorganisation app-update.sml to place related functions close together --- fcore/app-update.sml | 212 ++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 115 deletions(-) diff --git a/fcore/app-update.sml b/fcore/app-update.sml index 4c6344f..2ffce8c 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -72,6 +72,8 @@ struct (newApp, drawMsg) end + (* movement functions *) + fun moveToStart (app: app_type) = let val {buffer, windowWidth, windowHeight, ...} = app @@ -226,7 +228,64 @@ struct buildTextAndClear (app, buffer, cursorIdx) end - (* equivalent of vi's 'x' command *) + fun helpMoveToChr (app: app_type, buffer, cursorIdx, count, fMove, chr) = + if count = 0 then + let + val {windowWidth, windowHeight, startLine, ...} = app + + (* move LineGap to first line displayed on screen *) + val buffer = LineGap.goToLine (startLine, buffer) + + (* get new startLine which may move screen depending on cursor movements *) + val startLine = TextWindow.getStartLine + (buffer, startLine, cursorIdx, windowWidth, windowHeight) + + (* move buffer to new startLine as required by TextBuilder.build *) + val buffer = LineGap.goToLine (startLine, buffer) + + val drawMsg = + TextBuilder.build + (startLine, cursorIdx, buffer, windowWidth, windowHeight) + + val mode = NORMAL_MODE "" + val newApp = AppWith.bufferAndCursorIdx + (app, buffer, cursorIdx, mode, startLine) + in + (newApp, drawMsg) + end + else + let + (* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *) + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val cursorIdx = fMove (buffer, cursorIdx, chr) + in + helpMoveToChr (app, buffer, cursorIdx, count - 1, fMove, chr) + end + + fun moveToChr (app: app_type, count, fMove, chr) = + let val {cursorIdx, buffer, ...} = app + in helpMoveToChr (app, buffer, cursorIdx, count, fMove, chr) + end + + fun handleMoveToChr (count, app, fMove, newCmd) = + case newCmd of + CHAR_EVENT chr => moveToChr (app, count, fMove, chr) + | KEY_ESC => clearMode app + | RESIZE_EVENT (width, height) => resizeText (app, width, height) + + fun handleGo (count, app, newCmd) = + case newCmd of + CHAR_EVENT chr => + (case chr of + #"e" => move (app, count, Cursor.endOfPrevWord) + | #"E" => move (app, count, Cursor.endOfPrevWORD) + | #"g" => moveToStart app + | _ => clearMode app) + | KEY_ESC => clearMode app + | RESIZE_EVENT (width, height) => resizeText (app, width, height) + + (* text-delete functions *) + (** equivalent of vi's 'x' command **) fun helpRemoveChr (app: app_type, buffer, cursorIdx, count) = if count = 0 then buildTextAndClear (app, buffer, cursorIdx) @@ -279,7 +338,41 @@ struct fun removeChr (app: app_type, count) = helpRemoveChr (app, #buffer app, #cursorIdx app, count) - (* number of characters which are integers *) + fun helpDelete (app: app_type, buffer, cursorIdx, count, fMove) = + if count = 0 then + buildTextAndClear (app, buffer, cursorIdx) + else + let + (* get otherIdx, where cursor will want to go after motion. *) + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val otherIdx = fMove (buffer, cursorIdx) + + (* Because some motions like 'b' take us backwards, + * and some motions like 'w' take us forwards, + * we need to find out which idx is lower and higher + * for proper deletion and seeing where to set cursorIdx to *) + val low = Int.min (cursorIdx, otherIdx) + val high = Int.max (cursorIdx, otherIdx) + val length = high - low + + val buffer = LineGap.delete (low, length, buffer) + + (* todo: possibly decrement cursorIdx by 1 + * if deleting put cursorIdx past end of file. + * else, if deleting put cursorIdx before 0, + * ensure that it is clipped to 0. + * else, leave cursorIdx alone. + * *) + in + helpDelete (app, buffer, low, count - 1, fMove) + end + + fun delete (app: app_type, count, fMove) = + helpDelete (app, #buffer app, #cursorIdx app, count, fMove) + + + (* command-parsing functions *) + (** number of characters which are integers *) fun getNumLength (pos, str) = if pos = String.size str then pos @@ -370,116 +463,6 @@ struct (newApp, []) end - fun helpMoveToChr (app: app_type, buffer, cursorIdx, count, fMove, chr) = - if count = 0 then - let - val {windowWidth, windowHeight, startLine, ...} = app - - (* move LineGap to first line displayed on screen *) - val buffer = LineGap.goToLine (startLine, buffer) - - (* get new startLine which may move screen depending on cursor movements *) - val startLine = TextWindow.getStartLine - (buffer, startLine, cursorIdx, windowWidth, windowHeight) - - (* move buffer to new startLine as required by TextBuilder.build *) - val buffer = LineGap.goToLine (startLine, buffer) - - val drawMsg = - TextBuilder.build - (startLine, cursorIdx, buffer, windowWidth, windowHeight) - - val mode = NORMAL_MODE "" - val newApp = AppWith.bufferAndCursorIdx - (app, buffer, cursorIdx, mode, startLine) - in - (newApp, drawMsg) - end - else - let - (* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *) - val buffer = LineGap.goToIdx (cursorIdx, buffer) - val cursorIdx = fMove (buffer, cursorIdx, chr) - in - helpMoveToChr (app, buffer, cursorIdx, count - 1, fMove, chr) - end - - fun moveToChr (app: app_type, count, fMove, chr) = - let val {cursorIdx, buffer, ...} = app - in helpMoveToChr (app, buffer, cursorIdx, count, fMove, chr) - end - - fun handleMoveToChr (count, app, fMove, newCmd) = - case newCmd of - CHAR_EVENT chr => moveToChr (app, count, fMove, chr) - | KEY_ESC => clearMode app - | RESIZE_EVENT (width, height) => resizeText (app, width, height) - - fun handleGo (count, app, newCmd) = - case newCmd of - CHAR_EVENT chr => - (case chr of - #"e" => move (app, count, Cursor.endOfPrevWord) - | #"E" => move (app, count, Cursor.endOfPrevWORD) - | #"g" => moveToStart app - | _ => clearMode app) - | KEY_ESC => clearMode app - | RESIZE_EVENT (width, height) => resizeText (app, width, height) - - fun helpDelete (app: app_type, buffer, cursorIdx, count, fMove) = - if count = 0 then - let - val {windowWidth, windowHeight, startLine, ...} = app - - (* move LineGap to first line displayed on screen *) - val buffer = LineGap.goToLine (startLine, buffer) - - (* get new startLine which may move screen depending on cursor movements *) - val startLine = TextWindow.getStartLine - (buffer, startLine, cursorIdx, windowWidth, windowHeight) - - (* move buffer to new startLine as required by TextBuilder.build *) - val buffer = LineGap.goToLine (startLine, buffer) - - val drawMsg = - TextBuilder.build - (startLine, cursorIdx, buffer, windowWidth, windowHeight) - - val mode = NORMAL_MODE "" - val newApp = AppWith.bufferAndCursorIdx - (app, buffer, cursorIdx, mode, startLine) - in - (newApp, drawMsg) - end - else - let - (* get otherIdx, where cursor will want to go after motion. *) - val buffer = LineGap.goToIdx (cursorIdx, buffer) - val otherIdx = fMove (buffer, cursorIdx) - - (* Because some motions like 'b' take us backwards, - * and some motions like 'w' take us forwards, - * we need to find out which idx is lower and higher - * for proper deletion and seeing where to set cursorIdx to *) - val low = Int.min (cursorIdx, otherIdx) - val high = Int.max (cursorIdx, otherIdx) - val length = high - low - - val buffer = LineGap.delete (low, length, buffer) - - (* todo: possibly decrement cursorIdx by 1 - * if deleting put cursorIdx past end of file. - * else, if deleting put cursorIdx before 0, - * ensure that it is clipped to 0. - * else, leave cursorIdx alone. - * *) - in - helpDelete (app, buffer, low, count - 1, fMove) - end - - fun delete (app: app_type, count, fMove) = - helpDelete (app, #buffer app, #cursorIdx app, count, fMove) - fun parseDelete (strPos, str, count, app, newCmd) = if strPos = String.size str - 1 then (* have to check newCmd *) @@ -497,12 +480,12 @@ struct | #"B" => delete (app, count, Cursor.prevWORD) | #"e" => delete (app, count, Cursor.endOfWord) | #"E" => delete (app, count, Cursor.endOfWORD) - | #"0" => delete (app, count, Cursor.vi0) + | #"0" => delete (app, 1, Cursor.vi0) (* todo for '$': * Cursor.viDlr takes us to last chr on line * but it leaves last chr on line alone. * Have to increment by 1. *) - | #"$" => delete (app, count, Cursor.viDlr) + | #"$" => delete (app, 1, Cursor.viDlr) (* todo: requires custom delete function | #"^" => firstNonSpaceChr app *) @@ -524,7 +507,6 @@ struct (print "app-update.sml line 527 temp\n"; clearMode app) (* useful reference as list of non-terminal commands *) - (* todo: actually parse, checking if there are further strings or input *) fun parseAfterCount (strPos, str, count, app, newCmd) = (* we are trying to parse multi-char but non-terminal strings here. * For example, we don't want to parse 3w which is a terminal commmand