diff --git a/fcore/app-update.sml b/fcore/app-update.sml index 82d9af3..c01b996 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -363,9 +363,34 @@ struct (* text-delete functions *) (** equivalent of vi's 'x' command **) - fun helpRemoveChr (app: app_type, buffer, cursorIdx, count) = + fun helpRemoveChr (app: app_type, buffer, searchList, cursorIdx, count) = if count = 0 then - buildTextAndClear (app, buffer, cursorIdx) + let + val {windowWidth, windowHeight, startLine, searchString, ...} = + 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 + , searchList, searchString + ) + + val mode = NORMAL_MODE "" + val newApp = AppWith.onDelete + (app, buffer, cursorIdx, mode, startLine, searchList) + in + (newApp, drawMsg) + end else let val buffer = LineGap.goToIdx (cursorIdx, buffer) @@ -388,14 +413,17 @@ struct (* vi simply doesn't do anything on 'x' command * when cursor is at start of line, and next chr is line break * so skip to end of loop by passing count of 0 *) - helpRemoveChr (app, buffer, cursorIdx, 0) + helpRemoveChr (app, buffer, searchList, cursorIdx, 0) else if cursorIsStart then - helpRemoveChr (app, buffer, cursorIdx, 0) + helpRemoveChr (app, buffer, searchList, cursorIdx, 0) else if nextIsEnd then let (* delete char at cursor and then decrement cursorIdx by 1 * if cursorIdx is not 0 *) val buffer = LineGap.delete (cursorIdx, 1, buffer) + val searchList = SearchList.delete (cursorIdx, 1, searchList) + val searchList = SearchList.mapFrom (cursorIdx, ~1, searchList) + val cursorIdx = if Cursor.isPrevChrStartOfLine (buffer, cursorIdx) @@ -403,16 +431,20 @@ struct then cursorIdx else cursorIdx - 1 in - helpRemoveChr (app, buffer, cursorIdx, count - 1) + helpRemoveChr (app, buffer, searchList, cursorIdx, count - 1) end else - let val buffer = LineGap.delete (cursorIdx, 1, buffer) - in helpRemoveChr (app, buffer, cursorIdx, count - 1) + let + val buffer = LineGap.delete (cursorIdx, 1, buffer) + val searchList = SearchList.delete (cursorIdx, 1, searchList) + val searchList = SearchList.mapFrom (cursorIdx, ~1, searchList) + in + helpRemoveChr (app, buffer, searchList, cursorIdx, count - 1) end end fun removeChr (app: app_type, count) = - helpRemoveChr (app, #buffer app, #cursorIdx app, count) + helpRemoveChr (app, #buffer app, #searchList app, #cursorIdx app, count) fun helpDelete (app: app_type, buffer, cursorIdx, otherIdx, count, fMove) = (* As a small optimisation to reduce allocations, @@ -470,8 +502,10 @@ struct val lastChr = Cursor.viDlr (buffer, cursorIdx) val length = lastChr - cursorIdx val buffer = LineGap.delete (cursorIdx, length, buffer) + + (* todo: delete from searchList and map *) in - helpRemoveChr (app, buffer, cursorIdx, 1) + helpRemoveChr (app, buffer, #searchList app, cursorIdx, 1) end end diff --git a/fcore/app-with.sml b/fcore/app-with.sml index 841d6cc..19456d4 100644 --- a/fcore/app-with.sml +++ b/fcore/app-with.sml @@ -75,6 +75,31 @@ struct } end + fun onDelete + (app: app_type, newBuffer, newCursorIdx, newMode, newStartLine, newSearchList) = + let + val + { mode = _ + , buffer = _ + , cursorIdx = _ + , startLine = _ + , searchList = _ + , searchString + , windowWidth + , windowHeight + } = app + in + { mode = newMode + , buffer = newBuffer + , cursorIdx = newCursorIdx + , startLine = newStartLine + , searchList = newSearchList + , searchString = searchString + , windowWidth = windowWidth + , windowHeight = windowHeight + } + end + fun mode (app: app_type, newMode) = let val diff --git a/fcore/search-list.sml b/fcore/search-list.sml index b60bf72..8ba8c00 100644 --- a/fcore/search-list.sml +++ b/fcore/search-list.sml @@ -8,13 +8,26 @@ sig val delete: int * int * t -> t val goToNum: int * t -> t - val mapFromNum: int * int * t -> t + val mapFrom: int * int * t -> t end structure SearchList :> SEARCH_LIST = struct type t = {left: int vector list, right: int vector list} + (* temp function for testing *) + fun printlst (left, right) = + let + val left = List.rev left + val lst = List.concat [left, right] + val v = Vector.concat lst + val _ = print "\nstart print list:\n" + val _ = Vector.map (fn el => print (" " ^ Int.toString el ^ ",")) v + val _ = print "\nend print list\n" + in + () + end + val targetLength = 1024 val empty: t = {left = [], right = []} @@ -379,54 +392,25 @@ struct val rfirst = Vector.sub (rhd, 0) in if start < rfirst then - (case left of - lhd :: ltl => - let - val llast = Vector.sub (lhd, Vector.length lhd - 1) - in - if - start < llast - then - if finish < rfirst then - (* start < rfirst and start < llast and finish < rfirst - * move left and delete *) - moveLeftAndDelete (start, finish, left, right) - else - (* start < rfirst and start < llast and finish >= rfirst - * in middle; delete from both sides *) - delFromLeftAndRight (start, finish, left, right) - else if - start = llast - then - if finish < rfirst then - (* start < rfirst, start = llast, and finish < rfirst - * so just have to delete left from here *) - delLeftFromHere (start, left, right) - else - (* start < rfirst, start = llast, finish >= rfirst - * in middle; delete from both sides *) - delFromLeftAndRight (start, finish, left, right) - else (* start > llast and start < rfirst *) if - finish >= rfirst - then - (* delete right from here *) - delRightFromHere (finish, left, right) - else - (* start < rfirst and finish < rfirst - * so just return *) - {left = left, right = right} - end - | [] => - (* start < rfirst - * but left is empty. - * All we can do is 1. Delete right or 2. Return *) - if finish < rfirst then {left = left, right = right} - else delRightFromHere (finish, left, right)) + if finish < rfirst then + (case left of + lhd :: ltl => + let + val llast = Vector.sub (lhd, Vector.length lhd - 1) + in + if finish = llast then + delLeftFromHere (start, left, right) + else + moveLeftAndDelete (start, finish, left, right) + end + | [] => + {left = left, right = right}) + else + (* finish >= rfirst *) + delFromLeftAndRight (start, finish, left, right) else if start = rfirst then delRightFromHere (finish, left, right) - else - (* start > rfirst - * move right and then start deleting *) + else moveRightAndDelete (start, finish, left, right) end | [] => @@ -435,13 +419,11 @@ struct let val llast = Vector.sub (lhd, Vector.length lhd - 1) in - if start < llast then - if finish <= llast then - moveRightAndDelete (start, finish, left, right) - else - delLeftFromHere (finish, left, right) + if finish >= llast then + delLeftFromHere (start, left, right) else - moveRightAndDelete (start, finish, left, right) + (* finish < last *) + moveLeftAndDelete (start, finish, left, right) end | [] => (* left and right are both empty *) @@ -493,7 +475,7 @@ struct end | [] => {left = left, right = right} - fun mapFromNum (num, mapBy, lst) = + fun mapFrom (num, mapBy, lst) = let (* goToNum always places vector where num was found to the right list *) val {left, right} = goToNum (num, lst) diff --git a/shf b/shf index e9f370b..a071ec6 100755 Binary files a/shf and b/shf differ