diff --git a/fcore/cursor.sml b/fcore/cursor.sml index fd1344b..0bae153 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -790,6 +790,130 @@ struct fun aroundWordNext (lineGap, cursorIdx) = AroundWordNext.foldNext (lineGap, cursorIdx, ()) + structure AroundWORDPrev = + MakeIfCharFolderPrev + (struct + type env = unit + + fun loopNonSpace (strPos, shd, absIdx, stl) = + if strPos < 0 then + case stl of + shd :: stl => + loopNonSpace (String.size shd - 1, shd, absIdx, stl) + | [] => 0 + else + let + val chr = String.sub (shd, strPos) + in + if Char.isSpace chr then absIdx + 1 + else loopNonSpace (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.isSpace chr then + loopSpace (strPos - 1, shd, absIdx - 1, stl) + else + loopNonSpace (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 loopNonSpace (strPos, shd, absIdx, stl) = + if strPos = String.size shd then + case stl of + shd :: stl => loopNonSpace (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 + loopNonSpace (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.isSpace chr then + loopSpace (strPos + 1, shd, absIdx + 1, stl) + else + loopNonSpace (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.isSpace chr then + loopSpace (strPos + 1, shd, absIdx + 1, stl) + else + loopNonSpace (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 diff --git a/fcore/normal-mode/make-normal-delete.sml b/fcore/normal-mode/make-normal-delete.sml index 9882358..3b7f805 100644 --- a/fcore/normal-mode/make-normal-delete.sml +++ b/fcore/normal-mode/make-normal-delete.sml @@ -997,8 +997,8 @@ struct let val {buffer, cursorIdx, dfa, ...} = app val buffer = LineGap.goToIdx (cursorIdx, buffer) - val low = raise Fail "unimplemented" - val high = raise Fail "unimplemented" + val low = Cursor.aroundWORDPrev (buffer, cursorIdx) + val high = Cursor.aroundWORDNext (buffer, cursorIdx) + 1 val length = high - low in deleteAndFinish (app, low, length, buffer, time) diff --git a/todo.md b/todo.md index 5bfe13f..6c172ae 100644 --- a/todo.md +++ b/todo.md @@ -1,7 +1,7 @@ # To-do list - Add tests for: -- Implement delete-around-word/WORD and test it +- Test delete-around-word/WORD - Reimple `%` motion and `d%` motion. - They should both search for the next character in any pair, the same way in Vim - Add tests for reimplemented movements and motions