a bit of refactoring

This commit is contained in:
2025-08-31 06:28:05 +01:00
parent 542da2229c
commit a86befdea8
10 changed files with 203 additions and 193 deletions

View File

@@ -16,7 +16,8 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
in
Finish.buildTextAndClear (app, buffer, low, searchList, initialMsg, time)
NormalFinish.buildTextAndClear
(app, buffer, low, searchList, initialMsg, time)
end
(* equivalent of vi's 'x' command **)
@@ -31,7 +32,7 @@ struct
val searchList =
SearchList.buildRange (buffer, searchString, cursorIdx + 1111)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, cursorIdx, searchList, initialMsg, time)
end
else
@@ -119,7 +120,7 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
val cursorIdx = Cursor.clipIdx (buffer, low)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, cursorIdx, searchList, initialMsg, time)
end
else
@@ -158,7 +159,7 @@ struct
if Cursor.isCursorAtStartOfLine (buffer, cursorIdx) then
(* if we are on \n, we don't want to delete or do anything
* so reset the mode *)
Finish.clearMode app
NormalFinish.clearMode app
else
let
(* viDlr takes us to the last chr in the line
@@ -317,7 +318,7 @@ struct
val mode = NORMAL_MODE ""
in
AppWith.bufferAndCursorIdx
NormalModeWith.bufferAndCursorIdx
(app, buffer, cursorIdx, mode, startLine, searchList, drawMsg, time)
end
@@ -335,7 +336,8 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
in
Finish.buildTextAndClear (app, buffer, low, searchList, initialMsg, time)
NormalFinish.buildTextAndClear
(app, buffer, low, searchList, initialMsg, time)
end
fun deleteToNextMatch (app: app_type, count, time) =
@@ -344,7 +346,7 @@ struct
val newCursorIdx = SearchList.nextMatch (cursorIdx, searchList, count)
in
if newCursorIdx = ~1 orelse newCursorIdx <= cursorIdx then
Finish.clearMode app
NormalFinish.clearMode app
else
helpDeleteToMatch (app, cursorIdx, newCursorIdx, time)
end
@@ -355,7 +357,7 @@ struct
val newCursorIdx = SearchList.prevMatch (cursorIdx, searchList, count)
in
if newCursorIdx = ~1 orelse newCursorIdx >= cursorIdx then
Finish.clearMode app
NormalFinish.clearMode app
else
helpDeleteToMatch (app, newCursorIdx, cursorIdx, time)
end
@@ -383,7 +385,7 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, low, searchList, initialMsg, time)
end
end
@@ -411,14 +413,14 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, low, searchList, initialMsg, time)
end
end
fun finishAfterDeleteInside (app: app_type, origLow, high, time) =
if origLow = high then
Finish.clearMode app
NormalFinish.clearMode app
else
let
val {cursorIdx, buffer, searchString, ...} = app
@@ -430,11 +432,12 @@ struct
val initialMsg = [SEARCH (buffer, searchString)]
val buffer = LineGap.goToIdx (low - 1111, buffer)
val searchList = SearchList.buildRange (buffer, searchString, low + 1111)
val searchList =
SearchList.buildRange (buffer, searchString, low + 1111)
val buffer = LineGap.goToIdx (origLow, buffer)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, origLow, searchList, initialMsg, time)
end
@@ -477,7 +480,7 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
val high = Cursor.matchPair (buffer, low)
in
if low = high then Finish.clearMode app
if low = high then NormalFinish.clearMode app
else deleteAndFinish (app, low, high - low + 1, buffer, time)
end
@@ -492,7 +495,7 @@ struct
val buffer = LineGap.goToIdx (high, buffer)
val low = Cursor.matchPair (buffer, high)
in
if low = high then Finish.clearMode app
if low = high then NormalFinish.clearMode app
else deleteAndFinish (app, low, high - low + 1, buffer, time)
end
@@ -502,7 +505,7 @@ struct
val otherIdx = Cursor.matchPair (buffer, cursorIdx)
in
if otherIdx = cursorIdx then
Finish.clearMode app
NormalFinish.clearMode app
else
let
val low = Int.min (cursorIdx, otherIdx)
@@ -530,7 +533,7 @@ struct
val buffer = LineGap.goToIdx (low, buffer)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, low, searchList, initialMsg, time)
end
end

View File

