add functionality to go to specific line in buffer

This commit is contained in:
2024-11-02 13:59:55 +00:00
parent 2df8f88452
commit b368619df3
3 changed files with 67 additions and 1 deletions

View File

@@ -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)

View File

@@ -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

BIN
shf

Binary file not shown.