Skip to content
Open
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
7 changes: 1 addition & 6 deletions Default (Linux).sublime-keymap
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
[
{ "keys": ["shift+delete"], "command": "cut_edit" },
{ "keys": ["ctrl+insert"], "command": "copy_edit" },
{ "keys": ["shift+insert"], "command": "paste_edit" },
{ "keys": ["ctrl+x"], "command": "cut_edit" },
{ "keys": ["ctrl+c"], "command": "copy_edit" },
{ "keys": ["ctrl+v"], "command": "paste_edit" }
{ "keys": ["ctrl+shift+v"], "command": "paste_from_history_edit" }
]
4 changes: 1 addition & 3 deletions Default (OSX).sublime-keymap
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
[
{ "keys": ["super+x"], "command": "cut_edit" },
{ "keys": ["super+c"], "command": "copy_edit" },
{ "keys": ["super+v"], "command": "paste_edit" }
{ "keys": ["super+shift+v"], "command": "paste_from_history_edit" }
]
7 changes: 1 addition & 6 deletions Default (Windows).sublime-keymap
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
[
{ "keys": ["shift+delete"], "command": "cut_edit" },
{ "keys": ["ctrl+insert"], "command": "copy_edit" },
{ "keys": ["shift+insert"], "command": "paste_edit" },
{ "keys": ["ctrl+x"], "command": "cut_edit" },
{ "keys": ["ctrl+c"], "command": "copy_edit" },
{ "keys": ["ctrl+v"], "command": "paste_edit" }
{ "keys": ["ctrl+shift+v"], "command": "paste_from_history_edit" }
]
111 changes: 84 additions & 27 deletions copy_edit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sublime, sublime_plugin
import sublime, sublime_plugin, collections

selection_strings = []

Expand All @@ -16,79 +16,136 @@

def print_status_message(verb, numregions=None):
numregions = numregions or len(selection_strings)
numchars = sum([len(s) for s in selection_strings])
numchars = sum([len(s[0]) for s in selection_strings])
message = "{0} {1} character{2}".format(verb, numchars, 's' if numchars != 1 else '')
if numregions > 1:
message += " over {0} selection regions".format(numregions)
sublime.status_message(message)

class CopyEditCommand(sublime_plugin.TextCommand):
@staticmethod
def copy(self, edit):
#See copy_with_empty_selection note above.
copy_with_empty_sel = self.view.settings().get("copy_with_empty_selection")

new_sel_strings = []
for s in self.view.sel():
if len(s):
new_sel_strings.append(self.view.substr(s))
new_sel_strings.append((self.view.substr(s), False))
elif copy_with_empty_sel:
new_sel_strings.append(self.view.substr(self.view.full_line(s)))

new_sel_strings.append((self.view.substr(self.view.line(s)) + "\n", True))

actual_selection_strings = new_sel_strings
if all(s == new_sel_strings[0] for s in new_sel_strings):
new_sel_strings = [new_sel_strings[0]]

if len(new_sel_strings) > 0:
selection_strings[:] = [] #.clear() doesn't exist in 2.7
selection_strings.extend(new_sel_strings)
line_ending = line_endings[self.view.line_endings()]
sublime.set_clipboard(line_ending.join(selection_strings))
return True
sublime.set_clipboard(add_string_to_paste_history(line_ending.join([s[0].replace('\n', line_ending) for s in selection_strings])))
return actual_selection_strings
return False

def run(self, edit, verb="Copied"):
if self.copy(edit):
print_status_message(verb)
def run(self, edit):
if self.copy(self, edit):
print_status_message("Copied")

class CutEditCommand(sublime_plugin.TextCommand):
def run(self, edit):
self.view.run_command("copy_edit", {"verb":"Cut"})
for s in reversed(self.view.sel()):
self.view.erase(edit, s)
actual_selection_strings = CopyEditCommand.copy(self, edit)
if actual_selection_strings:
print_status_message("Cut")
for s, ss in reversed(list(zip(self.view.sel(), actual_selection_strings))):
self.view.erase(edit, self.view.full_line(s) if ss[1] else s)

class PasteEditCommand(sublime_plugin.TextCommand):
def run(self, edit):
global selection_strings