@@ -0,0 +1,190 @@
structure NormalFinish =
struct
open AppType
open MailboxType
open DrawMsg
open InputMsg
fun clearMode app =
NormalModeWith.mode (app, NORMAL_MODE "", [])
fun buildTextAndClear
(app: app_type, buffer, cursorIdx, searchList, msgs, bufferModifyTime) =
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 *)
val buffer = LineGap.goToLine (startLine, buffer)
val msgs = TextBuilder.build
( startLine
, cursorIdx
, buffer
, windowWidth
, windowHeight
, searchList
, searchString
, msgs
)
val mode = NORMAL_MODE ""
in
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
, mode
, startLine
, searchList
, msgs
, bufferModifyTime
)
end
fun withSearchList (app: app_type, searchList) =
let
val {buffer, searchString, cursorIdx, bufferModifyTime, ...} = app
val app = NormalModeWith.searchList
(app, searchList, buffer, searchString, bufferModifyTime)
in
buildTextAndClear
(app, buffer, cursorIdx, searchList, [], bufferModifyTime)
end
fun resizeText (app: app_type, newWidth, newHeight) =
let
val
{ buffer
, windowWidth
, windowHeight
, startLine
, cursorIdx
, searchList
, searchString
, bufferModifyTime
, ...
} = 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
NormalModeWith.bufferAndSize
( app
, newBuffer
, newWidth
, newHeight
, searchList
, drawMsg
, bufferModifyTime
)
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, bufferModifyTime) =
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
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
, mode
, startLine
, searchList
, drawMsg
, bufferModifyTime
)
end
fun centreToCursor (app: app_type) =
let
val
{ buffer
, windowWidth
, windowHeight
, startLine = origLine
, cursorIdx
, searchList
, searchString
, bufferModifyTime
, ...
} = 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
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
, NORMAL_MODE ""
, startLine
, searchList
, drawMsg
, bufferModifyTime
)
end
end

View File

@@ -0,0 +1,139 @@
structure NormalModeWith =
struct
open AppType
fun bufferAndSize
( app: app_type
, newBuffer
, newWidth
, newHeight
, newSearchList
, newMsgs
, newBufferModifyTime
) =
let
val
{ mode
, buffer = _
, bufferModifyTime = _
, windowWidth = _
, windowHeight = _
, searchList = _
, msgs = _
, searchString
, startLine
, cursorIdx
} = app
in
{ mode = mode
, buffer = newBuffer
, bufferModifyTime = newBufferModifyTime
, windowWidth = newWidth
, windowHeight = newHeight
, searchList = newSearchList
, msgs = newMsgs
, searchString = searchString
, startLine = startLine
, cursorIdx = cursorIdx
}
end
fun bufferAndCursorIdx
( app: app_type
, newBuffer
, newCursorIdx
, newMode
, newStartLine
, newSearchList
, newMsgs
, newBufferModifyTime
) =
let
val
{ mode = _
, buffer = _
, bufferModifyTime = _
, cursorIdx = _
, startLine = _
, searchList = _
, msgs = _
, searchString
, windowWidth
, windowHeight
} = app
in
{ mode = newMode
, buffer = newBuffer
, bufferModifyTime = newBufferModifyTime
, cursorIdx = newCursorIdx
, startLine = newStartLine
, searchList = newSearchList
, msgs = newMsgs
, searchString = searchString
, windowWidth = windowWidth
, windowHeight = windowHeight
}
end
fun mode (app: app_type, newMode, newMsgs) =
let
val
{ mode = _
, msgs = _
, buffer
, bufferModifyTime
, searchList
, searchString
, cursorIdx
, windowWidth
, windowHeight
, startLine
} = app
in
{ mode = newMode
, msgs = newMsgs
, buffer = buffer
, bufferModifyTime = bufferModifyTime
, searchList = searchList
, searchString = searchString
, cursorIdx = cursorIdx
, windowWidth = windowWidth
, windowHeight = windowHeight
, startLine = startLine
}
end
fun searchList
( app: app_type
, newSearchList
, newBuffer
, newSearchString
, newBufferModifyTime
) =
let
val
{ searchList = _
, buffer = _
, bufferModifyTime
, searchString = _
, msgs
, mode
, cursorIdx
, windowWidth
, windowHeight
, startLine
} = app
in
{ searchList = newSearchList
, buffer = newBuffer
, bufferModifyTime = newBufferModifyTime
, searchString = newSearchString
, msgs = msgs
, mode = mode
, cursorIdx = cursorIdx
, windowWidth = windowWidth
, windowHeight = windowHeight
, startLine = startLine
}
end
end

