progress parsing normal mode commands
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user