Skip to content

Commit

Permalink
Merge pull request #34 from nakagami/yank_and_delete
Browse files Browse the repository at this point in the history
Yank and delete commands #7
  • Loading branch information
nakagami authored Jul 31, 2024
2 parents 677d8f5 + b86ce7e commit e4797ec
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 5 deletions.
41 changes: 38 additions & 3 deletions pyvim/commands/commands.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from prompt_toolkit.application import run_in_terminal
from prompt_toolkit.application.current import get_app
from prompt_toolkit.clipboard import ClipboardData
from prompt_toolkit.selection import SelectionType
from prompt_toolkit.document import Document

import os
Expand Down Expand Up @@ -740,7 +743,7 @@ def set_all(editor):
editor.show_set_all()


def _get_line_index_iterator(editor, cursor_position_row, range_start, range_end):
def _get_line_index(editor, cursor_position_row, range_start, range_end):
if not range_start:
assert not range_end
range_start = range_end = cursor_position_row
Expand All @@ -758,7 +761,7 @@ def _get_line_index_iterator(editor, cursor_position_row, range_start, range_end
range_end = int(range_end) - 1
else:
range_end = range_start
return range(range_start, range_end + 1)
return range_start, range_end + 1


def substitute(editor, range_start, range_end, search, replace, flags):
Expand All @@ -779,7 +782,8 @@ def get_transform_callback(search, replace, flags):
if replace is None:
replace = editor.last_substitute_text

line_index_iterator = _get_line_index_iterator(editor, cursor_position_row, range_start, range_end)
start, end = _get_line_index(editor, cursor_position_row, range_start, range_end)
line_index_iterator = range(start, end)
transform_callback = get_transform_callback(search, replace, flags)
new_text = buffer.transform_lines(line_index_iterator, transform_callback)

Expand All @@ -797,3 +801,34 @@ def get_transform_callback(search, replace, flags):
# update editor state
editor.last_substitute_text = replace
search_state.text = search


def yank(editor, range_start, range_end):
buffer = editor.current_editor_buffer.buffer
cursor_position_row = buffer.document.cursor_position_row
start, end = _get_line_index(editor, cursor_position_row, range_start, range_end)
lines = buffer.document.lines

yanked = "\n".join(lines[start: end])
get_app().clipboard.set_data(ClipboardData(yanked, SelectionType.LINES))


def delete(editor, range_start, range_end):
buffer = editor.current_editor_buffer.buffer
cursor_position_row = buffer.document.cursor_position_row
start, end = _get_line_index(editor, cursor_position_row, range_start, range_end)

lines = buffer.document.lines

before = "\n".join(lines[: start])
deleted = "\n".join(lines[start: end])
after = "\n".join(lines[end:])
get_app().clipboard.set_data(ClipboardData(deleted, SelectionType.LINES))

new_text = before + after
# update text buffer
buffer.document = Document(
new_text,
Document(new_text).translate_row_col_to_index(start, 0),
)
buffer.cursor_position += start
6 changes: 6 additions & 0 deletions pyvim/commands/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
# Substitute command
((?P<range_start>\d+|\.|\'[a-z])(,(?P<range_end>\d+|\.|\'[a-z]|\$))?)? (?P<command>s|substitute) \s* / (?P<search>[^/]*) ( / (?P<replace>[^/]*) (?P<flags> /(g)? )? )? |
# Yank command
((?P<range_start>\d+|\.|\'[a-z])(,(?P<range_end>\d+|\.|\'[a-z]|\$))?)? (?P<command>ya|yank[^\s]+) |
# Delete command
((?P<range_start>\d+|\.|\'[a-z])(,(?P<range_end>\d+|\.|\'[a-z]|\$))?)? (?P<command>d|delete[^\s]+) |
# Commands accepting a location.
(?P<command>%(commands_taking_locations)s)(?P<force>!?) \s+ (?P<location>[^\s]+) |
Expand Down
7 changes: 5 additions & 2 deletions pyvim/commands/handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio
from .grammar import COMMAND_GRAMMAR
from .commands import call_command_handler, has_command_handler, substitute
from .commands import call_command_handler, has_command_handler, substitute, yank, delete

__all__ = (
'handle_command',
Expand Down Expand Up @@ -44,7 +44,10 @@ def handle_command(editor, input_string):
elif command in ('s', 'substitute'):
flags = flags.lstrip('/')
substitute(editor, range_start, range_end, search, replace, flags)

elif command in ('ya', 'yank'):
yank(editor, range_start, range_end)
elif command in ('d', 'delete'):
delete(editor, range_start, range_end)
else:
# For unknown commands, show error message.
editor.show_message('Not an editor command: %s' % input_string)
Expand Down

0 comments on commit e4797ec

Please sign in to comment.