implement 'daw' motion
This commit is contained in:
172
fcore/cursor.sml
172
fcore/cursor.sml
@@ -619,7 +619,177 @@ struct
|
|||||||
fun lastContiguousNonSpace (lineGap, cursorIdx) =
|
fun lastContiguousNonSpace (lineGap, cursorIdx) =
|
||||||
LastContiguousNonSpace.foldNext (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) =
|
fun isCursorAtStartOfLine (lineGap: LineGap.t, cursorIdx) =
|
||||||
let
|
let
|
||||||
val {rightStrings, idx = bufferIdx, ...} = lineGap
|
val {rightStrings, idx = bufferIdx, ...} = lineGap
|
||||||
|
|||||||
@@ -23,7 +23,14 @@ struct
|
|||||||
val initialMsg = Fn.initMsgs (low, length, buffer)
|
val initialMsg = Fn.initMsgs (low, length, buffer)
|
||||||
val buffer = LineGap.delete (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 buffer = LineGap.goToIdx (low, buffer)
|
||||||
|
|
||||||
val low =
|
val low =
|
||||||
if Cursor.isOnNewlineAfterChr (buffer, low) then low - 1 else low
|
if Cursor.isOnNewlineAfterChr (buffer, low) then low - 1 else low
|
||||||
in
|
in
|
||||||
@@ -973,6 +980,30 @@ struct
|
|||||||
end
|
end
|
||||||
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) =
|
fun finishAfterDeleteInside (app: app_type, origLow, high, time) =
|
||||||
if origLow = high then
|
if origLow = high then
|
||||||
NormalFinish.clearMode app
|
NormalFinish.clearMode app
|
||||||
|
|||||||
@@ -234,7 +234,9 @@ struct
|
|||||||
|
|
||||||
fun parseDeleteAround (app, chr, time) =
|
fun parseDeleteAround (app, chr, time) =
|
||||||
case chr of
|
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)
|
| #"{" => NormalDelete.deleteAroundChrOpen (app, chr, time)
|
||||||
| #"<" => NormalDelete.deleteAroundChrOpen (app, chr, time)
|
| #"<" => NormalDelete.deleteAroundChrOpen (app, chr, time)
|
||||||
|
|||||||
Reference in New Issue
Block a user