diff --git a/fcore/persistent-vector.sml b/fcore/persistent-vector.sml index 673727f..c246e71 100644 --- a/fcore/persistent-vector.sml +++ b/fcore/persistent-vector.sml @@ -483,7 +483,7 @@ struct else if splitIdx > Vector.sub (sizes, Vector.length sizes - 1) then empty - else if splitIdx < Vector.sub (sizes, 0) then + else if splitIdx < #start (Vector.sub (items, 0)) then tree else let @@ -743,13 +743,6 @@ struct let val finish = start + length - val matchBeforeStart = prevMatch (start, tree, 1) - val matchBeforeStart = - if matchBeforeStart >= start then - ~1 - else - matchBeforeStart - val matchAfterFinish = nextMatch (finish, tree, 1) val matchAfterFinish = if matchAfterFinish < finish then @@ -757,63 +750,47 @@ struct else matchAfterFinish in - if matchBeforeStart = ~1 andalso matchAfterFinish = ~1 then - empty - else if matchAfterFinish = ~1 then - (* there is no match after 'finish', so just split left. - * No need to decrement or split right, - * because the right vector would be empty. *) - splitLeft (start, tree) - else if matchBeforeStart = ~1 then - (* We don't want to use left split - * because there are no elements - * before the deletion range's 'start'. - * So we make a right split and then decrement it. *) - let - val right = splitRight (finish, tree) - in - if isEmpty right then - empty - else - let - val startIdx = getStartIdx right - val shouldBeStartIdx = matchAfterFinish - length - val difference = startIdx - shouldBeStartIdx - in - if difference = 0 then - right - else if isEmpty right then - empty - else - decrementBy (difference, right) - end - end - else - let - val left = splitLeft (start, tree) - val right = splitRight (finish, tree) - in - if isEmpty right then - left - else - let - val leftSize = getFinishIdx left - val rightStartRelative = getStartIdx right - val rightStartAbsolute = leftSize + rightStartRelative + let + val left = splitLeft (start, tree) + val right = splitRight (finish, tree) + in + if isEmpty left andalso isEmpty right then + empty + else if isEmpty left then + (* just decrement right and return it *) + let + val rightStart = getStartIdx right + val shouldBeStartIdx = matchAfterFinish - length + val difference = rightStart - shouldBeStartIdx + in + if difference = 0 then + right + else + decrementBy (difference, right) + end + else if isEmpty right then + (* return left half without doing anything *) + left + else + (* decrement right, and then merge both together *) + let + val leftSize = getFinishIdx left + val rightStartRelative = getStartIdx right + val rightStartAbsolute = leftSize + rightStartRelative - val shouldBeStartIdx = matchAfterFinish - length - val difference = rightStartAbsolute - shouldBeStartIdx - in - if difference = 0 then + val shouldBeStartIdx = matchAfterFinish - length + val difference = rightStartAbsolute - shouldBeStartIdx + in + if difference = 0 then + merge (left, right) + else + let + val right = decrementBy (difference, right) + in merge (left, right) - else - let - val right = decrementBy (difference, right) - in - merge (left, right) - end - end - end + end + end + end end (* Usually, when inserting, we want the absolute metadata diff --git a/fcore/search-list/search-list.sml b/fcore/search-list/search-list.sml index e267aa2..e05f0bd 100644 --- a/fcore/search-list/search-list.sml +++ b/fcore/search-list/search-list.sml @@ -144,13 +144,13 @@ struct in (buffer, searchList) end - else if PersistentVector.isInRange (idx, searchList) then - (buffer, searchList) else if Dfa.isDead curState then if prevFinalPos = ~1 then (* no match found: restart search from `startPos + 1` *) insertUntilMatch (startPos + 1, buffer, searchList, dfa, 0, startPos + 1, ~1) + else if PersistentVector.isInRange (prevFinalPos, searchList) then + (buffer, searchList) else (* new match. Insert and continue *) let diff --git a/temp.txt b/temp.txt index 9c708c1..a2c1105 100644 --- a/temp.txt +++ b/temp.txt @@ -1 +1,2 @@ -hellohello +hello hello hello +world world world diff --git a/test/normal-delete-tests.sml b/test/normal-delete-tests.sml index fa8a357..4b24999 100644 --- a/test/normal-delete-tests.sml +++ b/test/normal-delete-tests.sml @@ -5824,7 +5824,6 @@ struct (* assert *) Expect.isTrue assertion end) - , test "extends match when match should extend after deletion" (fn _ => let (* arrange *) @@ -5850,6 +5849,41 @@ struct [{start = 0, finish = 4}, {start = 6, finish = 10}] val expectedNewSearchList = [{start = 0, finish = 9}] + val assertion = + oldSearchList = expectedOldSearchList + andalso newSearchList = expectedNewSearchList + in + Expect.isTrue assertion + end) + , test "detects match when we delete in middle of it" (fn _ => + let + (* arrange *) + val originalIdx = 1 + val originalString = "hello hello hello\n" + + val app = TestUtils.init originalString + val app = AppWith.idx (app, originalIdx) + + val app = TestUtils.updateMany (app, "/hello") + val app = AppUpdate.update (app, InputMsg.KEY_ENTER, Time.now ()) + + (* act *) + val newApp = TestUtils.updateMany (app, "dn") + + (* assert *) + val oldSearchList = #searchList app + val oldSearchList = PersistentVector.toList oldSearchList + val newSearchList = #searchList newApp + val newSearchList = PersistentVector.toList newSearchList + + val expectedOldSearchList = + [ {start = 0, finish = 4} + , {start = 6, finish = 10} + , {start = 12, finish = 16} + ] + val expectedNewSearchList = + [{start = 1, finish = 5}, {start = 7, finish = 11}] + val assertion = oldSearchList = expectedOldSearchList andalso newSearchList = expectedNewSearchList @@ -5952,6 +5986,45 @@ struct (actualString = expectedString andalso cursorIdx = expectedCursorIdx) end) + + , test + "decrements subsequent matches in search list \ + \when we delete prior to last match" + (fn _ => + let + (* arrange *) + val originalIdx = 1 + val originalString = "hello hello hello\n" + + val app = TestUtils.init originalString + val app = AppWith.idx (app, originalIdx) + + val app = TestUtils.updateMany (app, "/hello") + val app = AppUpdate.update (app, InputMsg.KEY_ENTER, Time.now ()) + + (* act *) + val newApp = TestUtils.updateMany (app, "dN") + + (* assert *) + val oldSearchList = #searchList app + val oldSearchList = PersistentVector.toList oldSearchList + val newSearchList = #searchList newApp + val newSearchList = PersistentVector.toList newSearchList + + val expectedOldSearchList = + [ {start = 0, finish = 4} + , {start = 6, finish = 10} + , {start = 12, finish = 16} + ] + val expectedNewSearchList = + [{start = 5, finish = 9}, {start = 11, finish = 15}] + + val assertion = + oldSearchList = expectedOldSearchList + andalso newSearchList = expectedNewSearchList + in + Expect.isTrue assertion + end) ] val dfDelete = describe "delete motion 'df'"