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:
@@ -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*)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
7
fcore/text-constants.sml
Normal 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
81
fcore/text-window.sml
Normal 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
|
||||||
4
shf.mlb
4
shf.mlb
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user