finish reimplementing 'di<symbol>' and 'da<symbol>' motions so that they align more closely with the behaviour of Vim. (Todo: test them next)
This commit is contained in:
@@ -260,7 +260,7 @@ struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
fun fStart (strPos, str, _, absIdx, stl, _, {openChr, closeChr}) =
|
fun fStart (strPos, str, _, absIdx, stl, _, {openChr, closeChr}) =
|
||||||
loop (strPos, str, absIdx, stl, openChr, closeChr, 0)
|
loop (strPos + 1, str, absIdx + 1, stl, openChr, closeChr, 0)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
val toCloseChrNext = ToCloseChrNext.foldNext
|
val toCloseChrNext = ToCloseChrNext.foldNext
|
||||||
|
|||||||
@@ -1035,143 +1035,140 @@ struct
|
|||||||
deleteAndFinish (app, low, length, buffer, time)
|
deleteAndFinish (app, low, length, buffer, time)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fun finishDeletingInsidePair (app, buffer, cursorIdx, otherIdx, dfa, time) =
|
||||||
|
let
|
||||||
|
val low = Int.min (cursorIdx, otherIdx)
|
||||||
|
val high = Int.max (cursorIdx, otherIdx)
|
||||||
|
in
|
||||||
|
if high = low + 1 then
|
||||||
|
NormalFinish.clearMode app
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val deleteLow = low + 1
|
||||||
|
val length = high - deleteLow
|
||||||
|
|
||||||
|
val buffer = LineGap.goToIdx (high, buffer)
|
||||||
|
val initialMsg = Fn.initMsgs (deleteLow, length, buffer)
|
||||||
|
|
||||||
|
val buffer = LineGap.delete (deleteLow, length, buffer)
|
||||||
|
val (buffer, searchList) = SearchList.build (buffer, dfa)
|
||||||
|
|
||||||
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
|
in
|
||||||
|
NormalFinish.buildTextAndClear
|
||||||
|
(app, buffer, low, searchList, initialMsg, time)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
fun deleteInsidePair (app: app_type, openChr, closeChr, time) =
|
fun deleteInsidePair (app: app_type, openChr, closeChr, time) =
|
||||||
let
|
let
|
||||||
val {buffer, cursorIdx, dfa, ...} = app
|
val {buffer, cursorIdx, dfa, ...} = app
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (cursorIdx, buffer)
|
val buffer = LineGap.goToIdx (cursorIdx, buffer)
|
||||||
val nextIdx =
|
val cursorChr = LineGap.sub (cursorIdx, buffer)
|
||||||
Cursor.toCloseChrNext
|
|
||||||
(buffer, cursorIdx, {openChr = openChr, closeChr = closeChr})
|
|
||||||
in
|
in
|
||||||
if nextIdx = ~1 then
|
if cursorChr = openChr orelse cursorChr = closeChr then
|
||||||
NormalFinish.clearMode app
|
let
|
||||||
|
val otherIdx = Cursor.matchPair (buffer, cursorIdx)
|
||||||
|
in
|
||||||
|
finishDeletingInsidePair (app, buffer, cursorIdx, otherIdx, dfa, time)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val buffer = LineGap.goToIdx (nextIdx, buffer)
|
val nextIdx =
|
||||||
val matchIdx = Cursor.matchPair (buffer, nextIdx)
|
Cursor.toCloseChrNext
|
||||||
|
(buffer, cursorIdx, {openChr = openChr, closeChr = closeChr})
|
||||||
in
|
in
|
||||||
if matchIdx = ~1 then
|
if nextIdx = ~1 then
|
||||||
NormalFinish.clearMode app
|
NormalFinish.clearMode app
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val low = Int.min (nextIdx, matchIdx)
|
val buffer = LineGap.goToIdx (nextIdx, buffer)
|
||||||
val high = Int.max (nextIdx, matchIdx)
|
val matchIdx = Cursor.matchPair (buffer, nextIdx)
|
||||||
in
|
in
|
||||||
if high = low + 1 then
|
if matchIdx = ~1 then
|
||||||
NormalFinish.clearMode app
|
NormalFinish.clearMode app
|
||||||
else
|
else
|
||||||
let
|
finishDeletingInsidePair
|
||||||
val deleteLow = low + 1
|
(app, buffer, nextIdx, matchIdx, dfa, time)
|
||||||
val length = high - deleteLow
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (high, buffer)
|
|
||||||
val initialMsg = Fn.initMsgs (deleteLow, length, buffer)
|
|
||||||
|
|
||||||
val buffer = LineGap.delete (deleteLow, length, buffer)
|
|
||||||
val (buffer, searchList) = SearchList.build (buffer, dfa)
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (low, buffer)
|
|
||||||
in
|
|
||||||
NormalFinish.buildTextAndClear
|
|
||||||
(app, buffer, low, searchList, initialMsg, time)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fun finishAfterDeleteInside (app: app_type, origLow, high, time) =
|
fun finishDeleteAroundPair (app, buffer, chr1Idx, chr2Idx, time) =
|
||||||
if origLow = high then
|
|
||||||
NormalFinish.clearMode app
|
|
||||||
else
|
|
||||||
let
|
|
||||||
val {cursorIdx, buffer, dfa, ...} = app
|
|
||||||
val low = origLow + 1
|
|
||||||
val length = high - low
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (high, buffer)
|
|
||||||
val initialMsg = Fn.initMsgs (low, length, buffer)
|
|
||||||
|
|
||||||
val buffer = LineGap.delete (low, length, buffer)
|
|
||||||
val (buffer, searchList) = SearchList.build (buffer, dfa)
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (origLow, buffer)
|
|
||||||
in
|
|
||||||
NormalFinish.buildTextAndClear
|
|
||||||
(app, buffer, origLow, searchList, initialMsg, time)
|
|
||||||
end
|
|
||||||
|
|
||||||
fun deleteInsideChrOpen (app: app_type, chr, time) =
|
|
||||||
let
|
let
|
||||||
val {cursorIdx, buffer, ...} = app
|
val low = Int.min (chr1Idx, chr2Idx)
|
||||||
|
val high = Int.max (chr1Idx, chr2Idx) + 1
|
||||||
|
val length = high - low
|
||||||
|
|
||||||
val start = cursorIdx + 1
|
|
||||||
val buffer = LineGap.goToIdx (start, buffer)
|
|
||||||
|
|
||||||
val origLow = Cursor.toPrevChr (buffer, start, {findChr = chr, count = 1})
|
|
||||||
val buffer = LineGap.goToIdx (origLow, buffer)
|
|
||||||
val high = Cursor.matchPair (buffer, origLow)
|
|
||||||
in
|
|
||||||
finishAfterDeleteInside (app, origLow, high, time)
|
|
||||||
end
|
|
||||||
|
|
||||||
fun deleteInsideChrClose (app: app_type, chr, time) =
|
|
||||||
let
|
|
||||||
val {cursorIdx, buffer, ...} = app
|
|
||||||
|
|
||||||
val start = Int.max (cursorIdx - 1, 0)
|
|
||||||
val buffer = LineGap.goToIdx (start, buffer)
|
|
||||||
|
|
||||||
val high = Cursor.toNextChr (buffer, start, {findChr = chr, count = 1})
|
|
||||||
val buffer = LineGap.goToIdx (high, buffer)
|
|
||||||
val origLow = Cursor.matchPair (buffer, high)
|
|
||||||
in
|
|
||||||
finishAfterDeleteInside (app, origLow, high, time)
|
|
||||||
end
|
|
||||||
|
|
||||||
fun finishDeleteAroundChr (app, low, high, buffer, time) =
|
|
||||||
let
|
|
||||||
val length = high - low + 1
|
|
||||||
val buffer = LineGap.goToIdx (high, buffer)
|
val buffer = LineGap.goToIdx (high, buffer)
|
||||||
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 buffer = LineGap.goToIdx (low, buffer)
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
val low =
|
val low =
|
||||||
if Cursor.isCursorAtStartOfLine (buffer, low) then Int.max (low - 1, 0)
|
if Cursor.isOnNewlineAfterChr (buffer, low) then low - 1 else low
|
||||||
else low
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
in
|
in
|
||||||
finishAfterDeletingBuffer (app, low, buffer, time, initialMsg)
|
finishAfterDeletingBuffer (app, low, buffer, time, initialMsg)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun deleteAroundChrOpen (app: app_type, chr, time) =
|
fun finishDeletingPair (app, buffer, cursorIdx, otherIdx, dfa, time) =
|
||||||
let
|
let
|
||||||
val {cursorIdx, buffer, ...} = app
|
val low = Int.min (cursorIdx, otherIdx)
|
||||||
|
val high = Int.max (cursorIdx, otherIdx)
|
||||||
|
val length = high - low + 1
|
||||||
|
|
||||||
val start = cursorIdx + 1
|
val buffer = LineGap.goToIdx (high, buffer)
|
||||||
val buffer = LineGap.goToIdx (start, buffer)
|
val initialMsg = Fn.initMsgs (low, length, buffer)
|
||||||
|
|
||||||
|
val buffer = LineGap.delete (low, length, buffer)
|
||||||
|
val (buffer, searchList) = SearchList.build (buffer, dfa)
|
||||||
|
|
||||||
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
|
|
||||||
|
val low =
|
||||||
|
if Cursor.isCursorAtStartOfLine (buffer, low) then
|
||||||
|
(* we may have deleted the last character of this current line,
|
||||||
|
* and if we did, we have to move the cursor back by 1 *)
|
||||||
|
Int.max (low - 1, 0)
|
||||||
|
else
|
||||||
|
low
|
||||||
|
|
||||||
val low = Cursor.toPrevChr (buffer, start, {findChr = chr, count = 1})
|
|
||||||
val buffer = LineGap.goToIdx (low, buffer)
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
val high = Cursor.matchPair (buffer, low)
|
|
||||||
in
|
in
|
||||||
if low = high then NormalFinish.clearMode app
|
NormalFinish.buildTextAndClear
|
||||||
else finishDeleteAroundChr (app, low, high, buffer, time)
|
(app, buffer, low, searchList, initialMsg, time)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun deleteAroundChrClose (app: app_type, chr, time) =
|
fun deleteAroundPair (app: app_type, openChr, closeChr, time) =
|
||||||
let
|
let
|
||||||
val {cursorIdx, buffer, ...} = app
|
val {buffer, cursorIdx, dfa, ...} = app
|
||||||
|
|
||||||
val start = Int.max (cursorIdx - 1, 0)
|
val buffer = LineGap.goToIdx (cursorIdx, buffer)
|
||||||
val buffer = LineGap.goToIdx (start, buffer)
|
val cursorChr = LineGap.sub (cursorIdx, buffer)
|
||||||
|
|
||||||
val high = Cursor.toNextChr (buffer, start, {findChr = chr, count = 1})
|
|
||||||
val buffer = LineGap.goToIdx (high, buffer)
|
|
||||||
val low = Cursor.matchPair (buffer, high)
|
|
||||||
in
|
in
|
||||||
if low = high then NormalFinish.clearMode app
|
if cursorChr = closeChr orelse cursorChr = openChr then
|
||||||
else finishDeleteAroundChr (app, low, high, buffer, time)
|
let val pairIdx = Cursor.matchPair (buffer, cursorIdx)
|
||||||
|
in finishDeletingPair (app, buffer, cursorIdx, pairIdx, dfa, time)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val nextIdx =
|
||||||
|
Cursor.toCloseChrNext
|
||||||
|
(buffer, cursorIdx, {openChr = openChr, closeChr = closeChr})
|
||||||
|
in
|
||||||
|
if nextIdx = ~1 then
|
||||||
|
NormalFinish.clearMode app
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val buffer = LineGap.goToIdx (nextIdx, buffer)
|
||||||
|
val matchIdx = Cursor.matchPair (buffer, nextIdx)
|
||||||
|
in
|
||||||
|
if matchIdx = ~1 then NormalFinish.clearMode app
|
||||||
|
else finishDeleteAroundPair (app, buffer, nextIdx, matchIdx, time)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fun deletePair (app: app_type, time) =
|
fun deletePair (app: app_type, time) =
|
||||||
@@ -1187,35 +1184,8 @@ struct
|
|||||||
val buffer = LineGap.goToIdx (otherIdx, buffer)
|
val buffer = LineGap.goToIdx (otherIdx, buffer)
|
||||||
val otherIdx = Cursor.matchPair (buffer, otherIdx)
|
val otherIdx = Cursor.matchPair (buffer, otherIdx)
|
||||||
in
|
in
|
||||||
if otherIdx = ~1 then
|
if otherIdx = ~1 then NormalFinish.clearMode app
|
||||||
NormalFinish.clearMode app
|
else finishDeletingPair (app, buffer, cursorIdx, otherIdx, dfa, time)
|
||||||
else
|
|
||||||
let
|
|
||||||
val low = Int.min (cursorIdx, otherIdx)
|
|
||||||
val high = Int.max (cursorIdx, otherIdx)
|
|
||||||
val length = high - low + 1
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (high, buffer)
|
|
||||||
val initialMsg = Fn.initMsgs (low, length, buffer)
|
|
||||||
|
|
||||||
val buffer = LineGap.delete (low, length, buffer)
|
|
||||||
val (buffer, searchList) = SearchList.build (buffer, dfa)
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (low, buffer)
|
|
||||||
|
|
||||||
val low =
|
|
||||||
if Cursor.isCursorAtStartOfLine (buffer, low) then
|
|
||||||
(* we may have deleted the last character of this current line,
|
|
||||||
* and if we did, we have to move the cursor back by 1 *)
|
|
||||||
Int.max (low - 1, 0)
|
|
||||||
else
|
|
||||||
low
|
|
||||||
|
|
||||||
val buffer = LineGap.goToIdx (low, buffer)
|
|
||||||
in
|
|
||||||
NormalFinish.buildTextAndClear
|
|
||||||
(app, buffer, low, searchList, initialMsg, time)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -240,14 +240,19 @@ struct
|
|||||||
case chr of
|
case chr of
|
||||||
#"w" => NormalDelete.deleteAroundWord (app, time)
|
#"w" => NormalDelete.deleteAroundWord (app, 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.deleteAroundPair (app, #"(", #")", time)
|
||||||
| #"<" => NormalDelete.deleteAroundChrOpen (app, chr, time)
|
| #")" => NormalDelete.deleteAroundPair (app, #"(", #")", time)
|
||||||
| #")" => NormalDelete.deleteAroundChrClose (app, chr, time)
|
|
||||||
| #"]" => NormalDelete.deleteAroundChrClose (app, chr, time)
|
| #"[" => NormalDelete.deleteAroundPair (app, #"[", #"]", time)
|
||||||
| #"}" => NormalDelete.deleteAroundChrClose (app, chr, time)
|
| #"]" => NormalDelete.deleteAroundPair (app, #"[", #"]", time)
|
||||||
| #">" => NormalDelete.deleteAroundChrClose (app, chr, time)
|
|
||||||
|
| #"{" => NormalDelete.deleteAroundPair (app, #"{", #"}", time)
|
||||||
|
| #"}" => NormalDelete.deleteAroundPair (app, #"{", #"}", time)
|
||||||
|
|
||||||
|
| #"<" => NormalDelete.deleteAroundPair (app, #"<", #">", time)
|
||||||
|
| #">" => NormalDelete.deleteAroundPair (app, #"<", #">", time)
|
||||||
| _ => NormalFinish.clearMode app
|
| _ => NormalFinish.clearMode app
|
||||||
|
|
||||||
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
||||||
@@ -317,26 +322,37 @@ struct
|
|||||||
case chr of
|
case chr of
|
||||||
#"w" => NormalYankDelete.deleteInsideWord (app, time)
|
#"w" => NormalYankDelete.deleteInsideWord (app, time)
|
||||||
| #"W" => NormalYankDelete.deleteInsideWORD (app, time)
|
| #"W" => NormalYankDelete.deleteInsideWORD (app, time)
|
||||||
| #"(" => NormalYankDelete.deleteInsideChrOpen (app, chr, time)
|
|
||||||
| #"[" => NormalYankDelete.deleteInsideChrOpen (app, chr, time)
|
| #"(" => NormalYankDelete.deleteInsidePair (app, #"(", #")", time)
|
||||||
| #"{" => NormalYankDelete.deleteInsideChrOpen (app, chr, time)
|
| #")" => NormalYankDelete.deleteInsidePair (app, #"(", #")", time)
|
||||||
| #"<" => NormalYankDelete.deleteInsideChrOpen (app, chr, time)
|
|
||||||
| #")" => NormalYankDelete.deleteInsideChrClose (app, chr, time)
|
| #"[" => NormalYankDelete.deleteInsidePair (app, #"[", #"]", time)
|
||||||
| #"]" => NormalYankDelete.deleteInsideChrClose (app, chr, time)
|
| #"]" => NormalYankDelete.deleteInsidePair (app, #"[", #"]", time)
|
||||||
| #"}" => NormalYankDelete.deleteInsideChrClose (app, chr, time)
|
|
||||||
| #">" => NormalYankDelete.deleteInsideChrClose (app, chr, time)
|
| #"{" => NormalYankDelete.deleteInsidePair (app, #"{", #"}", time)
|
||||||
|
| #"}" => NormalYankDelete.deleteInsidePair (app, #"{", #"}", time)
|
||||||
|
|
||||||
|
| #"<" => NormalYankDelete.deleteInsidePair (app, #"<", #">", time)
|
||||||
|
| #">" => NormalYankDelete.deleteInsidePair (app, #"<", #">", time)
|
||||||
| _ => NormalFinish.clearMode app
|
| _ => NormalFinish.clearMode app
|
||||||
|
|
||||||
fun parseDeleteAround (app, chr, time) =
|
fun parseDeleteAround (app, chr, time) =
|
||||||
case chr of
|
case chr of
|
||||||
#"(" => NormalYankDelete.deleteAroundChrOpen (app, chr, time)
|
#"w" => NormalYankDelete.deleteAroundWord (app, time)
|
||||||
| #"[" => NormalYankDelete.deleteAroundChrOpen (app, chr, time)
|
| #"W" => NormalYankDelete.deleteAroundWORD (app, time)
|
||||||
| #"{" => NormalYankDelete.deleteAroundChrOpen (app, chr, time)
|
|
||||||
| #"<" => NormalYankDelete.deleteAroundChrOpen (app, chr, time)
|
|
||||||
| #")" => NormalYankDelete.deleteAroundChrClose (app, chr, time)
|
| #"(" => NormalYankDelete.deleteAroundPair (app, #"(", #")", time)
|
||||||
| #"]" => NormalYankDelete.deleteAroundChrClose (app, chr, time)
|
| #")" => NormalYankDelete.deleteAroundPair (app, #"(", #")", time)
|
||||||
| #"}" => NormalYankDelete.deleteAroundChrClose (app, chr, time)
|
|
||||||
| #">" => NormalYankDelete.deleteAroundChrClose (app, chr, time)
|
| #"[" => NormalYankDelete.deleteAroundPair (app, #"[", #"]", time)
|
||||||
|
| #"]" => NormalYankDelete.deleteAroundPair (app, #"[", #"]", time)
|
||||||
|
|
||||||
|
| #"{" => NormalYankDelete.deleteAroundPair (app, #"{", #"}", time)
|
||||||
|
| #"}" => NormalYankDelete.deleteAroundPair (app, #"{", #"}", time)
|
||||||
|
|
||||||
|
| #"<" => NormalYankDelete.deleteAroundPair (app, #"<", #">", time)
|
||||||
|
| #">" => NormalYankDelete.deleteAroundPair (app, #"<", #">", time)
|
||||||
| _ => NormalFinish.clearMode app
|
| _ => NormalFinish.clearMode app
|
||||||
|
|
||||||
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
||||||
|
|||||||
4
todo.md
4
todo.md
@@ -1,9 +1,7 @@
|
|||||||
# To-do list
|
# To-do list
|
||||||
|
|
||||||
- Add tests for:
|
- Add tests for:
|
||||||
- Reimplement `di<symbol>` and `da<symbol>`
|
- `di<symbol>` and `da<symbol>`
|
||||||
- They should search for the next char in the specific pair, the same way in Vim
|
|
||||||
- Add tests for both
|
|
||||||
|
|
||||||
Afterwards, add tests for yanking.
|
Afterwards, add tests for yanking.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user