begin refactoring (split app-update into different files)
This commit is contained in:
@@ -6,123 +6,7 @@ struct
|
|||||||
open DrawMsg
|
open DrawMsg
|
||||||
open InputMsg
|
open InputMsg
|
||||||
|
|
||||||
fun clearMode app =
|
|
||||||
AppWith.mode (app, NORMAL_MODE "", [])
|
|
||||||
|
|
||||||
fun withSearchList (app: app_type, searchList) =
|
|
||||||
let
|
|
||||||
val {buffer, searchString, cursorIdx, ...} = app
|
|
||||||
val app = AppWith.searchList (app, searchList, buffer, searchString)
|
|
||||||
in
|
|
||||||
Finish.buildTextAndClear (app, buffer, cursorIdx, searchList, [])
|
|
||||||
end
|
|
||||||
|
|
||||||
fun resizeText (app: app_type, newWidth, newHeight) =
|
|
||||||
let
|
|
||||||
val
|
|
||||||
{ buffer
|
|
||||||
, windowWidth
|
|
||||||
, windowHeight
|
|
||||||
, startLine
|
|
||||||
, cursorIdx
|
|
||||||
, searchList
|
|
||||||
, searchString
|
|
||||||
, ...
|
|
||||||
} = app
|
|
||||||
|
|
||||||
val newBuffer = LineGap.goToLine (startLine, buffer)
|
|
||||||
val lineIdx = TextBuilder.getLineAbsIdx (startLine, buffer)
|
|
||||||
|
|
||||||
val drawMsg = TextBuilder.build
|
|
||||||
( startLine
|
|
||||||
, cursorIdx
|
|
||||||
, newBuffer
|
|
||||||
, newWidth
|
|
||||||
, newHeight
|
|
||||||
, searchList
|
|
||||||
, searchString
|
|
||||||
, []
|
|
||||||
)
|
|
||||||
in
|
|
||||||
AppWith.bufferAndSize
|
|
||||||
(app, newBuffer, newWidth, newHeight, searchList, drawMsg)
|
|
||||||
end
|
|
||||||
|
|
||||||
(* Difference between this and buildTextAndClear is that
|
|
||||||
* this is meant to be called after a chr movement,
|
|
||||||
* where the cursor may possibly jump off window by a wide marigin.
|
|
||||||
* Since the cursor may move away a lot, it is best to recenter.
|
|
||||||
* *)
|
|
||||||
fun buildTextAndClearAfterChr
|
|
||||||
(app: app_type, buffer, cursorIdx, searchList, initialMsg) =
|
|
||||||
let
|
|
||||||
val {windowWidth, windowHeight, startLine, searchString, ...} = app
|
|
||||||
|
|
||||||
(* move LineGap to first line displayed on screen *)
|
|
||||||
val buffer = LineGap.goToLine (startLine, buffer)
|
|
||||||
|
|
||||||
(* get new startLine which may move screen depending on cursor movements *)
|
|
||||||
val startLine = TextWindow.getStartLine
|
|
||||||
(buffer, startLine, cursorIdx, windowWidth, windowHeight)
|
|
||||||
|
|
||||||
(* move buffer to new startLine as required by TextBuilder.build
|
|
||||||
* and move searchList to idx where line starts as well *)
|
|
||||||
val buffer = LineGap.goToLine (startLine, buffer)
|
|
||||||
|
|
||||||
val drawMsg = TextBuilder.build
|
|
||||||
( startLine
|
|
||||||
, cursorIdx
|
|
||||||
, buffer
|
|
||||||
, windowWidth
|
|
||||||
, windowHeight
|
|
||||||
, searchList
|
|
||||||
, searchString
|
|
||||||
, []
|
|
||||||
)
|
|
||||||
|
|
||||||
val mode = NORMAL_MODE ""
|
|
||||||
in
|
|
||||||
AppWith.bufferAndCursorIdx
|
|
||||||
(app, buffer, cursorIdx, mode, startLine, searchList, drawMsg)
|
|
||||||
end
|
|
||||||
|
|
||||||
fun centreToCursor (app: app_type) =
|
|
||||||
let
|
|
||||||
val
|
|
||||||
{ buffer
|
|
||||||
, windowWidth
|
|
||||||
, windowHeight
|
|
||||||
, startLine = origLine
|
|
||||||
, cursorIdx
|
|
||||||
, searchList
|
|
||||||
, searchString
|
|
||||||
, ...
|
|
||||||
} = app
|
|
||||||
val buffer = LineGap.goToIdx (cursorIdx, buffer)
|
|
||||||
|
|
||||||
val startLine = TextWindow.getStartLineWithCursorCentered
|
|
||||||
(buffer, cursorIdx, origLine, windowWidth, windowHeight div 2)
|
|
||||||
|
|
||||||
val buffer = LineGap.goToLine (startLine, buffer)
|
|
||||||
val lineIdx = TextBuilder.getLineAbsIdx (startLine, buffer)
|
|
||||||
|
|
||||||
val drawMsg = TextBuilder.build
|
|
||||||
( startLine
|
|
||||||
, cursorIdx
|
|
||||||
, buffer
|
|
||||||
, windowWidth
|
|
||||||
, windowHeight
|
|
||||||
, searchList
|
|
||||||
, searchString
|
|
||||||
, []
|
|
||||||
)
|
|
||||||
in
|
|
||||||
AppWith.bufferAndCursorIdx
|
|
||||||
(app, buffer, cursorIdx, NORMAL_MODE "", startLine, searchList, drawMsg)
|
|
||||||
end
|
|
||||||
|
|
||||||
(* movement functions *)
|
(* movement functions *)
|
||||||
|
|
||||||
fun moveToStart (app: app_type) =
|
fun moveToStart (app: app_type) =
|
||||||
let
|
let
|
||||||
val {buffer, windowWidth, windowHeight, searchList, searchString, ...} =
|
val {buffer, windowWidth, windowHeight, searchList, searchString, ...} =
|
||||||
@@ -330,7 +214,7 @@ struct
|
|||||||
|
|
||||||
fun helpMoveToChr (app: app_type, buffer, cursorIdx, count, fMove, chr) =
|
fun helpMoveToChr (app: app_type, buffer, cursorIdx, count, fMove, chr) =
|
||||||
if count = 0 then
|
if count = 0 then
|
||||||
buildTextAndClearAfterChr (app, buffer, cursorIdx, #searchList app, [])
|
Finish.buildTextAndClearAfterChr (app, buffer, cursorIdx, #searchList app, [])
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
(* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *)
|
(* move LineGap to cursorIdx, which is necessary for finding newCursorIdx *)
|
||||||
@@ -349,9 +233,9 @@ struct
|
|||||||
fun handleMoveToChr (count, app, fMove, newCmd) =
|
fun handleMoveToChr (count, app, fMove, newCmd) =
|
||||||
case newCmd of
|
case newCmd of
|
||||||
CHAR_EVENT chr => moveToChr (app, count, fMove, chr)
|
CHAR_EVENT chr => moveToChr (app, count, fMove, chr)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList)
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
|
||||||
|
|
||||||
fun handleGo (count, app, newCmd) =
|
fun handleGo (count, app, newCmd) =
|
||||||
case newCmd of
|
case newCmd of
|
||||||
@@ -360,18 +244,18 @@ struct
|
|||||||
#"e" => MoveToEndOfPrevWord.move (app, count)
|
#"e" => MoveToEndOfPrevWord.move (app, count)
|
||||||
| #"E" => MoveToEndOfPrevWORD.move (app, count)
|
| #"E" => MoveToEndOfPrevWORD.move (app, count)
|
||||||
| #"g" => moveToStart app
|
| #"g" => moveToStart app
|
||||||
| _ => clearMode app)
|
| _ => Finish.clearMode app)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList)
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
|
||||||
|
|
||||||
fun moveToNextMatch (app: app_type, count) =
|
fun moveToNextMatch (app: app_type, count) =
|
||||||
let
|
let
|
||||||
val {cursorIdx, searchList, buffer, ...} = app
|
val {cursorIdx, searchList, buffer, ...} = app
|
||||||
val newCursorIdx = SearchList.nextMatch (cursorIdx, searchList, count)
|
val newCursorIdx = SearchList.nextMatch (cursorIdx, searchList, count)
|
||||||
in
|
in
|
||||||
if newCursorIdx = ~1 then clearMode app
|
if newCursorIdx = ~1 then Finish.clearMode app
|
||||||
else buildTextAndClearAfterChr (app, buffer, newCursorIdx, searchList, [])
|
else Finish.buildTextAndClearAfterChr (app, buffer, newCursorIdx, searchList, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
fun moveToPrevMatch (app: app_type, count) =
|
fun moveToPrevMatch (app: app_type, count) =
|
||||||
@@ -379,8 +263,8 @@ struct
|
|||||||
val {cursorIdx, searchList, buffer, ...} = app
|
val {cursorIdx, searchList, buffer, ...} = app
|
||||||
val newCursorIdx = SearchList.prevMatch (cursorIdx, searchList, count)
|
val newCursorIdx = SearchList.prevMatch (cursorIdx, searchList, count)
|
||||||
in
|
in
|
||||||
if newCursorIdx = ~1 then clearMode app
|
if newCursorIdx = ~1 then Finish.clearMode app
|
||||||
else buildTextAndClearAfterChr (app, buffer, newCursorIdx, searchList, [])
|
else Finish.buildTextAndClearAfterChr (app, buffer, newCursorIdx, searchList, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
(* text-delete functions *)
|
(* text-delete functions *)
|
||||||
@@ -531,7 +415,7 @@ struct
|
|||||||
if Cursor.isCursorAtStartOfLine (buffer, cursorIdx) then
|
if Cursor.isCursorAtStartOfLine (buffer, cursorIdx) then
|
||||||
(* if we are on \n, we don't want to delete or do anything
|
(* if we are on \n, we don't want to delete or do anything
|
||||||
* so reset the mode *)
|
* so reset the mode *)
|
||||||
clearMode app
|
Finish.clearMode app
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
(* viDlr takes us to the last chr in the line
|
(* viDlr takes us to the last chr in the line
|
||||||
@@ -662,7 +546,7 @@ struct
|
|||||||
val searchList =
|
val searchList =
|
||||||
SearchList.buildRange (buffer, searchString, cursorIdx - 777)
|
SearchList.buildRange (buffer, searchString, cursorIdx - 777)
|
||||||
in
|
in
|
||||||
buildTextAndClearAfterChr (app, buffer, low, searchList, initialMsg)
|
Finish.buildTextAndClearAfterChr (app, buffer, low, searchList, initialMsg)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
@@ -744,7 +628,7 @@ struct
|
|||||||
val {cursorIdx, searchList, ...} = app
|
val {cursorIdx, searchList, ...} = app
|
||||||
val newCursorIdx = SearchList.nextMatch (cursorIdx, searchList, count)
|
val newCursorIdx = SearchList.nextMatch (cursorIdx, searchList, count)
|
||||||
in
|
in
|
||||||
if newCursorIdx = ~1 orelse newCursorIdx <= cursorIdx then clearMode app
|
if newCursorIdx = ~1 orelse newCursorIdx <= cursorIdx then Finish.clearMode app
|
||||||
else helpDeleteToMatch (app, cursorIdx, newCursorIdx)
|
else helpDeleteToMatch (app, cursorIdx, newCursorIdx)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -753,7 +637,7 @@ struct
|
|||||||
val {cursorIdx, searchList, ...} = app
|
val {cursorIdx, searchList, ...} = app
|
||||||
val newCursorIdx = SearchList.prevMatch (cursorIdx, searchList, count)
|
val newCursorIdx = SearchList.prevMatch (cursorIdx, searchList, count)
|
||||||
in
|
in
|
||||||
if newCursorIdx = ~1 orelse newCursorIdx >= cursorIdx then clearMode app
|
if newCursorIdx = ~1 orelse newCursorIdx >= cursorIdx then Finish.clearMode app
|
||||||
else helpDeleteToMatch (app, newCursorIdx, cursorIdx)
|
else helpDeleteToMatch (app, newCursorIdx, cursorIdx)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -789,7 +673,7 @@ struct
|
|||||||
| #"E" => MoveToEndOfWORD.move (app, count)
|
| #"E" => MoveToEndOfWORD.move (app, count)
|
||||||
| #"n" => moveToNextMatch (app, count)
|
| #"n" => moveToNextMatch (app, count)
|
||||||
| #"N" => moveToPrevMatch (app, count)
|
| #"N" => moveToPrevMatch (app, count)
|
||||||
| #"z" => centreToCursor app
|
| #"z" => Finish.centreToCursor app
|
||||||
(* can only move to start or end of line once
|
(* can only move to start or end of line once
|
||||||
* so hardcode count as 1 *)
|
* so hardcode count as 1 *)
|
||||||
| #"0" =>
|
| #"0" =>
|
||||||
@@ -880,10 +764,10 @@ struct
|
|||||||
| #"F" => appendChr (app, chr, str)
|
| #"F" => appendChr (app, chr, str)
|
||||||
| #"g" => appendChr (app, chr, str)
|
| #"g" => appendChr (app, chr, str)
|
||||||
(* invalid command: reset mode *)
|
(* invalid command: reset mode *)
|
||||||
| _ => clearMode app)
|
| _ => Finish.clearMode app)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList)
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
|
||||||
else
|
else
|
||||||
(* have to continue parsing string *)
|
(* have to continue parsing string *)
|
||||||
case String.sub (str, strPos + 1) of
|
case String.sub (str, strPos + 1) of
|
||||||
@@ -892,32 +776,32 @@ struct
|
|||||||
(case newCmd of
|
(case newCmd of
|
||||||
CHAR_EVENT chr =>
|
CHAR_EVENT chr =>
|
||||||
deleteToChr (app, 1, Cursor.tillNextChr, op+, chr)
|
deleteToChr (app, 1, Cursor.tillNextChr, op+, chr)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList))
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList))
|
||||||
| #"T" =>
|
| #"T" =>
|
||||||
(* delete till chr, backwards *)
|
(* delete till chr, backwards *)
|
||||||
(case newCmd of
|
(case newCmd of
|
||||||
CHAR_EVENT chr =>
|
CHAR_EVENT chr =>
|
||||||
deleteToChr (app, 1, Cursor.tillPrevChr, op-, chr)
|
deleteToChr (app, 1, Cursor.tillPrevChr, op-, chr)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList))
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList))
|
||||||
| #"f" =>
|
| #"f" =>
|
||||||
(case newCmd of
|
(case newCmd of
|
||||||
CHAR_EVENT chr =>
|
CHAR_EVENT chr =>
|
||||||
deleteToChr (app, count, Cursor.toNextChr, op+, chr)
|
deleteToChr (app, count, Cursor.toNextChr, op+, chr)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList))
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList))
|
||||||
| #"F" =>
|
| #"F" =>
|
||||||
(* delete to chr, backwards *)
|
(* delete to chr, backwards *)
|
||||||
(case newCmd of
|
(case newCmd of
|
||||||
CHAR_EVENT chr =>
|
CHAR_EVENT chr =>
|
||||||
deleteToChr (app, count, Cursor.toPrevChr, op-, chr)
|
deleteToChr (app, count, Cursor.toPrevChr, op-, chr)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList))
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList))
|
||||||
| #"g" =>
|
| #"g" =>
|
||||||
(* same events as handleGo *)
|
(* same events as handleGo *)
|
||||||
(case newCmd of
|
(case newCmd of
|
||||||
@@ -926,11 +810,11 @@ struct
|
|||||||
#"e" => deleteByDfa (app, count, Cursor.endOfPrevWord)
|
#"e" => deleteByDfa (app, count, Cursor.endOfPrevWord)
|
||||||
| #"E" => deleteByDfa (app, count, Cursor.endOfPrevWORD)
|
| #"E" => deleteByDfa (app, count, Cursor.endOfPrevWORD)
|
||||||
| #"g" => deleteToStart app
|
| #"g" => deleteToStart app
|
||||||
| _ => clearMode app)
|
| _ => Finish.clearMode app)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList))
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList))
|
||||||
| _ => clearMode app
|
| _ => Finish.clearMode app
|
||||||
|
|
||||||
(* useful reference as list of non-terminal commands *)
|
(* useful reference as list of non-terminal commands *)
|
||||||
fun parseAfterCount (strPos, str, count, app, newCmd) =
|
fun parseAfterCount (strPos, str, count, app, newCmd) =
|
||||||
@@ -950,7 +834,7 @@ struct
|
|||||||
| #"T" =>
|
| #"T" =>
|
||||||
(* to just before chr, backward *)
|
(* to just before chr, backward *)
|
||||||
handleMoveToChr (1, app, Cursor.tillPrevChr, newCmd)
|
handleMoveToChr (1, app, Cursor.tillPrevChr, newCmd)
|
||||||
| #"y" => (* yank *) clearMode app
|
| #"y" => (* yank *) Finish.clearMode app
|
||||||
| #"d" => (* delete *) parseDelete (strPos, str, count, app, newCmd)
|
| #"d" => (* delete *) parseDelete (strPos, str, count, app, newCmd)
|
||||||
| #"f" =>
|
| #"f" =>
|
||||||
(* to chr, forward *)
|
(* to chr, forward *)
|
||||||
@@ -959,28 +843,28 @@ struct
|
|||||||
(* to chr, backward *)
|
(* to chr, backward *)
|
||||||
handleMoveToChr (count, app, Cursor.toPrevChr, newCmd)
|
handleMoveToChr (count, app, Cursor.toPrevChr, newCmd)
|
||||||
| #"g" => (* go *) handleGo (count, app, newCmd)
|
| #"g" => (* go *) handleGo (count, app, newCmd)
|
||||||
| #"c" => (* change *) clearMode app
|
| #"c" => (* change *) Finish.clearMode app
|
||||||
| _ =>
|
| _ =>
|
||||||
(* isn't a non-terminal cmd
|
(* isn't a non-terminal cmd
|
||||||
* this case should never happen*)
|
* this case should never happen*)
|
||||||
clearMode app
|
Finish.clearMode app
|
||||||
|
|
||||||
fun parseNormalModeCommand (app, str, newCmd) =
|
fun parseNormalModeCommand (app, str, newCmd) =
|
||||||
if String.size str = 0 then
|
if String.size str = 0 then
|
||||||
case newCmd of
|
case newCmd of
|
||||||
CHAR_EVENT chr => handleChr (app, 1, chr, str)
|
CHAR_EVENT chr => handleChr (app, 1, chr, str)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList)
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
|
||||||
else if String.size str = 1 then
|
else if String.size str = 1 then
|
||||||
case newCmd of
|
case newCmd of
|
||||||
CHAR_EVENT chr =>
|
CHAR_EVENT chr =>
|
||||||
(case Int.fromString str of
|
(case Int.fromString str of
|
||||||
SOME count => handleChr (app, count, chr, str)
|
SOME count => handleChr (app, count, chr, str)
|
||||||
| NONE => parseAfterCount (0, str, 1, app, newCmd))
|
| NONE => parseAfterCount (0, str, 1, app, newCmd))
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList)
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val numLength = getNumLength (0, str)
|
val numLength = getNumLength (0, str)
|
||||||
@@ -994,9 +878,9 @@ struct
|
|||||||
(* reached end of str; str only contained numbers *)
|
(* reached end of str; str only contained numbers *)
|
||||||
case newCmd of
|
case newCmd of
|
||||||
CHAR_EVENT chr => handleChr (app, count, chr, str)
|
CHAR_EVENT chr => handleChr (app, count, chr, str)
|
||||||
| KEY_ESC => clearMode app
|
| KEY_ESC => Finish.clearMode app
|
||||||
| RESIZE_EVENT (width, height) => resizeText (app, width, height)
|
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
|
||||||
| WITH_SEARCH_LIST searchList => withSearchList (app, searchList)
|
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
|
||||||
else
|
else
|
||||||
(* continue parsing. *)
|
(* continue parsing. *)
|
||||||
parseAfterCount (numLength, str, count, app, newCmd)
|
parseAfterCount (numLength, str, count, app, newCmd)
|
||||||
|
|||||||
119
fcore/finish.sml
119
fcore/finish.sml
@@ -2,6 +2,13 @@ structure Finish =
|
|||||||
struct
|
struct
|
||||||
open AppType
|
open AppType
|
||||||
|
|
||||||
|
open MailboxType
|
||||||
|
open DrawMsg
|
||||||
|
open InputMsg
|
||||||
|
|
||||||
|
fun clearMode app =
|
||||||
|
AppWith.mode (app, NORMAL_MODE "", [])
|
||||||
|
|
||||||
fun buildTextAndClear (app: app_type, buffer, cursorIdx, searchList, msgs) =
|
fun buildTextAndClear (app: app_type, buffer, cursorIdx, searchList, msgs) =
|
||||||
let
|
let
|
||||||
val {windowWidth, windowHeight, startLine, searchString, ...} = app
|
val {windowWidth, windowHeight, startLine, searchString, ...} = app
|
||||||
@@ -32,4 +39,116 @@ struct
|
|||||||
AppWith.bufferAndCursorIdx
|
AppWith.bufferAndCursorIdx
|
||||||
(app, buffer, cursorIdx, mode, startLine, searchList, msgs)
|
(app, buffer, cursorIdx, mode, startLine, searchList, msgs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fun withSearchList (app: app_type, searchList) =
|
||||||
|
let
|
||||||
|
val {buffer, searchString, cursorIdx, ...} = app
|
||||||
|
val app = AppWith.searchList (app, searchList, buffer, searchString)
|
||||||
|
in
|
||||||
|
buildTextAndClear (app, buffer, cursorIdx, searchList, [])
|
||||||
|
end
|
||||||
|
|
||||||
|
fun resizeText (app: app_type, newWidth, newHeight) =
|
||||||
|
let
|
||||||
|
val
|
||||||
|
{ buffer
|
||||||
|
, windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, startLine
|
||||||
|
, cursorIdx
|
||||||
|
, searchList
|
||||||
|
, searchString
|
||||||
|
, ...
|
||||||
|
} = app
|
||||||
|
|
||||||
|
val newBuffer = LineGap.goToLine (startLine, buffer)
|
||||||
|
val lineIdx = TextBuilder.getLineAbsIdx (startLine, buffer)
|
||||||
|
|
||||||
|
val drawMsg = TextBuilder.build
|
||||||
|
( startLine
|
||||||
|
, cursorIdx
|
||||||
|
, newBuffer
|
||||||
|
, newWidth
|
||||||
|
, newHeight
|
||||||
|
, searchList
|
||||||
|
, searchString
|
||||||
|
, []
|
||||||
|
)
|
||||||
|
in
|
||||||
|
AppWith.bufferAndSize
|
||||||
|
(app, newBuffer, newWidth, newHeight, searchList, drawMsg)
|
||||||
|
end
|
||||||
|
|
||||||
|
(* Difference between this and buildTextAndClear is that
|
||||||
|
* this is meant to be called after a chr movement,
|
||||||
|
* where the cursor may possibly jump off window by a wide marigin.
|
||||||
|
* Since the cursor may move away a lot, it is best to recenter.
|
||||||
|
* *)
|
||||||
|
fun buildTextAndClearAfterChr
|
||||||
|
(app: app_type, buffer, cursorIdx, searchList, initialMsg) =
|
||||||
|
let
|
||||||
|
val {windowWidth, windowHeight, startLine, searchString, ...} = app
|
||||||
|
|
||||||
|
(* move LineGap to first line displayed on screen *)
|
||||||
|
val buffer = LineGap.goToLine (startLine, buffer)
|
||||||
|
|
||||||
|
(* get new startLine which may move screen depending on cursor movements *)
|
||||||
|
val startLine = TextWindow.getStartLine
|
||||||
|
(buffer, startLine, cursorIdx, windowWidth, windowHeight)
|
||||||
|
|
||||||
|
(* move buffer to new startLine as required by TextBuilder.build
|
||||||
|
* and move searchList to idx where line starts as well *)
|
||||||
|
val buffer = LineGap.goToLine (startLine, buffer)
|
||||||
|
|
||||||
|
val drawMsg = TextBuilder.build
|
||||||
|
( startLine
|
||||||
|
, cursorIdx
|
||||||
|
, buffer
|
||||||
|
, windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, searchList
|
||||||
|
, searchString
|
||||||
|
, []
|
||||||
|
)
|
||||||
|
|
||||||
|
val mode = NORMAL_MODE ""
|
||||||
|
in
|
||||||
|
AppWith.bufferAndCursorIdx
|
||||||
|
(app, buffer, cursorIdx, mode, startLine, searchList, drawMsg)
|
||||||
|
end
|
||||||
|
|
||||||
|
fun centreToCursor (app: app_type) =
|
||||||
|
let
|
||||||
|
val
|
||||||
|
{ buffer
|
||||||
|
, windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, startLine = origLine
|
||||||
|
, cursorIdx
|
||||||
|
, searchList
|
||||||
|
, searchString
|
||||||
|
, ...
|
||||||
|
} = app
|
||||||
|
val buffer = LineGap.goToIdx (cursorIdx, buffer)
|
||||||
|
|
||||||
|
val startLine = TextWindow.getStartLineWithCursorCentered
|
||||||
|
(buffer, cursorIdx, origLine, windowWidth, windowHeight div 2)
|
||||||
|
|
||||||
|
val buffer = LineGap.goToLine (startLine, buffer)
|
||||||
|
val lineIdx = TextBuilder.getLineAbsIdx (startLine, buffer)
|
||||||
|
|
||||||
|
val drawMsg = TextBuilder.build
|
||||||
|
( startLine
|
||||||
|
, cursorIdx
|
||||||
|
, buffer
|
||||||
|
, windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, searchList
|
||||||
|
, searchString
|
||||||
|
, []
|
||||||
|
)
|
||||||
|
in
|
||||||
|
AppWith.bufferAndCursorIdx
|
||||||
|
(app, buffer, cursorIdx, NORMAL_MODE "", startLine, searchList, drawMsg)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
3
fcore/normal-mode/normal-move.sml
Normal file
3
fcore/normal-mode/normal-move.sml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
structure NormalMove =
|
||||||
|
struct
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
$(SML_LIB)/basis/basis.mlb
|
$(SML_LIB)/basis/basis.mlb
|
||||||
|
|
||||||
(* LIBRARIEES *)
|
(* LIBRARIES *)
|
||||||
lib/brolib-sml/src/line_gap.sml
|
lib/brolib-sml/src/line_gap.sml
|
||||||
lib/brolib-sml/src/gap_set.sml
|
lib/brolib-sml/src/gap_set.sml
|
||||||
lib/cozette-sml/fonts/cozette-ascii.mlb
|
lib/cozette-sml/fonts/cozette-ascii.mlb
|
||||||
@@ -32,8 +32,10 @@ fcore/text-window.sml
|
|||||||
|
|
||||||
fcore/finish.sml
|
fcore/finish.sml
|
||||||
fcore/move.sml
|
fcore/move.sml
|
||||||
|
fcore/normal-mode/normal-move.sml
|
||||||
fcore/app-update.sml
|
fcore/app-update.sml
|
||||||
|
|
||||||
|
|
||||||
(* TEST FILES *)
|
(* TEST FILES *)
|
||||||
$(SML_LIB)/basis/mlton.mlb
|
$(SML_LIB)/basis/mlton.mlb
|
||||||
|
|
||||||
|
|||||||
3
shf.mlb
3
shf.mlb
@@ -1,6 +1,6 @@
|
|||||||
$(SML_LIB)/basis/basis.mlb
|
$(SML_LIB)/basis/basis.mlb
|
||||||
|
|
||||||
(* LIBRARIEES *)
|
(* LIBRARIES *)
|
||||||
lib/brolib-sml/src/line_gap.sml
|
lib/brolib-sml/src/line_gap.sml
|
||||||
lib/brolib-sml/src/gap_set.sml
|
lib/brolib-sml/src/gap_set.sml
|
||||||
lib/cozette-sml/fonts/cozette-ascii.mlb
|
lib/cozette-sml/fonts/cozette-ascii.mlb
|
||||||
@@ -32,6 +32,7 @@ fcore/text-window.sml
|
|||||||
|
|
||||||
fcore/finish.sml
|
fcore/finish.sml
|
||||||
fcore/move.sml
|
fcore/move.sml
|
||||||
|
fcore/normal-mode/normal-move.sml
|
||||||
fcore/app-update.sml
|
fcore/app-update.sml
|
||||||
|
|
||||||
(* IMPERATIVE SHELL *)
|
(* IMPERATIVE SHELL *)
|
||||||
|
|||||||
Reference in New Issue
Block a user