diff --git a/fcore/app-update.sml b/fcore/app-update.sml index 0baf494..94739cd 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -131,23 +131,43 @@ struct val buffer = LineGap.goToIdx (cursorIdx, buffer) 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 newApp = AppWith.bufferAndCursorIdx - (app, buffer, cursorIdx, NORMAL_MODE "", startLine) - - val drawMsg = - TextBuilder.build - (startLine, cursorIdx, buffer, windowWidth, windowHeight) 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 fun firstNonSpaceChr (app: app_type) = diff --git a/fcore/text-window.sml b/fcore/text-window.sml index 3e4723a..ac42fc4 100644 --- a/fcore/text-window.sml +++ b/fcore/text-window.sml @@ -278,11 +278,11 @@ struct fun helpIsCursorVisible (strPos, str, stl, absIdx, maxW, maxH, curW, curH, newCursorIdx) = - if strPos = String.size str then - case stl of - hd :: tl => - helpIsCursorVisible - (0, hd, tl, absIdx, maxW, maxH, curW, curH) + if strPos = String.size str then + case stl of + hd :: tl => + helpIsCursorVisible + (0, hd, tl, absIdx, maxW, maxH, curW, curH, newCursorIdx) | [] => true else @@ -301,14 +301,14 @@ struct , maxW, maxH, 0, curH + ySpace, newCursorIdx ) else - if curWidth + xSpace <= maxWidth then + if curW + xSpace <= maxW then helpIsCursorVisible ( strPos + 1, str, stl, absIdx + 1 , maxW, maxH, curW + xSpace, curH, newCursorIdx ) else (* have to create visual line break *) - if curHeight + (ySpace * 3) >= maxHeight then + if curH + (ySpace * 3) >= maxH then false else helpIsCursorVisible @@ -318,11 +318,40 @@ struct end fun startIsCursorVisible - (strIdx, shd, stl, absIdx, maxW, maxH, newCursorIdx) = - raise Match + (curIdx, shd, stl, lhd, startLine, curLine, maxW, maxH, newCursorIdx) = + 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 *) - fun isCursorVisible - (lineGap: LineGap.t, newCursorIdx, oldLine) = - raise Match + (* Prerequisite: move LineGap.t to startLine *) + fun isCursorVisible (lineGap: LineGap.t, newCursorIdx, startLine, maxW, maxH) = + let + 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 diff --git a/shf b/shf index 19c8e4e..4551914 100755 Binary files a/shf and b/shf differ