begin moving text window when cursor goes off screen (currently, we only move the window when cursor goes backwards but this works fine and as expected)

This commit is contained in:
2024-10-28 09:34:55 +00:00
parent deab30c46d
commit 4b1ee33954
7 changed files with 120 additions and 41 deletions

View File

@@ -24,6 +24,8 @@ struct
let let
val {windowWidth, windowHeight, startLine, ...} = app val {windowWidth, windowHeight, startLine, ...} = app
(* todo: get new startLine if cursor has moved out of screen *) (* todo: get new startLine if cursor has moved out of screen *)
val startLine = TextWindow.getStartLine
(buffer, startLine, cursorIdx, windowWidth, windowHeight)
(* move LineGap to first line displayed on screen, and build new text *) (* move LineGap to first line displayed on screen, and build new text *)
val buffer = LineGap.goToLine (startLine, buffer) val buffer = LineGap.goToLine (startLine, buffer)
@@ -31,7 +33,8 @@ struct
(startLine, cursorIdx, buffer, windowWidth, windowHeight) (startLine, cursorIdx, buffer, windowWidth, windowHeight)
val mode = NORMAL_MODE "" val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode) val newApp = AppWith.bufferAndCursorIdx
(app, buffer, cursorIdx, mode, startLine)
in in
(newApp, drawMsg) (newApp, drawMsg)
end end
@@ -61,7 +64,8 @@ struct
(startLine, cursorIdx, buffer, windowWidth, windowHeight) (startLine, cursorIdx, buffer, windowWidth, windowHeight)
val mode = NORMAL_MODE "" val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode) val newApp = AppWith.bufferAndCursorIdx
(app, buffer, cursorIdx, mode, startLine)
in in
(newApp, drawMsg) (newApp, drawMsg)
end end
@@ -99,7 +103,8 @@ struct
(startLine, cursorIdx, buffer, windowWidth, windowHeight) (startLine, cursorIdx, buffer, windowWidth, windowHeight)
val mode = NORMAL_MODE "" val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode) val newApp = AppWith.bufferAndCursorIdx
(app, buffer, cursorIdx, mode, startLine)
in in
(newApp, drawMsg) (newApp, drawMsg)
end end
@@ -109,11 +114,8 @@ struct
if pos = String.size str then if pos = String.size str then
pos pos
else else
let let val chr = String.sub (str, pos)
val chr = String.sub (str, pos) in if Char.isDigit chr then getNumLength (pos + 1, str) else pos
in
if Char.isDigit chr then getNumLength (pos + 1, str)
else pos
end end
fun appendChr (app: app_type, chr, str) = fun appendChr (app: app_type, chr, str) =
@@ -180,10 +182,7 @@ struct
* such as "2dw" to delete two word * such as "2dw" to delete two word
* so add current chr to mode, and save it in the app state *) * so add current chr to mode, and save it in the app state *)
let let
val str = val str = if Char.isDigit chr then str ^ Char.toString chr else ""
if Char.isDigit chr
then str ^ Char.toString chr
else ""
val mode = NORMAL_MODE str val mode = NORMAL_MODE str
val newApp = AppWith.mode (app, mode) val newApp = AppWith.mode (app, mode)
in in
@@ -202,7 +201,8 @@ struct
(startLine, cursorIdx, buffer, windowWidth, windowHeight) (startLine, cursorIdx, buffer, windowWidth, windowHeight)
val mode = NORMAL_MODE "" val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode) val newApp = AppWith.bufferAndCursorIdx
(app, buffer, cursorIdx, mode, startLine)
in in
(newApp, drawMsg) (newApp, drawMsg)
end end
@@ -262,24 +262,16 @@ struct
| #"T" => | #"T" =>
(* to just before chr, backward *) (* to just before chr, backward *)
handleNextChr (1, app, Cursor.tillPrevChr, newCmd) handleNextChr (1, app, Cursor.tillPrevChr, newCmd)
| #"y" => | #"y" => (* yank *) clearMode app
(* yank *) | #"d" => (* delete *) clearMode app
clearMode app
| #"d" =>
(* delete *)
clearMode app
| #"f" => | #"f" =>
(* to chr, forward *) (* to chr, forward *)
handleNextChr (count, app, Cursor.toNextChr, newCmd) handleNextChr (count, app, Cursor.toNextChr, newCmd)
| #"F" => | #"F" =>
(* to chr, backward *) (* to chr, backward *)
handleNextChr (count, app, Cursor.toPrevChr, newCmd) handleNextChr (count, app, Cursor.toPrevChr, newCmd)
| #"g" => | #"g" => (* go *) handleGo (count, app, newCmd)
(* go *) | #"c" => (* change *) clearMode app
handleGo (count, app, newCmd)
| #"c" =>
(* change *)
clearMode app
| _ => | _ =>
(* isn't a non-terminal cmd (* isn't a non-terminal cmd
* this case should never happen*) * this case should never happen*)

View File

