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

Already on GitHub? Sign in to your account

fixes #100 - pasting at EOF should create new line #103

Closed
wants to merge 5 commits into
from
View
@@ -385,6 +385,16 @@
"context": [{"key": "setting.command_mode"}]
},
+ { "keys": ["y"], "command": "set_action", "args": {
+ "action": "vi_copy",
+ "action_args": {"add_newline_at_eof": true},
+ "description": "Yank"},
+ "context": [
+ {"key": "setting.command_mode"},
+ {"key": "vi_motion_mode", "operator": "equal", "operand": "line"}
+ ]
+ },
+
{ "keys": ["c"], "command": "set_action", "args": {
"action": "enter_insert_mode",
"description": "Change",
@@ -766,7 +776,7 @@
{ "keys": ["y"], "command": "set_motion", "args": {
"motion": "expand_selection",
- "motion_args": {"to": "line" },
+ "motion_args": {"to": "line", "add_newline_at_eof": true},
"mode": "normal"},
"context":
[
View
@@ -279,8 +279,8 @@ class SetMotion(sublime_plugin.TextCommand):
def run_(self, args):
return self.run(**args)
- def run(self, motion, motion_args = {}, linewise = False, inclusive = False,
- clip_to_line = False, character = None, mode = None):
+ def run(self, motion, motion_args={}, linewise=False, inclusive=False,
+ clip_to_line=False, character=None, mode=None, add_newline_at_eof=False):
global g_input_state
@@ -553,6 +553,11 @@ def run(self, edit, action_command, action_args,
if motion_args and 'explicit_repeat' in motion_args:
motion_args['explicit_repeat'] = explicit_repeat
+ # Some actions need to add a newline at eol if it doesn't exist,
+ # like 'yy' or 'Vy'. Let them know they should check for this condition.
+ if motion_args and motion_args.get('add_newline_at_eof') == True:
+ action_args['add_newline_at_eof'] = True
+
visual_mode = self.view.has_non_empty_selection_region()
# Let the motion know if we're in visual mode, if it wants to know
@@ -780,9 +785,9 @@ def run(self, edit, register = '"'):
clip_empty_selection_to_line_contents(self.view)
class ViCopy(sublime_plugin.TextCommand):
- def run(self, edit, register = '"'):
- set_register(self.view, register, forward=True)
- set_register(self.view, '0', forward=True)
+ def run(self, edit, register = '"', add_newline_at_eof=False):
+ set_register(self.view, register, forward=True, add_newline_at_eof=add_newline_at_eof)
+ set_register(self.view, '0', forward=True, add_newline_at_eof=add_newline_at_eof)
transform_selection_regions(self.view, shrink_to_first_char)
class ViPrefixableCommand(sublime_plugin.TextCommand):
@@ -830,17 +835,26 @@ def run(self, edit, register = '"', repeat = 1):
'repeat': repeat,
'register': register})
-def set_register(view, register, forward):
+def set_register(view, register, forward, add_newline_at_eof=False):
delta = 1
if not forward:
delta = -1
text = []
+ # TODO: regions doesn't seem to be used for anything - delete.
regions = []
for s in view.sel():
if s.empty():
s = sublime.Region(s.a, s.a + delta)
text.append(view.substr(s))
+
+ # If the copied selection is on the last line, Vim creates a new
+ # line when pasting unless we're moving characterwise.
+ sel_row, _ = view.rowcol(s.begin())
+ last_row, _ = view.rowcol(view.size())
+ if ((sel_row == last_row) or (s.end() == view.size())) and add_newline_at_eof:
+ text[-1] += '\n'
+
regions.append(s)
text = '\n'.join(text)
@@ -902,8 +916,14 @@ def run(self, edit, register, repeat = 1, forward = True):
for s in regions:
s = sublime.Region(s.a + offset, s.b + offset)
- if len(text) > 0 and text[-1] == '\n':
+ if text.endswith('\n'):
# paste line-wise
+ # If we are at the end of the buffer, add a new line as
+ # Vim does.
+ if (self.view.rowcol(s.end())[0] == \
+ self.view.rowcol(self.view.size())[0]):
+ text = '\n' + text[:-1]
+
@misfo

misfo Apr 6, 2012

Collaborator

This last set of changes to pasting looks good. Can you submit this as a separate fix (for #117)?

if forward:
start = self.view.full_line(s.end()).b
else: