diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 1b82a07..a0b2a53 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -1125,22 +1125,46 @@ struct (* Prerequisite: move lineGap to reqLine *) fun getLineStartIdx (lineGap: LineGap.t, reqLine) = let - val {rightStrings, rightLines, line = bufferLine, idx = bufferIdx, ...} = - lineGap + val + { rightStrings + , rightLines + , line = bufferLine + , idx = bufferIdx + , leftStrings + , leftLines + , ... + } = lineGap in case (rightStrings, rightLines) of (shd :: stl, lhd :: ltl) => (* reqLine exists in lineGap, so retrieve it *) let val relativeLine = reqLine - bufferLine - 1 - 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 + if relativeLine < 0 then + (* line is in left node, if it exists *) + (case (leftStrings, leftLines) of + (leftShd :: leftStl, leftLhd :: leftLtl) => + startVi0 + ( String.size leftShd - 1 + , leftShd + , leftLhd + , bufferIdx - 1 + , leftStl + , leftLtl + ) + 1 + | (_, _) => 0) 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 | (_, _) => (* reqLine does not exist in lineGap, so just go to start of last line *) diff --git a/fcore/normal-mode/normal-mode.sml b/fcore/normal-mode/normal-mode.sml index b50fb1b..bc337bd 100644 --- a/fcore/normal-mode/normal-mode.sml +++ b/fcore/normal-mode/normal-mode.sml @@ -192,7 +192,7 @@ struct * interpret as "go to line" command; * else, interpret as a command to move to end *) if String.size str = 0 then NormalMove.moveToEnd app - else NormalMove.moveToLine (app, count - 1) + else NormalMove.moveToLine (app, count) | #"%" => NormalMove.moveToMatchingPair app | #"x" => NormalDelete.removeChr (app, count, time) | #"J" => NormalDelete.removeLineBreaks (app, count, time) diff --git a/fcore/normal-mode/normal-move.sml b/fcore/normal-mode/normal-move.sml index f321eb2..478d916 100644 --- a/fcore/normal-mode/normal-move.sml +++ b/fcore/normal-mode/normal-move.sml @@ -107,65 +107,69 @@ struct end fun moveToLine (app: app_type, reqLine) = - if reqLine = 0 then - moveToStart app - else - let - val - { windowWidth - , windowHeight - , buffer - , startLine = prevLineNumber - , searchList - , searchString - , bufferModifyTime - , visualScrollColumn = prevScrollColumn - , ... - } = app - val buffer = LineGap.goToLine (reqLine, buffer) + let + val reqLine = reqLine - 1 + in + if reqLine = 0 then + moveToStart app + else + let + val + { windowWidth + , windowHeight + , buffer + , startLine = prevLineNumber + , searchList + , searchString + , bufferModifyTime + , visualScrollColumn = prevScrollColumn + , ... + } = app + val buffer = LineGap.goToLine (reqLine, buffer) - (* get idx of first chr after linebreak *) - val cursorIdx = Cursor.getLineStartIdx (buffer, reqLine) + (* get idx of first chr after linebreak *) + val cursorIdx = Cursor.getLineStartIdx (buffer, reqLine) - val buffer = LineGap.goToIdx (cursorIdx, buffer) - val visualScrollColumn = - TextScroll.getScrollColumn - (buffer, cursorIdx, windowWidth, prevScrollColumn) + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val visualScrollColumn = + TextScroll.getScrollColumn + (buffer, cursorIdx, windowWidth, prevScrollColumn) - val cursorLine = LineGap.getLineNumberOfIdx (cursorIdx, buffer) - val startLine = - TextScroll.getStartLine (prevLineNumber, cursorLine, windowHeight) + val cursorLine = LineGap.getLineNumberOfIdx (cursorIdx, buffer) + val startLine = + TextScroll.getStartLine (prevLineNumber, cursorLine, windowHeight) - val buffer = LineGap.goToLine (startLine, buffer) + val buffer = LineGap.goToLine (startLine, buffer) - val drawMsg = NormalModeTextBuilder.build - ( startLine - , cursorIdx - , buffer - , windowWidth - , windowHeight - , searchList - , searchString - , visualScrollColumn - ) - val drawMsg = Vector.concat drawMsg - val drawMsg = DrawMsg.DRAW_TEXT drawMsg - val drawMsg = [MailboxType.DRAW drawMsg] + val drawMsg = NormalModeTextBuilder.build + ( startLine + , cursorIdx + , buffer + , windowWidth + , windowHeight + , searchList + , searchString + , visualScrollColumn + ) + val drawMsg = Vector.concat drawMsg + val drawMsg = DrawMsg.DRAW_TEXT drawMsg + val drawMsg = [MailboxType.DRAW drawMsg] - val mode = NORMAL_MODE "" - in - NormalModeWith.bufferAndCursorIdx - ( app - , buffer - , cursorIdx - , mode - , startLine - , searchList - , drawMsg - , bufferModifyTime - , visualScrollColumn - ) - end + val mode = NORMAL_MODE "" + in + NormalModeWith.bufferAndCursorIdx + ( app + , buffer + , cursorIdx + , mode + , startLine + , searchList + , drawMsg + , bufferModifyTime + , visualScrollColumn + ) + end + end fun moveToMatchingPair (app: app_type) = let