diff --git a/fcore/app-update.sml b/fcore/app-update.sml index 94739cd..94687fd 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -84,6 +84,30 @@ struct (newApp, drawMsg) end + fun moveToLine (app: app_type, reqLine) = + let + val {windowWidth, windowHeight, buffer, startLine = origLine, ...} = app + val buffer = LineGap.goToLine (reqLine, buffer) + + (* get idx of first chr after linebreak *) + val cursorIdx = Cursor.getLineStartIdx (buffer, reqLine) + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val startLine = TextWindow.getStartLineWithCursorCentered + (buffer, cursorIdx, origLine, windowWidth, windowHeight div 2) + + val buffer = LineGap.goToLine (startLine, buffer) + + val newApp = AppWith.bufferAndCursorIdx + (app, buffer, cursorIdx, NORMAL_MODE "", startLine) + + val drawMsg = + TextBuilder.build + (startLine, cursorIdx, buffer, windowWidth, windowHeight) + in + (newApp, drawMsg) + end + fun helpMove (app: app_type, buffer, cursorIdx, count, fMove) = if count = 0 then let @@ -258,7 +282,10 @@ struct (* if str has a size larger than 0, * interpret as "go to line" command; * else, interpret as a command to move to end *) - moveToEnd app + if String.size str = 0 then + moveToEnd app + else + moveToLine (app, count) | #"%" => moveToMatchingPair app (* multi-char commands which can be appended *) | #"t" => appendChr (app, chr, str) diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 888e2be..42c423e 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -1703,4 +1703,43 @@ struct end | [] => cursorIdx end + + (* Prerequisite: move lineGap to reqLine *) + fun getLineStartIdx (lineGap: LineGap.t, reqLine) = + let + val {rightLines, line = bufferLine, idx = bufferIdx, ...} = lineGap + in + case rightLines of + hd :: tl => + (* reqLine exists in lineGap, so retrieve it *) + let + val relativeLine = reqLine - bufferLine - 1 + val lineIdx = Vector.sub (hd, relativeLine) + in + bufferIdx + lineIdx + 1 + end + | [] => + (* reqLine does not exist in lineGap, so just go to start of last line *) + let + val {leftStrings, rightStrings, leftLines, ...} = lineGap + in + (case rightStrings of + hd :: _ => + helpVi0 + (~1, hd, bufferIdx - 1, leftStrings, leftLines) + | [] => + (case (leftStrings, leftLines) of + (lshd :: lstl, llhd :: lltl) => + let + val result = helpVi0 + (String.size lshd - 1, lshd, bufferIdx - 1, lstl, lltl) + in + if result = bufferIdx then + bufferIdx - 1 + else + result + end + | (_, _) => 0)) + end + end end diff --git a/shf b/shf index 002ee0c..74ec465 100755 Binary files a/shf and b/shf differ