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 yt command #1437

Merged
merged 4 commits into from
Aug 30, 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>**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 |

</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 @@ -52,6 +52,7 @@ yy or Y - Copy a line
y{ - Yank to the previous blank line
y} - Yank to the next blank line
yl - Yank a character
yt any - Ynak characters to a any character
p - Paste the clipboard
n - Search forwards
: - Start Ex mode
Expand Down
64 changes: 62 additions & 2 deletions src/moepkg/normalmode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,55 @@ proc yankCharacters(status: var Editorstatus, registerName: string) =
registerName,
isDelete)

# yt command
proc yankCharactersToCharacter(status: var EditorStatus,
rune: Rune) =

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

if position > currentColumn:
const
isDelete = false
registerName = ""
currentBufStatus.yankCharacters(
status.registers,
currentMainWindowNode,
status.commandLine,
status.messageLog,
status.settings,
position,
registerName,
isDelete)

# yt command
proc yankCharactersToCharacter(status: var EditorStatus,
rune: Rune,
registerName: string) =

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

if position > currentColumn:
const isDelete = false
currentBufStatus.yankCharacters(
status.registers,
currentMainWindowNode,
status.commandLine,
status.messageLog,
status.settings,
position,
registerName,
isDelete)

proc deleteCharacters(status: var EditorStatus, registerName: string) =
if currentBufStatus.isReadonly:
status.commandLine.writeReadonlyModeWarning
Expand Down Expand Up @@ -844,6 +893,8 @@ proc addRegister(status: var EditorStatus, command, registerName: string) =
status.deleteCharacterAndEnterInsertMode(registerName)
elif command.len == 3 and command[0 .. 1] == "ci":
status.changeInnerCommand(command[2].toRune, registerName)
elif command.len == 3 and command[0 .. 1] == "yt":
status.yankCharactersToCharacter(command[2].toRune, registerName)
else:
discard

Expand Down Expand Up @@ -899,10 +950,11 @@ proc registerCommand(status: var EditorStatus, command: seq[Rune]) =
cmd == "dgg" or
cmd == "d{" or
cmd == "d}" or
cmd.len == 3 and cmd[0 .. 1] == "di" or
(cmd.len == 3 and cmd[0 .. 1] == "di") or
cmd == "dh" or
cmd == "cl" or cmd == "s" or
cmd.len == 3 and cmd[0 .. 1] == "ci":
(cmd.len == 3 and cmd[0 .. 1] == "ci") or
(cmd.len == 3 and cmd[0 .. 1] == "yt"):
status.addRegister(cmd, $registerName)

proc pasteAfterCursor(status: var EditorStatus) {.inline.} =
Expand Down Expand Up @@ -1110,6 +1162,9 @@ proc normalCommand(status: var EditorStatus,
status.yankToNextBlankLine
elif secondKey == ord('l'):
status.yankCharacters
elif secondKey == ord('t'):
let thirdKey = commands[2]
status.yankCharactersToCharacter(thirdKey)
elif key == ord('Y'):
status.yankLines
elif key == ord('p'):
Expand Down Expand Up @@ -1358,6 +1413,11 @@ proc isNormalModeCommand(command: seq[Rune]): InputState =
command[1] == ord('}') or
command[1] == ord('l'):
result = InputState.Valid
elif command == "yt".ru:
result = InputState.Continue
elif command.len == 3:
if command[0 .. 1] == "yt".ru:
result = InputState.Valid

elif command[0] == ord('='):
if command.len == 1:
Expand Down
80 changes: 80 additions & 0 deletions tests/tnormalmode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1836,3 +1836,83 @@ suite "Normal mode: Move to the right of the back character":

check currentMainWindowNode.currentLine == 0
check currentMainWindowNode.currentColumn == 0

suite "Normal mode: Yank characters to any character":
test "Case 1: Yank characters before 'd' (\"ytd\" command)":
var status = initEditorStatus()
status.addNewBuffer

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

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

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

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

test "Case 2: Yank characters before 'd' (\"ytd\" command)":
var status = initEditorStatus()
status.addNewBuffer

const buffer = ru "ab c d"
currentBufStatus.buffer = initGapBuffer(@[buffer])

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

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

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

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

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

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

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

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

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

const buffer = ru "abcd efg"
currentBufStatus.buffer = initGapBuffer(@[buffer])
currentMainWindowNode.currentColumn = 3

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

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

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

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

const buffer = ru "abcd efg"
currentBufStatus.buffer = initGapBuffer(@[buffer])
currentMainWindowNode.currentColumn = buffer.high

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

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

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