fix 'Cursor.getLineStartIdx' function, which should look at the left nodes if there is no relevant line in this node

This commit is contained in:
2025-09-16 22:09:15 +01:00
parent 96521f358f
commit c4fedc6434
3 changed files with 90 additions and 62 deletions

View File

@@ -1125,22 +1125,46 @@ struct
(* Prerequisite: move lineGap to reqLine *) (* Prerequisite: move lineGap to reqLine *)
fun getLineStartIdx (lineGap: LineGap.t, reqLine) = fun getLineStartIdx (lineGap: LineGap.t, reqLine) =
let let
val {rightStrings, rightLines, line = bufferLine, idx = bufferIdx, ...} = val
lineGap { rightStrings
, rightLines
, line = bufferLine
, idx = bufferIdx
, leftStrings
, leftLines
, ...
} = lineGap
in in
case (rightStrings, rightLines) of case (rightStrings, rightLines) of
(shd :: stl, lhd :: ltl) => (shd :: stl, lhd :: ltl) =>
(* reqLine exists in lineGap, so retrieve it *) (* reqLine exists in lineGap, so retrieve it *)
let let
val relativeLine = reqLine - bufferLine - 1 val relativeLine = reqLine - bufferLine - 1
val lineIdx = Vector.sub (lhd, relativeLine)
in in
if lineIdx = String.size shd - 1 andalso List.null stl then if relativeLine < 0 then
(* if is end of buffer, return last idx in buffer; else, (* line is in left node, if it exists *)
* increment by 1 as we want to go to first char after line break *) (case (leftStrings, leftLines) of
bufferIdx + lineIdx (leftShd :: leftStl, leftLhd :: leftLtl) =>
startVi0
( String.size leftShd - 1
, leftShd
, leftLhd
, bufferIdx - 1
, leftStl
, leftLtl
) + 1
| (_, _) => 0)
else else
bufferIdx + lineIdx + 1 let
val lineIdx = Vector.sub (lhd, relativeLine)
in
if lineIdx = String.size shd - 1 andalso List.null stl then
(* if is end of buffer, return last idx in buffer; else,
* increment by 1 as we want to go to first char after line break *)
bufferIdx + lineIdx
else
bufferIdx + lineIdx + 1
end
end end
| (_, _) => | (_, _) =>
(* reqLine does not exist in lineGap, so just go to start of last line *) (* reqLine does not exist in lineGap, so just go to start of last line *)

View File

@@ -192,7 +192,7 @@ struct
* interpret as "go to line" command; * interpret as "go to line" command;
* else, interpret as a command to move to end *) * else, interpret as a command to move to end *)
if String.size str = 0 then NormalMove.moveToEnd app if String.size str = 0 then NormalMove.moveToEnd app
else NormalMove.moveToLine (app, count - 1) else NormalMove.moveToLine (app, count)
| #"%" => NormalMove.moveToMatchingPair app | #"%" => NormalMove.moveToMatchingPair app
| #"x" => NormalDelete.removeChr (app, count, time) | #"x" => NormalDelete.removeChr (app, count, time)
| #"J" => NormalDelete.removeLineBreaks (app, count, time) | #"J" => NormalDelete.removeLineBreaks (app, count, time)

View File

@@ -107,65 +107,69 @@ struct
end end
fun moveToLine (app: app_type, reqLine) = fun moveToLine (app: app_type, reqLine) =
if reqLine = 0 then let
moveToStart app val reqLine = reqLine - 1
else in
let if reqLine = 0 then
val moveToStart app
{ windowWidth else
, windowHeight let
, buffer val
, startLine = prevLineNumber { windowWidth
, searchList , windowHeight
, searchString , buffer
, bufferModifyTime , startLine = prevLineNumber
, visualScrollColumn = prevScrollColumn , searchList
, ... , searchString
} = app , bufferModifyTime
val buffer = LineGap.goToLine (reqLine, buffer) , visualScrollColumn = prevScrollColumn
, ...
} = app
val buffer = LineGap.goToLine (reqLine, buffer)
(* get idx of first chr after linebreak *) (* get idx of first chr after linebreak *)
val cursorIdx = Cursor.getLineStartIdx (buffer, reqLine) val cursorIdx = Cursor.getLineStartIdx (buffer, reqLine)
val buffer = LineGap.goToIdx (cursorIdx, buffer) val buffer = LineGap.goToIdx (cursorIdx, buffer)
val visualScrollColumn = val visualScrollColumn =
TextScroll.getScrollColumn TextScroll.getScrollColumn
(buffer, cursorIdx, windowWidth, prevScrollColumn) (buffer, cursorIdx, windowWidth, prevScrollColumn)
val cursorLine = LineGap.getLineNumberOfIdx (cursorIdx, buffer) val cursorLine = LineGap.getLineNumberOfIdx (cursorIdx, buffer)
val startLine = val startLine =
TextScroll.getStartLine (prevLineNumber, cursorLine, windowHeight) TextScroll.getStartLine (prevLineNumber, cursorLine, windowHeight)
val buffer = LineGap.goToLine (startLine, buffer) val buffer = LineGap.goToLine (startLine, buffer)
val drawMsg = NormalModeTextBuilder.build val drawMsg = NormalModeTextBuilder.build
( startLine ( startLine
, cursorIdx , cursorIdx
, buffer , buffer
, windowWidth , windowWidth
, windowHeight , windowHeight
, searchList , searchList
, searchString , searchString
, visualScrollColumn , visualScrollColumn
) )
val drawMsg = Vector.concat drawMsg val drawMsg = Vector.concat drawMsg
val drawMsg = DrawMsg.DRAW_TEXT drawMsg val drawMsg = DrawMsg.DRAW_TEXT drawMsg
val drawMsg = [MailboxType.DRAW drawMsg] val drawMsg = [MailboxType.DRAW drawMsg]
val mode = NORMAL_MODE "" val mode = NORMAL_MODE ""
in in
NormalModeWith.bufferAndCursorIdx NormalModeWith.bufferAndCursorIdx
( app ( app
, buffer , buffer
, cursorIdx , cursorIdx
, mode , mode
, startLine , startLine
, searchList , searchList
, drawMsg , drawMsg
, bufferModifyTime , bufferModifyTime
, visualScrollColumn , visualScrollColumn
) )
end end
end
fun moveToMatchingPair (app: app_type) = fun moveToMatchingPair (app: app_type) =
let let