implement 'daw' motion

This commit is contained in:
2025-12-13 03:40:32 +00:00
parent 7130fe7dda
commit 204f549c79
4 changed files with 208 additions and 2 deletions

View File

@@ -619,7 +619,177 @@ struct
fun lastContiguousNonSpace (lineGap, cursorIdx) =
LastContiguousNonSpace.foldNext (lineGap, cursorIdx, ())
(* Prerequisite: lineGap is moved to cursorIdx *)
structure AroundWordPrev =
MakeIfCharFolderPrev
(struct
type env = unit
fun loopAlphaNum (strPos, shd, absIdx, stl) =
if strPos < 0 then
case stl of
shd :: stl =>
loopAlphaNum (String.size shd - 1, shd, absIdx, stl)
| [] => 0
else
let
val chr = String.sub (shd, strPos)
in
if Char.isAlphaNum chr orelse chr = #"_" then
loopAlphaNum (strPos - 1, shd, absIdx - 1, stl)
else
absIdx + 1
end
fun loopPunct (strPos, shd, absIdx, stl) =
if strPos < 0 then
case stl of
shd :: stl => loopPunct (String.size shd - 1, shd, absIdx, stl)
| [] => 0
else
let
val chr = String.sub (shd, strPos)
in
if
Char.isAlphaNum chr orelse chr = #"_" orelse chr = #"\n"
orelse Char.isSpace chr
then absIdx + 1
else (* is punct *) loopPunct (strPos - 1, shd, absIdx - 1, stl)
end
fun loopSpace (strPos, shd, absIdx, stl) =
if strPos < 0 then
case stl of
shd :: stl => loopSpace (String.size shd - 1, shd, absIdx, stl)
| [] => 0
else
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx + 1
else if Char.isSpace chr then
loopSpace (strPos - 1, shd, absIdx - 1, stl)
else
absIdx + 1
end
fun fStart (strPos, shd, _, absIdx, stl, _, _) =
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx
else if Char.isAlphaNum chr orelse chr = #"_" then
loopAlphaNum (strPos - 1, shd, absIdx - 1, stl)
else if Char.isSpace chr then
loopSpace (strPos - 1, shd, absIdx - 1, stl)
else
loopPunct (strPos - 1, shd, absIdx - 1, stl)
end
end)
fun aroundWordPrev (lineGap, cursorIdx) =
AroundWordPrev.foldPrev (lineGap, cursorIdx, ())
structure AroundWordNext =
MakeIfCharFolderNext
(struct
type env = unit
fun stopAtFirstNonSpace (strPos, shd, absIdx, stl) =
if strPos = String.size shd then
case stl of
shd :: stl => stopAtFirstNonSpace (0, shd, absIdx, stl)
| [] => absIdx
else
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx - 1
else if Char.isSpace chr then
stopAtFirstNonSpace (strPos + 1, shd, absIdx + 1, stl)
else
absIdx - 1
end
fun loopAlphaNum (strPos, shd, absIdx, stl) =
if strPos = String.size shd then
case stl of
shd :: stl => loopAlphaNum (0, shd, absIdx, stl)
| [] => absIdx
else
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx - 1
else if Char.isAlphaNum chr orelse chr = #"_" then
loopAlphaNum (strPos + 1, shd, absIdx + 1, stl)
else if Char.isSpace chr then
stopAtFirstNonSpace (strPos + 1, shd, absIdx + 1, stl)
else
(* is punct *)
absIdx - 1
end
fun loopPunct (strPos, shd, absIdx, stl) =
if strPos = String.size shd then
case stl of
shd :: stl => loopPunct (0, shd, absIdx, stl)
| [] => absIdx
else
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx - 1
else if Char.isAlphaNum chr orelse chr = #"_" then
absIdx - 1
else if Char.isSpace chr then
stopAtFirstNonSpace (strPos + 1, shd, absIdx + 1, stl)
else
(* is punct *)
loopPunct (strPos + 1, shd, absIdx + 1, stl)
end
fun loopSpace (strPos, shd, absIdx, stl) =
if strPos = String.size shd then
case stl of
shd :: stl => loopSpace (0, shd, absIdx, stl)
| [] => absIdx
else
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx - 1
else if Char.isAlphaNum chr orelse chr = #"_" then
loopAlphaNum (strPos + 1, shd, absIdx + 1, stl)
else if Char.isSpace chr then
loopSpace (strPos + 1, shd, absIdx + 1, stl)
else
loopPunct (strPos + 1, shd, absIdx + 1, stl)
end
fun fStart (strPos, shd, _, absIdx, stl, _, _) =
let
val chr = String.sub (shd, strPos)
in
if chr = #"\n" then
absIdx
else if Char.isAlphaNum chr orelse chr = #"_" then
loopAlphaNum (strPos + 1, shd, absIdx + 1, stl)
else if Char.isSpace chr then
loopSpace (strPos + 1, shd, absIdx + 1, stl)
else
loopPunct (strPos + 1, shd, absIdx + 1, stl)
end
end)
fun aroundWordNext (lineGap, cursorIdx) =
AroundWordNext.foldNext (lineGap, cursorIdx, ())
fun isCursorAtStartOfLine (lineGap: LineGap.t, cursorIdx) =
let
val {rightStrings, idx = bufferIdx, ...} = lineGap

View File

@@ -23,7 +23,14 @@ struct
val initialMsg = Fn.initMsgs (low, length, buffer)
val buffer = LineGap.delete (low, length, buffer)
val low =
if low >= #textLength buffer - 1 then
Int.max (#textLength buffer - 1, 0)
else
low
val buffer = LineGap.goToIdx (low, buffer)
val low =
if Cursor.isOnNewlineAfterChr (buffer, low) then low - 1 else low
in
@@ -973,6 +980,30 @@ struct
end
end
fun deleteAroundWord (app: app_type, time) =
let
val {buffer, cursorIdx, dfa, ...} = app
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val low = Cursor.aroundWordPrev (buffer, cursorIdx)
val high = Cursor.aroundWordNext (buffer, cursorIdx) + 1
val length = high - low
in
deleteAndFinish (app, low, length, buffer, time)
end
fun deleteAroundWORD (app: app_type, time) =
let
val {buffer, cursorIdx, dfa, ...} = app
val buffer = LineGap.goToIdx (cursorIdx, buffer)
val low = raise Fail "unimplemented"
val high = raise Fail "unimplemented"
val length = high - low
in
deleteAndFinish (app, low, length, buffer, time)
end
fun finishAfterDeleteInside (app: app_type, origLow, high, time) =
if origLow = high then
NormalFinish.clearMode app

View File

@@ -234,7 +234,9 @@ struct
fun parseDeleteAround (app, chr, time) =
case chr of
#"(" => NormalDelete.deleteAroundChrOpen (app, chr, time)
#"w" => NormalDelete.deleteAroundWord (app, time)
| #"W" => NormalDelete.deleteAroundWORD (app, time)
| #"(" => NormalDelete.deleteAroundChrOpen (app, chr, time)
| #"[" => NormalDelete.deleteAroundChrOpen (app, chr, time)
| #"{" => NormalDelete.deleteAroundChrOpen (app, chr, time)
| #"<" => NormalDelete.deleteAroundChrOpen (app, chr, time)

View File

@@ -1 +1,4 @@
hello abc_123 world
fun hello () =
print (##)lo"