Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cf command #1439

Merged
merged 4 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documents/howtouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
| <kbd>**Z**</kbd> <kbd>**Z**</kbd><br>Write current file and exit | <kbd>**Z**</kbd> <kbd>**Q**</kbd><br>Same as `:q!` | <kbd>**Ctrl**</kbd> <kbd>**w**</kbd> <kbd>**c**</kbd><br>Close current window | <kbd>**?**</kbd><br>`keyword` Search backwards |
| <kbd>**/**</kbd><br>`keyword` Search forwards | <kbd>**\\**</kbd> <kbd>**r**</kbd><br>Quick Run | <kbd>**s**</kbd> OR <kbd>**c**</kbd><kbd>**u**</kbd><br> Delete current charater and enter insert mode | <kbd>**y**</kbd><kbd>**{**</kbd><br> Yank to the previous blank line |
| <kbd>**y**</kbd><kbd>**}**</kbd><br> Yank to the next blank line | <kbd>**y**</kbd><kbd>**l**</kbd><br> Yank a character| <kbd>**X**</kbd> OR <kbd>**d**</kbd><kbd>**h**</kbd><br> Cut a character before cursor | <kbd>**g**</kbd><kbd>**a**</kbd><br> Show current character info |
| <kbd>**t**</kbd><kbd>**x**</kbd><br> Move to the left of the next ```x``` (any character) on the current line | <kbd>**T**</kbd><kbd>**x**</kbd><br> Move to the right of the back ```x ``` (any character) on the current line | <kbd>**y**</kbd><kbd>**t**</kbd><br><kbd>**Any key**</kbd><br> Yank characters to an any character |
| <kbd>**t**</kbd><kbd>**x**</kbd><br> Move to the left of the next ```x``` (any character) on the current line | <kbd>**T**</kbd><kbd>**x**</kbd><br> Move to the right of the back ```x ``` (any character) on the current line | <kbd>**y**</kbd><kbd>**t**</kbd><br><kbd>**Any key**</kbd><br> Yank characters to an any character | <kbd>**c**</kbd><kbd>**f**</kbd><br><kbd>**Any key**</kbd><br> Delete characters to an any character and enter insert mode |

</details>

Expand Down
1 change: 1 addition & 0 deletions src/moepkg/help.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ ciw - Delete the current word and enter insert mode
ci( or ci) - Delete the inside of round brackets and enter insert mode
ci[ or ci] - Delete the inside of square brackets and enter insert mode
ci{ or ci} - Delete the inside of curly brackets and enter insert mode
cf any - Delete characters to the any character and enter insert mode
di" - Delete the inside of double quotes
di' - Delete the inside of single quotes
diw - Delete the current word
Expand Down
52 changes: 45 additions & 7 deletions src/moepkg/normalmode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,35 @@ proc deleteCharactersAfterBlankInLine(status: var EditorStatus) =
registerName,
status.settings)

# cf command
proc deleteCharactersToCharacterAndEnterInsertMode(status: var EditorStatus,
rune: Rune,
registerName: string) =

if currentBufStatus.isReadonly:
status.commandLine.writeReadonlyModeWarning
return

let
currentColumn = currentMainWindowNode.currentColumn
# Get the position of a character
position = currentBufStatus.searchOneCharacterToEndOfLine(
currentMainWindowNode,
rune)

if position > currentColumn:
currentBufStatus.cmdLoop = position - currentColumn + 1
status.deleteCharacters

status.changeMode(Mode.insert)

# cf command
proc deleteCharactersToCharacterAndEnterInsertMode(status: var EditorStatus,
rune: Rune) =

const registerName = ""
status.deleteCharactersToCharacterAndEnterInsertMode(rune, registerName)

proc enterInsertModeAfterCursor(status: var EditorStatus) =
if currentBufStatus.isReadonly:
status.commandLine.writeReadonlyModeWarning
Expand Down Expand Up @@ -895,6 +924,10 @@ proc addRegister(status: var EditorStatus, command, registerName: string) =
status.changeInnerCommand(command[2].toRune, registerName)
elif command.len == 3 and command[0 .. 1] == "yt":
status.yankCharactersToCharacter(command[2].toRune, registerName)
elif command.len == 3 and command[0 .. 1] == "cf":
status.deleteCharactersToCharacterAndEnterInsertMode(
command[2].toRune,
registerName)
else:
discard

Expand Down Expand Up @@ -954,7 +987,8 @@ proc registerCommand(status: var EditorStatus, command: seq[Rune]) =
cmd == "dh" or
cmd == "cl" or cmd == "s" or
(cmd.len == 3 and cmd[0 .. 1] == "ci") or
(cmd.len == 3 and cmd[0 .. 1] == "yt"):
(cmd.len == 3 and cmd[0 .. 1] == "yt") or
(cmd.len == 3 and cmd[0 .. 1] == "cf"):
status.addRegister(cmd, $registerName)

proc pasteAfterCursor(status: var EditorStatus) {.inline.} =
Expand Down Expand Up @@ -1111,13 +1145,16 @@ proc normalCommand(status: var EditorStatus,
if secondKey == ord('c'):
status.deleteCharactersAfterBlankInLine
status.enterInsertModeAfterCursor
if secondKey == ord('l'):
elif secondKey == ord('l'):
status.deleteCharacterAndEnterInsertMode
elif secondKey == ord('i'):
let thirdKey = commands[2]
if isParen(thirdKey) or
thirdKey == ord('w'):
status.changeInnerCommand(thirdKey)
elif secondKey == ord('f'):
let thirdKey = commands[2]
status.deleteCharactersToCharacterAndEnterInsertMode(thirdKey)
elif key == ord('d'):
let secondKey = commands[1]
if secondKey == ord('d'):
Expand Down Expand Up @@ -1371,15 +1408,16 @@ proc isNormalModeCommand(command: seq[Rune]): InputState =
if command.len == 1:
result = InputState.Continue
elif command.len == 2:
if command[1] == ord('i'):
if command[1] == ord('i') or
command[1] == ord('f'):
result = InputState.Continue
elif command[1] == ord('c') or command[1] == ('l'):
result = InputState.Valid
elif command.len == 3:
if command[1] == ord('i'):
if isParen(command[2]) or
command[2] == ord('w'):
result = InputState.Valid
if command[1] == ord('f') or
(command[1] == ord('i') and
(isParen(command[2]) or command[2] == ord('w'))):
result = InputState.Valid

elif command[0] == ord('d'):
if command.len == 1:
Expand Down
36 changes: 36 additions & 0 deletions tests/tnormalmode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1916,3 +1916,39 @@ suite "Normal mode: Yank characters to any character":
check currentBufStatus.buffer[0] == buffer

check status.registers.noNameRegister.buffer.len == 0

suite "Normal mode: Delete characters to any characters and Enter insert mode":
test "Case 1: Delete characters to 'd' and enter insert mode (\"cfd\" command)":
var status = initEditorStatus()
status.addNewBuffer

const buffer = ru "abcd"
currentBufStatus.buffer = initGapBuffer(@[buffer])

const command = ru "cfd"
status.normalCommand(command, 100, 100)

check currentBufStatus.buffer.len == 1
check currentBufStatus.buffer[0] == ru ""

check not status.registers.noNameRegister.isLine
check status.registers.noNameRegister.buffer[0] == ru "abcd"

check currentBufStatus.mode == Mode.insert

test "Case 1: Do nothing (\"cfz\" command)":
var status = initEditorStatus()
status.addNewBuffer

const buffer = ru "abcd"
currentBufStatus.buffer = initGapBuffer(@[buffer])

const command = ru "cfz"
status.normalCommand(command, 100, 100)

check currentBufStatus.buffer.len == 1
check currentBufStatus.buffer[0] == buffer

check status.registers.noNameRegister.buffer.len == 0

check currentBufStatus.mode == Mode.normal