(Note: This question is different from Move cursor on middle button paste in Sublime Text 3 )
I am using Sublime Text 3 on Linux (but it also applies to Sublime Text 2).
In both emacs and vim, it is possible to highlight some text (this copies it to the clipboard), delete the text, then paste it elsewhere with the middle mouse button. This is my usual workflow to move some text (select->delete->middleclick).
On Sublime however, it doesn't paste anything, i.e., the middle button paste functionality only works with non-deleted text, apparently. Does anyone know how to make it work with deleted text too?
I've came with plugin like this:
import sublime, sublime_plugin
import re
class MyListener(sublime_plugin.EventListener):
def __init__(self):
sublime_plugin.EventListener.__init__(self)
self.deleted = ''
self.mark_for_clear = ''
self.clipboard_save = ''
self.empty_matcher = re.compile('^\s+$')
# Clear last deleted word if user made highlight of another one
# Delete if you want to e.g delete one word and highlight another to replace
def on_selection_modified(self, view):
selected_text = view.substr(view.sel()[0])
if self.mark_for_clear != '' and self.mark_for_clear != self.deleted:
self.deleted = ''
self.mark_for_clear = ''
if len(selected_text) > 0 and not self.empty_matcher.match(selected_text):
self.mark_for_clear = selected_text
def on_text_command(self, view, name, args):
# Save deleted word if command was deletion command
if name in ['right_delete', 'left_delete']:
self.deleted = view.substr(view.sel()[0])
#print("Deleted: %s " % self.deleted)
# Propagate saved deleted word to clipboard and change command to
# standard paste (we can only control standard paste clipboard)
if name == "paste_selection_clipboard" and len(self.deleted) > 0:
#print("Pasting:%s" % self.deleted)
self.clipboard_save = sublime.get_clipboard()
sublime.set_clipboard(self.deleted)
# Comment line below to enable multiple middle-click pasting of deleted words:
self.deleted = ''
return("paste", 'HackedByAlkuzad')
# If we are after paste_selection_clipboard command, return old clipboard
def on_post_text_command(self, view, name, args):
if name == 'paste' and len(self.clipboard_save) > 0 and args == 'HackedByAlkuzad':
sublime.set_clipboard(self.clipboard_save)
self.clipboard_save = ''
This plugin will detect delete comamnd (right = delete, left = backspace) and copy deleted content to memory. Then if user uses middle-click paste it replaces clipboard with deleted content and pastes it. After paste it restores saved clipboard.
I assumed that the copy from deletion should work on empty space (ST does not have insert mode without Vintage). To change that behaviour you can delete on_selection_modified function to stop checking for that explictly, however highlighting the new word will not copy it to middle-button clipboard.
Edit:
Version for system-wide clipboard using Linux xclip (taken from pyperclip)
import sublime, sublime_plugin
import re
from subprocess import Popen, PIPE, check_call, CalledProcessError
class DeletedToClipboard(sublime_plugin.EventListener):
empty_matcher = re.compile('^\s*$')
def __init__(self):
sublime_plugin.EventListener.__init__(self)
try:
check_call(['which','xclip'])
except CalledProcessError:
sublime.error_message("You have to have xclip installed to use DeletedToClipboard")
@classmethod
def _is_empty(cls, text):
return len(text) <= 0 or cls.empty_matcher.match(text)
# Thanks pyperclip :)
@classmethod
def _copy_to_system_clipboard(cls, text):
# try secondary if not working
p = Popen(['xclip', '-selection', 'primary'], stdin=PIPE)
try:
p.communicate(input=bytes(text, 'utf-8'))
except Exception as e:
print("Error on paste to clipboard, is xclip installed ? \n{}".format(e))
def on_text_command(self, view, name, args):
# Save deleted word if command was deletion command and selected text was not empty
if name in ['right_delete', 'left_delete']:
deleted = []
for region in view.sel():
text = view.substr(region)
if not DeletedToClipboard._is_empty(text):
deleted.append(text)
if deleted != []:
self._copy_to_system_clipboard("\n".join(deleted))