View File

@@ -12,7 +12,7 @@ struct
NORMAL_SEARCH_MODE
{searchString = "", tempSearchList = Vector.fromList []}
in
AppWith.mode (app, mode, [])
NormalModeWith.mode (app, mode, [])
end
fun getNumLength (pos, str) =
@@ -28,7 +28,7 @@ struct
val str = str ^ Char.toString chr
val mode = NORMAL_MODE str
in
AppWith.mode (app, mode, [])
NormalModeWith.mode (app, mode, [])
end
fun parseMoveToChr (count, app, fMove, chrCmd) =
@@ -39,7 +39,7 @@ struct
#"e" => MoveToEndOfPrevWord.move (app, count)
| #"E" => MoveToEndOfPrevWORD.move (app, count)
| #"g" => NormalMove.moveToStart app
| _ => Finish.clearMode app
| _ => NormalFinish.clearMode app
fun parseChr (app: app_type, count, chr, str, time) =
case chr of
@@ -55,7 +55,7 @@ struct
| #"E" => MoveToEndOfWORD.move (app, count)
| #"n" => NormalMove.moveToNextMatch (app, count)
| #"N" => NormalMove.moveToPrevMatch (app, count)
| #"z" => Finish.centreToCursor app
| #"z" => NormalFinish.centreToCursor app
(* can only move to start or end of line once
* so hardcode count as 1 *)
| #"0" =>
@@ -75,7 +75,7 @@ struct
val str = str ^ chr
val mode = NORMAL_MODE str
in
AppWith.mode (app, mode, [])
NormalModeWith.mode (app, mode, [])
end
else
MoveToStartOfLine.move (app, 1)
@@ -110,7 +110,7 @@ struct
val str = if Char.isDigit chr then str ^ Char.toString chr else ""
val mode = NORMAL_MODE str
in
AppWith.mode (app, mode, [])
NormalModeWith.mode (app, mode, [])
end
fun parseDeleteInside (app, chr, time) =
@@ -125,7 +125,7 @@ struct
| #"]" => NormalDelete.deleteInsideChrClose (app, chr, time)
| #"}" => NormalDelete.deleteInsideChrClose (app, chr, time)
| #">" => NormalDelete.deleteInsideChrClose (app, chr, time)
| _ => Finish.clearMode app
| _ => NormalFinish.clearMode app
fun parseDeleteAround (app, chr, time) =
case chr of
@@ -137,7 +137,7 @@ struct
| #"]" => NormalDelete.deleteAroundChrClose (app, chr, time)
| #"}" => NormalDelete.deleteAroundChrClose (app, chr, time)
| #">" => NormalDelete.deleteAroundChrClose (app, chr, time)
| _ => Finish.clearMode app
| _ => NormalFinish.clearMode app
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
case chrCmd of
@@ -174,14 +174,14 @@ struct
| #"i" => appendChr (app, chrCmd, str)
| #"a" => appendChr (app, chrCmd, str)
(* invalid command: reset mode *)
| _ => Finish.clearMode app
| _ => NormalFinish.clearMode app
fun parseDeleteGo (app, count, chrCmd, time) =
case chrCmd of
#"e" => NormalDelete.deleteByDfa (app, count, Cursor.endOfPrevWord, time)
| #"E" => NormalDelete.deleteByDfa (app, count, Cursor.endOfPrevWORD, time)
| #"g" => NormalDelete.deleteToStart (app, time)
| _ => Finish.clearMode app
| _ => NormalFinish.clearMode app
fun parseDelete (strPos, str, count, app, chrCmd, time) =
if strPos = String.size str - 1 then
@@ -204,7 +204,7 @@ struct
| #"g" => parseDeleteGo (app, count, chrCmd, time)
| #"i" => parseDeleteInside (app, chrCmd, time)
| #"a" => parseDeleteAround (app, chrCmd, time)
| _ => Finish.clearMode app
| _ => NormalFinish.clearMode app
(* useful reference as list of non-terminal commands *)
fun parseAfterCount (strPos, str, count, app, chrCmd, time) =
@@ -224,7 +224,7 @@ struct
| #"T" =>
(* to just before chr, backward *)
parseMoveToChr (1, app, Cursor.tillPrevChr, chrCmd)
| #"y" => (* yank *) Finish.clearMode app
| #"y" => (* yank *) NormalFinish.clearMode app
| #"d" => (* delete *) parseDelete (strPos, str, count, app, chrCmd, time)
| #"f" =>
(* to chr, forward *)
@@ -233,11 +233,11 @@ struct
(* to chr, backward *)
parseMoveToChr (count, app, Cursor.toPrevChr, chrCmd)
| #"g" => (* go *) parseGo (count, app, chrCmd)
| #"c" => (* change *) Finish.clearMode app
| #"c" => (* change *) NormalFinish.clearMode app
| _ =>
(* isn't a non-terminal cmd
* this case should never happen*)
Finish.clearMode app
NormalFinish.clearMode app
fun parseNormalModeCommand (app, str, chrCmd, time) =
if String.size str = 0 then
@@ -266,8 +266,10 @@ struct
fun update (app, str, msg, time) =
case msg of
CHAR_EVENT chrCmd => parseNormalModeCommand (app, str, chrCmd, time)
| KEY_ESC => Finish.clearMode app
| RESIZE_EVENT (width, height) => Finish.resizeText (app, width, height)
| WITH_SEARCH_LIST searchList => Finish.withSearchList (app, searchList)
| KEY_ESC => NormalFinish.clearMode app
| RESIZE_EVENT (width, height) =>
NormalFinish.resizeText (app, width, height)
| WITH_SEARCH_LIST searchList =>
NormalFinish.withSearchList (app, searchList)
| KEY_ENTER => app
end

