From 886f384490004009c62929c48d63fc16c9fda063 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 2 Jan 2026 18:50:04 +0000 Subject: [PATCH] when deleting inside pair, instead of searching either for either chr1 or chr2 and stopping at first match, search instead for openChr and closeChr, and keep an integer tracking what level of nesting we are at. This gives us the behaviour we want, which is to delete the pair at the correct level of nesting. When we encounter openChr, we increment the nesting counter by 1 and continue searching. When we encounter closeChr, if the nesting counter is 0, we return the current index, but if the nesting counter is higher than 0 when encounter closeChr, we decrement the nesting counter by 1 and continue searching. --- fcore/cursor.sml | 50 +++++++++++++++++++----- fcore/normal-mode/make-normal-delete.sml | 45 +++++++++++++++++++++ fcore/normal-mode/normal-mode.sml | 20 ++++++---- temp.txt | 2 +- 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 3ffc937..21aa95f 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -209,29 +209,61 @@ struct val toPrevChr = ToPrevChr.foldPrev - structure ToEitherChrNext = + structure ToCloseChrNext = MakeIfCharFolderNext (struct - type env = {chr1: char, chr2: char} + type env = {openChr: char, closeChr: char} - fun loop (strPos, str, absIdx, stl, chr1, chr2) = + fun loop (strPos, str, absIdx, stl, openChr, closeChr, openCount) = if strPos = String.size str then case stl of - str :: stl => loop (0, str, absIdx, stl, chr1, chr2) + str :: stl => + loop (0, str, absIdx, stl, openChr, closeChr, openCount) | [] => ~1 else let val chr = String.sub (str, strPos) in - if chr = chr1 orelse chr = chr2 then absIdx - else loop (strPos + 1, str, absIdx + 1, stl, chr1, chr2) + if chr = openChr then + loop + ( strPos + 1 + , str + , absIdx + 1 + , stl + , openChr + , closeChr + , openCount + 1 + ) + else if chr = closeChr then + if openCount = 0 then + absIdx + else + loop + ( strPos + 1 + , str + , absIdx + 1 + , stl + , openChr + , closeChr + , openCount - 1 + ) + else + loop + ( strPos + 1 + , str + , absIdx + 1 + , stl + , openChr + , closeChr + , openCount + ) end - fun fStart (strPos, str, _, absIdx, stl, _, {chr1, chr2}) = - loop (strPos, str, absIdx, stl, chr1, chr2) + fun fStart (strPos, str, _, absIdx, stl, _, {openChr, closeChr}) = + loop (strPos, str, absIdx, stl, openChr, closeChr, 0) end) - val toEitherChrNext = ToEitherChrNext.foldNext + val toCloseChrNext = ToCloseChrNext.foldNext structure NextPairChr = MakeIfCharFolderNext diff --git a/fcore/normal-mode/make-normal-delete.sml b/fcore/normal-mode/make-normal-delete.sml index 0d9d544..4f7f3a8 100644 --- a/fcore/normal-mode/make-normal-delete.sml +++ b/fcore/normal-mode/make-normal-delete.sml @@ -1035,6 +1035,51 @@ struct deleteAndFinish (app, low, length, buffer, time) end + fun deleteInsidePair (app: app_type, openChr, closeChr, time) = + let + val {buffer, cursorIdx, dfa, ...} = app + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + 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 + let + val low = Int.min (nextIdx, matchIdx) + val high = Int.max (nextIdx, matchIdx) + 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 + end + end + fun finishAfterDeleteInside (app: app_type, origLow, high, time) = if origLow = high then NormalFinish.clearMode app diff --git a/fcore/normal-mode/normal-mode.sml b/fcore/normal-mode/normal-mode.sml index 45095b9..5158c01 100644 --- a/fcore/normal-mode/normal-mode.sml +++ b/fcore/normal-mode/normal-mode.sml @@ -222,14 +222,18 @@ struct case chr of #"w" => NormalDelete.deleteInsideWord (app, time) | #"W" => NormalDelete.deleteInsideWORD (app, time) - | #"(" => NormalDelete.deleteInsideChrOpen (app, chr, time) - | #"[" => NormalDelete.deleteInsideChrOpen (app, chr, time) - | #"{" => NormalDelete.deleteInsideChrOpen (app, chr, time) - | #"<" => NormalDelete.deleteInsideChrOpen (app, chr, time) - | #")" => NormalDelete.deleteInsideChrClose (app, chr, time) - | #"]" => NormalDelete.deleteInsideChrClose (app, chr, time) - | #"}" => NormalDelete.deleteInsideChrClose (app, chr, time) - | #">" => NormalDelete.deleteInsideChrClose (app, chr, time) + + | #"(" => NormalDelete.deleteInsidePair (app, #"(", #")", time) + | #")" => NormalDelete.deleteInsidePair (app, #"(", #")", time) + + | #"[" => NormalDelete.deleteInsidePair (app, #"[", #"]", time) + | #"]" => NormalDelete.deleteInsidePair (app, #"[", #"]", time) + + | #"{" => NormalDelete.deleteInsidePair (app, #"{", #"}", time) + | #"}" => NormalDelete.deleteInsidePair (app, #"{", #"}", time) + + | #"<" => NormalDelete.deleteInsidePair (app, #"<", #">", time) + | #">" => NormalDelete.deleteInsidePair (app, #"<", #">", time) | _ => NormalFinish.clearMode app fun parseDeleteAround (app, chr, time) = diff --git a/temp.txt b/temp.txt index 96ed11d..fd34872 100644 --- a/temp.txt +++ b/temp.txt @@ -1 +1 @@ -(((hello))) +( ( ( hello ) ) )