progress parsing normal mode commands

This commit is contained in:
2024-10-26 06:01:48 +01:00
parent defb17af20
commit 816f064558
3 changed files with 141 additions and 53 deletions

View File

@@ -19,49 +19,69 @@ struct
(newApp, drawMsg)
end
fun moveBackward (app: app_type, fMove) =
let
val {buffer, windowWidth, windowHeight, startLine, cursorIdx, ...} = app
fun helpMoveBackward (app: app_type, buffer, cursorIdx, count, fMove) =
if count = 0 then
let
val {windowWidth, windowHeight, startLine, ...} = app
(* todo: get new startLine if cursor has moved out of screen *)
(* move LineGap to first line displayed on screen, and build new text *)
val buffer = LineGap.goToLine (startLine, buffer)
val drawMsg = TextBuilder.build
(startLine, cursorIdx, buffer, windowWidth, windowHeight)
val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode)
in
(newApp, drawMsg)
end
else
(* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *)
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val cursorIdx = fMove (buffer, cursorIdx)
let
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val cursorIdx = fMove (buffer, cursorIdx)
in
helpMoveBackward (app, buffer, cursorIdx, count - 1, fMove)
end
(* todo: get new startLine if cursor has moved out of screen *)
(* move LineGap to first line displayed on screen, and build new text *)
val buffer = LineGap.goToLine (startLine, buffer)
val drawMsg = TextBuilder.build
(startLine, cursorIdx, buffer, windowWidth, windowHeight)
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx)
in
(newApp, drawMsg)
fun moveBackward (app: app_type, count, fMove) =
let val {cursorIdx, buffer, ...} = app
in helpMoveBackward (app, buffer, cursorIdx, count, fMove)
end
fun moveFowrards (app: app_type, fMove) =
let
val {buffer, windowWidth, windowHeight, startLine, cursorIdx, ...} = app
fun helpMoveForwards (app: app_type, buffer, cursorIdx, count, fMove) =
if count = 0 then
let
val {windowWidth, windowHeight, startLine, ...} = app
(* todo: get new startLine if cursor has moved out of screen *)
(* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *)
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val cursorIdx = fMove (buffer, cursorIdx)
(* move LineGap to first line displayed on screen, and build new text *)
val buffer = LineGap.goToLine (startLine, buffer)
val drawMsg = TextBuilder.build
(startLine, cursorIdx, buffer, windowWidth, windowHeight)
(* todo: get new startLine if cursor has moved out of screen *)
val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode)
in
(newApp, drawMsg)
end
else
let
(* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *)
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val cursorIdx = fMove (buffer, cursorIdx)
in
helpMoveForwards (app, buffer, cursorIdx, count - 1, fMove)
end
(* move LineGap to first line displayed on screen, and build new text *)
val buffer = LineGap.goToLine (startLine, buffer)
val drawMsg = TextBuilder.build
(startLine, cursorIdx, buffer, windowWidth, windowHeight)
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx)
in
(newApp, drawMsg)
fun moveForwards (app: app_type, count, fMove) =
let val {cursorIdx, buffer, ...} = app
in helpMoveForwards (app, buffer, cursorIdx, count, fMove)
end
fun firstNonSpaceChr (app: app_type) =
let
val {buffer, windowWidth, windowHeight, startLine, cursorIdx, ...} = app
val {buffer, cursorIdx, windowWidth, windowHeight, startLine, ...} = app
(* move LineGap and buffer to start of line *)
val buffer = LineGap.goToIdx (cursorIdx, buffer)
@@ -78,30 +98,79 @@ struct
val drawMsg = TextBuilder.build
(startLine, cursorIdx, buffer, windowWidth, windowHeight)
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx)
val mode = NORMAL_MODE ""
val newApp = AppWith.bufferAndCursorIdx (app, buffer, cursorIdx, mode)
in
(newApp, drawMsg)
end
fun handleChr (app: app_type, chr) =
(* number of characters which are integers *)
fun getNumLength (pos, str) =
if pos = String.size str then
pos
else
let
val chr = String.sub (str, pos)
in
if chr >= #"0" andalso chr <= #"9" then getNumLength (pos + 1, str)
else pos
end
fun handleChr (app: app_type, count, chr, str) =
case chr of
#"h" => moveBackward (app, Cursor.viH)
| #"j" => moveFowrards (app, Cursor.viJ)
| #"k" => moveBackward (app, Cursor.viK)
| #"l" => moveFowrards (app, Cursor.viL)
| #"0" => moveBackward (app, Cursor.vi0)
| #"$" => moveFowrards (app, Cursor.viDlr)
| #"w" => moveFowrards (app, Cursor.nextWord)
| #"W" => moveFowrards (app, Cursor.nextWORD)
| #"b" => moveBackward (app, Cursor.prevWord)
| #"B" => moveBackward (app, Cursor.prevWORD)
| #"e" => moveFowrards (app, Cursor.endOfWord)
| #"E" => moveFowrards (app, Cursor.endOfWORD)
#"h" => moveBackward (app, count, Cursor.viH)
| #"j" => moveForwards (app, count, Cursor.viJ)
| #"k" => moveBackward (app, count, Cursor.viK)
| #"l" => moveForwards (app, count, Cursor.viL)
| #"0" => moveBackward (app, 1, Cursor.vi0)
| #"$" => moveForwards (app, 1, Cursor.viDlr)
| #"w" => moveForwards (app, count, Cursor.nextWord)
| #"W" => moveForwards (app, count, Cursor.nextWORD)
| #"b" => moveBackward (app, count, Cursor.prevWord)
| #"B" => moveBackward (app, count, Cursor.prevWORD)
| #"e" => moveForwards (app, count, Cursor.endOfWord)
| #"E" => moveForwards (app, count, Cursor.endOfWORD)
| #"^" => firstNonSpaceChr app
| _ => (app, [])
| _ =>
(* user may be entering a cmd with more than one chr
* such as "2dw" to delete two word
* so add current chr to mode, and save it in the app state *)
let
val str =
if chr >= #"0" andalso chr <= #"9" then str ^ Char.toString chr
else ""
val mode = NORMAL_MODE str
val newApp = AppWith.mode (app, mode)
in
(newApp, [])
end
fun parseNormalModeCommand (app, str, newCmd) =
if String.size str = 0 then
case newCmd of
RESIZE_EVENT (width, height) => resizeText (app, width, height)
| CHAR_EVENT chr => handleChr (app, 1, chr, str)
else
let
val numLength = getNumLength (0, str)
val count = String.substring (str, 0, numLength)
val count =
case Int.fromString count of
SOME x => x
| NONE => 1
in
if numLength = String.size str then
(* reached end of str; str only contained numbers *)
case newCmd of
RESIZE_EVENT (width, height) => resizeText (app, width, height)
| CHAR_EVENT chr => handleChr (app, count, chr, str)
else
(* todo: continue parsing. *)
raise Match
end
fun updateNormalMode (app, str, msg) = parseNormalModeCommand (app, str, msg)
fun update (app, msg) =
case msg of
RESIZE_EVENT (width, height) => resizeText (app, width, height)
| CHAR_EVENT chr => handleChr (app, chr)
case #mode app of NORMAL_MODE str => updateNormalMode (app, str, msg)
end

View File

@@ -22,13 +22,18 @@ struct
}
end
fun bufferAndCursorIdx (app: app_type, newBuffer, newCursorIdx) =
fun bufferAndCursorIdx (app: app_type, newBuffer, newCursorIdx, newMode) =
let
val
{mode, buffer = _, cursorIdx = _, windowWidth, windowHeight, startLine} =
app
{ mode = _
, buffer = _
, cursorIdx = _
, windowWidth
, windowHeight
, startLine
} = app
in
{ mode = mode
{ mode = newMode
, buffer = newBuffer
, cursorIdx = newCursorIdx
, windowWidth = windowWidth
@@ -36,4 +41,18 @@ struct
, startLine = startLine
}
end
fun mode (app: app_type, newMode) =
let
val {mode = _, buffer, cursorIdx, windowWidth, windowHeight, startLine} =
app
in
{ mode = newMode
, buffer = buffer
, cursorIdx = cursorIdx
, windowWidth = windowWidth
, windowHeight = windowHeight
, startLine = startLine
}
end
end

BIN
shf

Binary file not shown.