View File

@@ -31,7 +31,7 @@ struct
val mode = NORMAL_MODE ""
in
AppWith.bufferAndCursorIdx
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
@@ -87,7 +87,7 @@ struct
val mode = NORMAL_MODE ""
in
AppWith.bufferAndCursorIdx
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, bufferIdx
@@ -139,7 +139,7 @@ struct
val mode = NORMAL_MODE ""
in
AppWith.bufferAndCursorIdx
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
@@ -189,7 +189,7 @@ struct
, []
)
in
AppWith.bufferAndCursorIdx
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
@@ -221,7 +221,7 @@ struct
, []
)
in
AppWith.bufferAndCursorIdx
NormalModeWith.bufferAndCursorIdx
( app
, buffer
, cursorIdx
@@ -255,13 +255,13 @@ struct
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val cursorIdx = Cursor.firstNonSpaceChr (buffer, cursorIdx)
in
Finish.buildTextAndClear
NormalFinish.buildTextAndClear
(app, buffer, cursorIdx, searchList, [], bufferModifyTime)
end
fun helpMoveToChr (app: app_type, buffer, cursorIdx, count, fMove, chr) =
if count = 0 then
Finish.buildTextAndClearAfterChr
NormalFinish.buildTextAndClearAfterChr
(app, buffer, cursorIdx, #searchList app, [], #bufferModifyTime app)
else
let
@@ -284,9 +284,9 @@ struct
val newCursorIdx = SearchList.nextMatch (cursorIdx, searchList, count)
in
if newCursorIdx = ~1 then
Finish.clearMode app
NormalFinish.clearMode app
else
Finish.buildTextAndClearAfterChr
NormalFinish.buildTextAndClearAfterChr
(app, buffer, newCursorIdx, searchList, [], bufferModifyTime)
end
@@ -296,9 +296,9 @@ struct
val newCursorIdx = SearchList.prevMatch (cursorIdx, searchList, count)
in
if newCursorIdx = ~1 then
Finish.clearMode app
NormalFinish.clearMode app
else
Finish.buildTextAndClearAfterChr
NormalFinish.buildTextAndClearAfterChr
(app, buffer, newCursorIdx, searchList, [], bufferModifyTime)
end
end

View File

@@ -18,7 +18,7 @@ struct
NORMAL_SEARCH_MODE
{searchString = searchString, tempSearchList = tempSearchList}
in
AppWith.mode (app, mode, [])
NormalModeWith.mode (app, mode, [])
end
(* todo: switch to normal mode, save tempSearchList and searchString,
@@ -28,7 +28,7 @@ struct
fun update (app, {searchString, tempSearchList}, msg, time) =
case msg of
CHAR_EVENT chr => parseChr (app, searchString, chr)
| KEY_ESC => Finish.clearMode app
| KEY_ESC => NormalFinish.clearMode app
| KEY_ENTER => finishSearch (app, searchString, tempSearchList)
| RESIZE_EVENT (width, height) => app
| WITH_SEARCH_LIST searchList => app