@@ -22,7 +22,8 @@ struct
} }
end end
fun bufferAndCursorIdx (app: app_type, newBuffer, newCursorIdx, newMode) = fun bufferAndCursorIdx
(app: app_type, newBuffer, newCursorIdx, newMode, newStartLine) =
let let
val val
{ mode = _ { mode = _
@@ -30,15 +31,15 @@ struct
, cursorIdx = _ , cursorIdx = _
, windowWidth , windowWidth
, windowHeight , windowHeight
, startLine , startLine = _
} = app } = app
in in
{ mode = newMode { mode = newMode
, buffer = newBuffer , buffer = newBuffer
, cursorIdx = newCursorIdx , cursorIdx = newCursorIdx
, startLine = newStartLine
, windowWidth = windowWidth , windowWidth = windowWidth
, windowHeight = windowHeight , windowHeight = windowHeight
, startLine = startLine
} }
end end

View File

@@ -7,10 +7,7 @@ end
structure TextBuilder :> TEXT_BUILDER = structure TextBuilder :> TEXT_BUILDER =
struct struct
val xSpace = 13 open TextConstants
val xSpace3 = xSpace * 3
val ySpace = 25
val fontSize = 30.0
fun accToDrawMsg (textAcc, cursorAcc) = fun accToDrawMsg (textAcc, cursorAcc) =
let let
@@ -480,7 +477,6 @@ struct
fun build fun build
(startLine, cursorPos, lineGap: LineGap.t, windowWidth, windowHeight) = (startLine, cursorPos, lineGap: LineGap.t, windowWidth, windowHeight) =
let let
val lineGap = LineGap.goToLine (startLine, lineGap)
val {rightStrings, rightLines, line = curLine, idx = curIdx, ...} = lineGap val {rightStrings, rightLines, line = curLine, idx = curIdx, ...} = lineGap
in in
case (rightStrings, rightLines) of case (rightStrings, rightLines) of
@@ -504,9 +500,7 @@ struct
end end
else else
0 0
val absIdx = curIdx + startIdx val absIdx = curIdx + startIdx
in in
if cursorPos < curIdx + String.size rStrHd then if cursorPos < curIdx + String.size rStrHd then
(* if cursor is within string *) (* if cursor is within string *)

7
fcore/text-constants.sml Normal file
View File

@@ -0,0 +1,7 @@
structure TextConstants =
struct
val xSpace = 13
val xSpace3 = xSpace * 3
val ySpace = 25
val fontSize : Real32.real = 30.0
end

81
fcore/text-window.sml Normal file
View File

@@ -0,0 +1,81 @@
structure TextWindow =
struct
open TextConstants
fun isPrevChrLn (str, strPos, strTl) =
if strPos > 0 then
String.sub (str, strPos - 1) = #"\n"
else
case strTl of
hd :: _ =>
String.sub (hd, String.size hd - 1) = #"\n"
| [] => false
fun getStartLineBefore (sIdx, shd, lineNum, absIdx, cursorIdx, stl) =
if sIdx < 0 then
case stl of
hd :: tl =>
getStartLineBefore
(String.size hd - 1, hd, lineNum, absIdx, cursorIdx, tl)
| [] =>
0
else
let
val chr = String.sub (shd, sIdx)
in
if chr = #"\n" then
if absIdx <> cursorIdx then
getStartLineBefore
(sIdx - 1, shd, lineNum - 1, absIdx - 1, cursorIdx, stl)
else
(* we have found cursor, and it is at \n *)
lineNum - 1
else
if absIdx <> cursorIdx then
getStartLineBefore
(sIdx - 1, shd, lineNum, absIdx - 1, cursorIdx, stl)
else
(* we have found cursor; return line *)
lineNum - 1
end
(* Prerequisite: LineGap is moved to oldLine first. *)
fun getStartLine (lineGap: LineGap.t, oldLine, cursorIdx, maxWidth, maxHeight) =
let
val {rightStrings, rightLines, line = curLine, idx = curIdx, leftStrings, ...} = lineGap
in
case (rightStrings, rightLines) of
(rStrHd :: rStrTl, rLnHd :: _) =>
let
(* get index of line to start building from *)
val startIdx =
if oldLine > curLine then
let
val lnPos = oldLine - curLine - 1
val startIdx = Vector.sub (rLnHd, lnPos)
in
startIdx - 1
end
else
0
val absIdx = curIdx + startIdx
in
if cursorIdx < absIdx then
(* move upwards *)
getStartLineBefore
(startIdx, rStrHd, oldLine, absIdx, cursorIdx, leftStrings)
else if cursorIdx = absIdx + 1 then
(* double linebreak *)
getStartLineBefore
(startIdx + 1, rStrHd, oldLine, absIdx + 1, cursorIdx, leftStrings)
else if cursorIdx > absIdx then
(* possibly move downwards *)
oldLine
else
(* keep current line *)
Int.max (oldLine - 1, 0)
end
| (_, _) =>
oldLine
end
end

BIN
shf

Binary file not shown.

View File

@@ -11,11 +11,15 @@ message-types/mailbox-type.sml
fcore/app-type.sml fcore/app-type.sml
fcore/app-with.sml fcore/app-with.sml
fcore/text-constants.sml
ann ann
"allowVectorExps true" "allowVectorExps true"
in in
fcore/text-builder.sml fcore/text-builder.sml
end end
fcore/text-window.sml
fcore/cursor.sml fcore/cursor.sml
fcore/app-update.sml fcore/app-update.sml