【问题标题】:Middle button paste deleted text in Sublime 3Sublime 3中的中键粘贴已删除的文本
【发布时间】:2015-07-06 17:15:52
【问题描述】:

(注:本题与Move cursor on middle button paste in Sublime Text 3不同)

我在 Linux 上使用 Sublime Text 3(但它也适用于 Sublime Text 2)。

在 emacs 和 vim 中,可以突出显示某些文本(这会将其复制到剪贴板),删除文本,然后用鼠标中键将其粘贴到其他地方。这是我通常的工作流程来移动一些文本(选择->删除->middleclick)。

然而,在 Sublime 上,它不会粘贴任何内容,也就是说,中间按钮粘贴功能显然只适用于未删除的文本。有谁知道如何使它也适用于已删除的文本?

【问题讨论】:

  • @JonTrauntvein 我注意到有两个不同的问题Why it doesn't work with deleted text?Why it doesn't the cursor gets moved? 现在stackoverflow 不允许我删除我给你的评论的赞成票:p
  • 我发现使用 parcellite 在 gedit 中解决了这个问题,但在 sublime 文本中却没有。请参阅Clipboard persistence 了解更多信息。
  • @sergioFC 感谢领先!这很有趣,可惜它不适用于 Sublime。
  • 我认为您需要向 sublime text 提交功能请求,因为这是由提供选择内容的应用程序在内部处理的。您可以使用autocutsel 或类似方法来同步缓冲区,但删除后您仍然必须使用Ctrl+v 进行粘贴。因此,使用Ctrl+x 进行切割可能会更容易。
  • @DominikGebhart 感谢您的建议,我刚刚做到了:sublimetext.userecho.com/topic/822073-

标签: linux sublimetext2 sublimetext3


【解决方案1】:

我有这样的插件:

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 = ''

此插件将检测删除命令(右 = 删除,左 = 退格)并将已删除的内容复制到内存中。然后,如果用户使用中键粘贴,它会将剪贴板替换为已删除的内容并将其粘贴。粘贴后恢复保存的剪贴板。

我假设删除的副本应该在空白空间上工作(ST没有Vintage的插入模式)。要更改该行为,您可以删除 on_selection_modified 函数以显式停止检查,但突出显示新单词不会将其复制到中键剪贴板。

编辑: 使用 Linux xclip 的系统范围剪贴板版本(取自 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))

【讨论】:

  • 我没有对它进行过广泛的测试,但我喜欢它。如果有一个与Linux剪贴板管理相关的解决方案会更好,但它似乎不存在,所以插件是一个很好的解决方案。您可以添加一个条件,以便仅在选择长度> 0 时保存已删除的文本 例如:选择一个单词,在选择它时将其删除,然后我多次按退格键删除以前的字符(不选择它们),然后没有任何内容被复制为当我删除字符而不选择它们时,保存了一个空字符串。干得好,你应该得到你的赏金。
  • 仅当 len > 0 并使用 linux xclip 添加时复制 :)
  • 我忘了点赞 :p 这个使用 xclip 的新版本有什么不同?
  • @sergioFC 它将使用标准的 Xorg 剪贴板,因此您可以将文本从删除中复制到另一个程序。上一个只能在 sublime 内部工作。它也更干净,更少hacky ;)
  • @alkuzad 谢谢,这看起来很棒!我会在星期一有空的时候试试这个。
猜你喜欢
  • 2017-10-31
  • 2013-06-11
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
相关资源
最近更新 更多