#check if clipboard is more up to date
pasteboard = sublime.get_clipboard()
pasteboard = add_string_to_paste_history(sublime.get_clipboard()) # this is needed when string was copied to clipboard not within Sublime Text
from_clipboard = False
if pasteboard != '\n'.join(selection_strings):
if pasteboard != '\n'.join([s[0] for s in selection_strings]):
selection_strings[:] = [] #.clear() doesn't exist in 2.7
selection_strings.append(pasteboard)
selection_strings.append((pasteboard, False))
from_clipboard = True #what should be done in this case?

numstrings = len(selection_strings)
numsels = len(self.view.sel())
if numsels == 0:
return

if numsels == 1: # To fix TN 7
selection_strings = [(("" if selection_strings[0][1] else "\n") # ‘this check is needed because if selection_strings[0][1] == True, then \n is already present at the end of line’\‘проверка нужна, так как если selection_strings[0][1] == True, то \n уже есть в конце строки’
.join([s[0] for s in selection_strings]), selection_strings[0][1])]
numstrings = 1

if numstrings <= numsels and numsels % numstrings == 0:
strs_per_sel = 1
elif numsels < numstrings and numstrings % numsels == 0:
strs_per_sel = int(numstrings / numsels)
else:
strs_per_sel = numstrings

str_index = 0
new_sels = []
for sel in self.view.sel():
self.view.erase(edit, sel)
insertion_point = sel.begin()
for string in selection_strings[str_index:str_index+strs_per_sel]:
self.view.insert(edit, insertion_point, string)
insertion_point += len(string)
region = sublime.Region(insertion_point)
new_sels.append(region)
str_index = (str_index + strs_per_sel) % numstrings
if numsels == numstrings or numstrings == 1: # fix for test #10 (character-by-character selection)
sel_strings = iter(selection_strings)
string = next(sel_strings)
for sel in self.view.sel():
replace_region = sublime.Region(self.view.line(sel.begin()).begin()) if string[1] and sel.size() == 0 else sel
self.view.replace(edit, replace_region, string[0])
string = next(sel_strings, None)
if string == None:
sel_strings = iter(selection_strings)
string = next(sel_strings)
else:
str_index = 0
for sel in self.view.sel():
self.view.erase(edit, sel)
insertion_point = sel.begin()
for string in selection_strings[str_index:str_index+strs_per_sel]:
self.view.insert(edit, self.view.line(insertion_point).begin() if string[1] else insertion_point, string[0])
insertion_point += len(string[0])
region = sublime.Region(insertion_point)
str_index = (str_index + strs_per_sel) % numstrings

print_status_message("Pasted", len(self.view.sel()))

new_sels=[]
for s in self.view.sel():
caret=s.end()
new_sels.append(sublime.Region(caret,caret))
self.view.sel().clear()
for s in new_sels:
self.view.sel().add(s)

paste_history_deque = collections.deque(maxlen = 15) # 15 is the same as in SublimeText's "Paste from History" list

def add_string_to_paste_history(string):#, do_not_reorder_entries_of_paste_history_deque = False):
if string == "":
return ""
if string in paste_history_deque:
paste_history_deque.remove(string)
paste_history_deque.appendleft(string)
return string

class PasteFromHistoryIdxCommand(sublime_plugin.TextCommand):
def run(self, edit, idx):
if idx != -1:
sublime.set_clipboard(paste_history_deque[idx])
self.view.run_command("paste_edit")

class PasteFromHistoryEditCommand(sublime_plugin.TextCommand):
def run(self, edit):
add_string_to_paste_history(sublime.get_clipboard()) # this is needed when string was copied to clipboard not within Sublime Text
if len(paste_history_deque) > 0:
(self.view.window().show_quick_panel if self.view.settings().get("paste_from_history_quick_panel") else self.view.show_popup_menu)(
[(s if len(s) < 45 else s[:45] + '...').replace("\n", " ").replace("\t", " ") for s in paste_history_deque],
lambda idx: self.view.run_command("paste_from_history_idx", {"idx": idx}))

class CopyEditListener(sublime_plugin.EventListener): # for support of standard main menu commands (Edit:Cut/Copy/Paste)
def on_text_command(self, view, command_name, args):
if command_name in ["cut", "copy", "paste", "paste_from_history"]: # actually adding "paste_from_history" here does not make any sense because this command is disabled after startup of SublimeText
return (command_name + "_edit", args)
if command_name in ["left_delete", "right_delete"]:
add_string_to_paste_history(view.substr(view.sel()[0]))
Loading