Files
sml-projects/shf/fcore/cursor-dfa/vi-caps-word-dfa.sml
Humza Shahid 6b91d64fc3 Add 'shf/' from commit 'b6c5a95b664aeb861d7b33ffc9eefe447ba99dd7'
git-subtree-dir: shf
git-subtree-mainline: 401408448f
git-subtree-split: b6c5a95b66
2026-04-24 00:27:49 +01:00

240 lines
6.5 KiB
Standard ML

structure ViCapsWordDfa =
struct
val startState: Word8.word = 0w0
val startNonBlankState: Word8.word = 0w1
val startSpaceState: Word8.word = 0w2
val nonBlankAfterSpaceState: Word8.word = 0w3
val spaceAfterNonBlankState = 0w4
val startNewline: Word8.word = 0w5
val newlineToNewline: Word8.word = 0w6
val chrToNewline: Word8.word = 0w07
fun makeStart i =
let
val chr = Char.chr i
in
if chr = #"\n" then startNewline
else if Char.isSpace chr then startSpaceState
else startNonBlankState
end
fun makeStartNonBlankState i =
let
val chr = Char.chr i
in
if chr = #"\n" then chrToNewline
else if Char.isSpace chr then spaceAfterNonBlankState
else startNonBlankState
end
fun makeStartSpace i =
let
val chr = Char.chr i
in
if chr = #"\n" then chrToNewline
else if Char.isSpace chr then startSpaceState
else nonBlankAfterSpaceState
end
fun makeNonBlankAfterSpace i =
let
val chr = Char.chr i
in
if chr = #"\n" then chrToNewline
else if Char.isSpace chr then spaceAfterNonBlankState
else nonBlankAfterSpaceState
end
fun makeStartNewline i =
let
val chr = Char.chr i
in
if chr = #"\n" then newlineToNewline
else if Char.isSpace chr then startSpaceState
else nonBlankAfterSpaceState
end
val startTable = Vector.tabulate (255, makeStart)
val startNonBlankTable = Vector.tabulate (255, makeStartNonBlankState)
val startSpaceTable = Vector.tabulate (255, makeStartSpace)
val nonBlankAfterSpaceTable = Vector.tabulate (255, makeNonBlankAfterSpace)
val spaceAfterNonBlankTable = nonBlankAfterSpaceTable
val newlineTable = Vector.tabulate (255, makeStartNewline)
val tables =
#[ startTable
, startNonBlankTable
, startSpaceTable
, nonBlankAfterSpaceTable
, spaceAfterNonBlankTable
, newlineTable
, newlineTable
, newlineTable
]
structure StartOfNextWORD =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun finish x = x
fun isFinal currentState =
currentState = nonBlankAfterSpaceState
orelse currentState = newlineToNewline
end)
val fStart = Folder.foldNext
end)
structure StartOfNextWORDForDelete =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun finish x = x
fun isFinal currentState =
currentState = nonBlankAfterSpaceState
orelse currentState = chrToNewline
end)
val fStart = Folder.foldNext
end)
structure EndOfPrevWORD =
MakePrevDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderPrev
(struct
val startState = startState
val tables = tables
fun finish x = x
fun isFinal currentState =
currentState = nonBlankAfterSpaceState
end)
val fStart = Folder.foldPrev
end)
structure StartOfCurrentWORDFolder =
MakeCharFolderPrev
(struct
val startState = startState
val tables = tables
fun isFinal currentState =
currentState = spaceAfterNonBlankState
orelse currentState = chrToNewline
orelse currentState = newlineToNewline
fun finish idx = idx + 1
end)
structure StartOfCurrentWORD =
MakePrevDfaLoopMinus1
(struct
val startState = startState
val fStart = StartOfCurrentWORDFolder.foldPrev
end)
structure StartOfNextWORDStrict =
MakePrevDfaLoop
(struct
val startState = startState
val fStart = StartOfCurrentWORDFolder.foldPrev
end)
fun endOfCurrentWORDFolderIsFinal currentState =
currentState = spaceAfterNonBlankState orelse currentState = chrToNewline
structure EndOfCurrentWORDFolder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
val isFinal = endOfCurrentWORDFolderIsFinal
fun finish idx =
Int.max (0, idx - 1)
end)
structure EndOfCurrentWORD =
MakeNextDfaLoopPlus1
(struct
val startState = startState
val fStart = EndOfCurrentWORDFolder.foldNext
end)
structure EndOfCurrentWORDForDelete =
MakeNextDfaLoopPlus1
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
val isFinal = endOfCurrentWORDFolderIsFinal
fun finish idx = idx
end)
val fStart = Folder.foldNext
end)
structure EndOfCurrentWORDStrict =
MakeNextDfaLoop
(struct
val startState = startState
val fStart = EndOfCurrentWORDFolder.foldNext
end)
(* W *)
val startOfNextWORD = StartOfNextWORD.next
val startOfNextWORDForDelete = StartOfNextWORDForDelete.next
(* gE *)
val endOfPrevWORD = EndOfPrevWORD.prev
(* B *)
val startOfCurrentWORD = StartOfCurrentWORD.prev
(* E *)
val endOfCurrentWORD = EndOfCurrentWORD.next
val endOfCurrentWORDForDelete = EndOfCurrentWORDForDelete.next
(* functions to strictly get the start and end of the current word.
* Problem: We want to support Vi motions like viW (selects a single word),
* as well as ciW (change one WORD) and diW (delete one WORD).
*
* The 'startOfCurrentWORD' and 'endOfCurrentWORD' functions do this
* (representing the vi 'B' and 'E' commands respectively),
* except that 'B' goes to the previous WORD if the cursor is on the first
* character of the current WORD, and 'E' goes to the next WORD if the cursor
* is on the last character of the current WORD.
*
* What is meant by "strict" is that these below functions always stay
* within the current WORD, not making the two exceptions mentioned above.
*)
val startOfCurrentWORDStrict = StartOfNextWORDStrict.prev
val endOfCurrentWORDStrict = EndOfCurrentWORDStrict.next
end