when pressing fcore/text-window.sml to match pair, only recentre text window if matching pair is not currently visible on screen

This commit is contained in:
2024-11-02 12:34:23 +00:00
parent 33f2bf7b58
commit 2a8e02ff3a
3 changed files with 77 additions and 28 deletions

View File

@@ -131,23 +131,43 @@ struct
val buffer = LineGap.goToIdx (cursorIdx, buffer) val buffer = LineGap.goToIdx (cursorIdx, buffer)
val cursorIdx = Cursor.matchPair (buffer, cursorIdx) val cursorIdx = Cursor.matchPair (buffer, cursorIdx)
val buffer = LineGap.goToIdx (cursorIdx, buffer)
(* todo:
* check if cursorIdx is visible on screen first,
* and only get new startLine if it is not visible *)
val startLine = TextWindow.getStartLineWithCursorCentered
(buffer, cursorIdx, startLine, windowWidth, windowHeight div 2)
val buffer = LineGap.goToLine (startLine, buffer) 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 in
(newApp, drawMsg) if TextWindow.isCursorVisible
(buffer, cursorIdx, startLine, windowWidth, windowHeight)
then
(* if visible, just need to redraw; no need to get line *)
let
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
else
(* not visible, so need to get startLine where cursor is visible *)
let
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val startLine =
TextWindow.getStartLineWithCursorCentered
(buffer, cursorIdx, startLine, 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
end end
fun firstNonSpaceChr (app: app_type) = fun firstNonSpaceChr (app: app_type) =

View File

@@ -278,11 +278,11 @@ struct
fun helpIsCursorVisible fun helpIsCursorVisible
(strPos, str, stl, absIdx, maxW, maxH, curW, curH, newCursorIdx) = (strPos, str, stl, absIdx, maxW, maxH, curW, curH, newCursorIdx) =
if strPos = String.size str then if strPos = String.size str then
case stl of case stl of
hd :: tl => hd :: tl =>
helpIsCursorVisible helpIsCursorVisible
(0, hd, tl, absIdx, maxW, maxH, curW, curH) (0, hd, tl, absIdx, maxW, maxH, curW, curH, newCursorIdx)
| [] => | [] =>
true true
else else
@@ -301,14 +301,14 @@ struct
, maxW, maxH, 0, curH + ySpace, newCursorIdx , maxW, maxH, 0, curH + ySpace, newCursorIdx
) )
else else
if curWidth + xSpace <= maxWidth then if curW + xSpace <= maxW then
helpIsCursorVisible helpIsCursorVisible
( strPos + 1, str, stl, absIdx + 1 ( strPos + 1, str, stl, absIdx + 1
, maxW, maxH, curW + xSpace, curH, newCursorIdx , maxW, maxH, curW + xSpace, curH, newCursorIdx
) )
else else
(* have to create visual line break *) (* have to create visual line break *)
if curHeight + (ySpace * 3) >= maxHeight then if curH + (ySpace * 3) >= maxH then
false false
else else
helpIsCursorVisible helpIsCursorVisible
@@ -318,11 +318,40 @@ struct
end end
fun startIsCursorVisible fun startIsCursorVisible
(strIdx, shd, stl, absIdx, maxW, maxH, newCursorIdx) = (curIdx, shd, stl, lhd, startLine, curLine, maxW, maxH, newCursorIdx) =
raise Match let
val relativeLine = (curLine + Vector.length lhd) - startLine
val lineIdx = Cursor.binSearch (relativeLine, lhd)
val absIdx = curIdx + lineIdx
in
helpIsCursorVisible
(lineIdx, shd, stl, absIdx, maxW, maxH, 0, 0, newCursorIdx)
end
(* Prerequisite: move LineGap.t to oldLine *) (* Prerequisite: move LineGap.t to startLine *)
fun isCursorVisible fun isCursorVisible (lineGap: LineGap.t, newCursorIdx, startLine, maxW, maxH) =
(lineGap: LineGap.t, newCursorIdx, oldLine) = let
raise Match val {rightStrings, rightLines, line = curLine, idx = curIdx, ...} = lineGap
in
case (rightStrings, rightLines) of
(shd :: stl, lhd :: ltl) =>
if startLine < curLine + Vector.length lhd then
(* startLine in this node *)
startIsCursorVisible
( curIdx, shd, stl, lhd, startLine, curLine
, maxW, maxH, newCursorIdx
)
else
(* startLine is in stl *)
(case (stl, ltl) of
(stlhd :: stltl, ltlhd :: ltltl) =>
startIsCursorVisible
( curIdx, stlhd, stltl, ltlhd, startLine, curLine
, maxW, maxH, newCursorIdx
)
| (_, _) =>
true)
| (_, _) =>
true
end
end end

BIN
shf

Binary file not shown.