1

我正在使用 Notepad++ 垂直选择和复制文本块。粘贴最新的文本块(当前位于剪贴板缓冲区中)可以正常工作,但是返回到第二个和第三个先前的剪贴板缓冲区(最初作为块复制)不会将这些其他缓冲区粘贴为块,而是作为第一行后跟换行符,第二行换行符等。

例如,假设我阻止复制以下块

      test
      test
      test

最新的剪贴板缓冲区粘贴为

      test
      test
      test

假设光标缩进 4 个空格。但是,如果最新的剪贴板缓冲区移动到剪贴板缓冲区队列中的第二位,我会得到以下粘贴:

      test
test
test

我正在使用 ClipMate 来存储以前的剪贴板缓冲区。

为什么记事本++知道块粘贴最新的剪贴板文本数据(作为块复制)而不是倒数第二个剪贴板缓冲区?

有没有办法存储剪贴板剪辑的块状态?

4

2 回答 2

1

看起来 Notepad++ 是从内部缓冲区粘贴,而不是从剪贴板中获取数据。有一种名为 MSDEVColumnSelect 的私有数据格式,但如果我尝试强制 ClipMate 捕获它,则数据为空。所以这似乎是应用程序通过复制/粘贴玩烟雾和镜子游戏的情况,它根本不是剪贴板功能。

于 2012-03-21T01:36:44.000 回答
1

我已经使用 Python Script Scintilla wrapper notepad++ 插件编写了一个解决方案。

用它来复制。
另存为C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Copy.py
映射到快捷键 Ctrl+c 和 Ctrl+INS

# $Revision: 1.2 $
# $Author: dot $
# $Date: 2012/03/23 20:59:46 $

from Npp import *
import string

# First we'll start an undo action, then Ctrl+z will undo the actions of the whole script
editor.beginUndoAction()

if editor.getSelText() != '':
    strClip = ""
    if editor.selectionIsRectangle():
        strClip = "<vertical>"+editor.getSelText()+"</vertical>"
    else:
        strClip = editor.getSelText()
    editor.copyText(strClip)

# End the undo action, so Ctrl+z will undo the above two actions
editor.endUndoAction()

用它来切割。
另存为C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Cut.py
映射到快捷键 Ctrl+x 和 Shift+DEL

# $Revision: 1.2 $
# $Author: dot $
# $Date: 2012/03/23 20:59:46 $

from Npp import *
import string

# First we'll start an undo action, then Ctrl+z will undo the actions of the whole script
editor.beginUndoAction()

if editor.getSelText() != '':
    strClip = ""
    if editor.selectionIsRectangle():
        strClip = "<vertical>"+editor.getSelText()+"</vertical>"
    else:
        strClip = editor.getSelText()
    editor.copyText(strClip)
    editor.clear()

# End the undo action, so Ctrl+z will undo the above two actions
editor.endUndoAction()

现在下载pyperclip.pyC:\Program Files\Notepad++\plugins\PythonScript\lib
使用它进行粘贴。
另存为C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Paste.py
映射到快捷键 Ctrl+v 和 Shift+INS

# $Revision: 1.11 $
# $Author: dot $
# $Date: 2012/05/18 22:22:22 $

from Npp import *
import pyperclip
import string

#debug = True
debug = False

# First we'll start an undo action, then Ctrl-z will undo the actions of the whole script
editor.beginUndoAction()

# Get the clip
clip = pyperclip.getcb()

# Debug
if debug:
    bufferID = notepad.getCurrentBufferID()
    # Show console for debugging
    console.clear()
    console.show()

    console.write( "editor.getRectangularSelectionCaret()              = " + str(editor.getRectangularSelectionCaret() ) + "\n")
    console.write( "editor.getRectangularSelectionAnchor()             = " + str(editor.getRectangularSelectionAnchor()) + "\n")
    console.write( "editor.getSelectionStart()                         = " + str(editor.getSelectionStart()            ) + "\n")
    console.write( "editor.getSelectionEnd()                           = " + str(editor.getSelectionEnd()              ) + "\n")
    console.write( "editor.getCurrentPos()                             = " + str(editor.getCurrentPos()                ) + "\n")
    console.write( "editor.getAnchor()                                 = " + str(editor.getAnchor()                    ) + "\n")
    console.write( "editor.getRectangularSelectionAnchorVirtualSpace() = " + str(editor.getRectangularSelectionAnchorVirtualSpace()) + "\n")
    console.write( "editor.getRectangularSelectionCaretVirtualSpace()  = " + str(editor.getRectangularSelectionCaretVirtualSpace() ) + "\n")
    console.write( "editor.getSelectionNCaretVirtualSpace(0)           = " + str(editor.getSelectionNCaretVirtualSpace(0)          ) + "\n")
    console.write( "editor.getSelectionNAnchorVirtualSpace(0)          = " + str(editor.getSelectionNAnchorVirtualSpace(0)         ) + "\n")

if editor.getRectangularSelectionCaret()              == -1 and \
   editor.getRectangularSelectionAnchor()             == -1 and \
   editor.getSelectionStart()                         == 0  and \
   editor.getSelectionEnd()                           == 0  and \
   editor.getCurrentPos()                             == 0  and \
   editor.getAnchor()                                 == 0  and \
   editor.getRectangularSelectionAnchorVirtualSpace() == 0  and \
   editor.getRectangularSelectionCaretVirtualSpace()  == 0  and \
   editor.getSelectionNCaretVirtualSpace(0)           == 0  and \
   editor.getSelectionNAnchorVirtualSpace(0)          == 0:
    currentPos = editor.getCurrentPos()
    # Debug   
    if debug:   
        console.write( "state 0\n")
if editor.getRectangularSelectionCaret() != 0 and editor.getRectangularSelectionAnchor() != 0:
    if editor.getSelectionStart() == editor.getRectangularSelectionCaret() and \
       editor.getSelectionEnd()   == editor.getRectangularSelectionAnchor():
        # Debug
        if debug:
            console.write( "state 1\n" )
        currentPos = min(editor.getRectangularSelectionCaret(),editor.getRectangularSelectionAnchor())
    elif editor.getSelectionStart() < editor.getRectangularSelectionCaret():
        # Debug
        if debug:
            console.write( "state 2\n")
        currentPos = editor.getSelectionStart()
    elif editor.getSelectionStart() == editor.getRectangularSelectionCaret() and \
         editor.getSelectionEnd()   >  editor.getRectangularSelectionAnchor():
        currentPos = min(editor.getRectangularSelectionCaret(),editor.getRectangularSelectionAnchor())
        # Debug
        if debug:
            console.write( "state 3\n")
elif editor.getCurrentPos() != 0 and editor.getAnchor() != 0:
    # Debug
    if debug:
        console.write( "state 4\n")
    currentPos = min(editor.getCurrentPos(),editor.getAnchor())
elif editor.getSelectionStart() == editor.getRectangularSelectionCaret() and \
     editor.getSelectionEnd()   >  editor.getRectangularSelectionAnchor():
    # Debug
    if debug:
        console.write( "state 5\n")
    currentPos = min(editor.getRectangularSelectionCaret(),editor.getRectangularSelectionAnchor())
else:
    currentPos = editor.getCurrentPos()
    # Debug
    if debug:
        console.write( "state 6\n")

# Debug
if debug:
    console.write( "currentPos = " + str(currentPos) + "\n")

if editor.getRectangularSelectionAnchorVirtualSpace()   != editor.getRectangularSelectionCaretVirtualSpace() and \
   ( editor.getRectangularSelectionAnchorVirtualSpace() == editor.getSelectionNCaretVirtualSpace(0)          and \
     editor.getSelectionNCaretVirtualSpace(0)           == editor.getSelectionNAnchorVirtualSpace(0) ):
    prefix = editor.getRectangularSelectionCaretVirtualSpace()
    # Debug
    if debug:
        console.write( "state 7\n")
else:
    prefix = min(editor.getSelectionNCaretVirtualSpace(0),editor.getSelectionNAnchorVirtualSpace(0))
    # Debug
    if debug:
        console.write( "state 8\n")

# Debug
if debug:
    console.write( "prefix = " + str(prefix) + "\n")

prefixSpaces = "".ljust(prefix,' ') 
eolmode      = editor.getEOLMode()

# SC_EOL_CRLF (0), SC_EOL_CR (1), or SC_EOL_LF (2)
if eolmode == 0:
    eol = "\r\n"
    eolcnt = 2
elif eolmode == 1:
    eol = '\r'
    eolcnt = 1
elif eolmode == 2:
    eol = "\n"
    eolcnt = 1

if prefix > 0:
    if currentPos < editor.getCurrentPos():
        editor.insertText(editor.getLineEndPosition(editor.lineFromPosition(currentPos)),prefixSpaces)
        editor.gotoPos(editor.getLineEndPosition(editor.lineFromPosition(currentPos+prefix)))
        start = currentPos+prefix
        # Debug
        if debug:
            console.write( "state 9\n")
    else:
        editor.insertText(editor.getLineEndPosition(editor.lineFromPosition(editor.getCurrentPos())),prefixSpaces)
        editor.gotoPos(editor.getLineEndPosition(editor.lineFromPosition(editor.getCurrentPos())))
        start = editor.getCurrentPos()
        # Debug
        if debug:
            console.write( "state 10\n")
else:
    start = currentPos
    # Debug
    if debug:
        console.write( "state 11\n")

# Debug
if debug:
    console.write( "start = " + str(start) + "\n")

if clip != "":
    if editor.getSelectionStart() != editor.getSelectionEnd() and                                         \
       ( editor.getColumn(editor.getSelectionStart()) != editor.getColumn(editor.getSelectionEnd()) or    \
         ( editor.getColumn(editor.getSelectionStart()) == editor.getColumn(editor.getSelectionEnd()) and \
           editor.getColumn(editor.getSelectionStart()) == 0 ) ) and                                      \
       prefix == 0:
        editor.clear()
        # Debug
        if debug:
            console.write( "state 12\n")

    # We are dealing with a vertical paste
    if clip.startswith("<vertical>") and clip.endswith("</vertical>"):
        clip = clip[10:-11]

        startCol  = editor.getColumn(start)
        startRow  = editor.lineFromPosition(start)

        # Debug
        if debug:
            console.write( "startCol = " + str(startCol) + "\n")

        # Debug
        if debug:    
            console.write( "startRow = " + str(startRow) + "\n")

        # keepends = False
        clipSplit = clip.splitlines(False)

        clipSplitLen = len(clipSplit)

        for index,line in enumerate(clipSplit):
            if index == 0:
                localPrefixSpaces = ""
            elif index == (clipSplitLen-1):
                localPrefixSpaces = prefixSpaces
            else:
                localPrefixSpaces = prefixSpaces

            try:
                editorLine = editor.getLine(startRow+index).strip(eol)
                editorLineLen = len(editorLine)

                # Empty line
                if editorLineLen == 0:
                    editor.insertText(editor.positionFromLine(startRow+index),"".ljust(startCol,' '))
                    editor.insertText(editor.findColumn(startRow+index,startCol),line)
                else:
                    if editorLineLen < startCol:
                        editor.insertText(editor.getLineEndPosition(startRow+index),"".ljust(startCol-editorLineLen,' '))
                    editor.insertText(editor.findColumn(startRow+index,startCol),line)

            # End of file
            except IndexError:
                editor.documentEnd()
                editor.appendText(eol)
                editor.appendText("".ljust(startCol,' ') + line)

        editor.setCurrentPos(start)
        editor.setSelection(start,start)
    # We are dealing with a horizontal paste
    else:
        editor.insertText(start, clip)
        editor.setCurrentPos(start + len(clip))
        editor.setSelection(start + len(clip),start + len(clip))

# End the undo action, so Ctrl-z will undo the above two actions
editor.endUndoAction()

# Debug
if debug:
    notepad.activateBufferID(bufferID)

这假设 VirtualSpaceOptions 设置为 3。将
文件修改C:\projects\misc\PythonScriptNppPlugin\startup.py为以下
代码并确保它在每次 notepad++ 启动时运行。

# $Revision: 1.2 $
# $Author: dot $
# $Date: 2012/03/23 20:59:46 $

# The lines up to and including sys.stderr should always come first
# Then any errors that occur later get reported to the console
# If you'd prefer to report errors to a file, you can do that instead here.
import sys
from Npp import *

# Set the stderr to the normal console as early as possible, in case of early errors
sys.stderr = console

# Define a class for writing to the console in red
class ConsoleError:
    def __init__(self):
        global console
        self._console = console;

    def write(self, text):
        self._console.writeError(text);

    def flush(self):
        pass

# Set the stderr to write errors in red
sys.stderr = ConsoleError()

# This imports the "normal" functions, including "help"
import site

# See docs
#   http://npppythonscript.sourceforge.net/docs/latest/intro.html
#   http://npppythonscript.sourceforge.net/docs/latest/scintilla.html
def set_word_chars(args):
    # Enable the virtual space options for both Scintilla views
    # For more information, see the Scintilla documentation on virtual space and the SCI_SETVIRTUALSPACEOPTIONS message.
    editor.setVirtualSpaceOptions(3)
    # Set the word characters
    editor.setWordChars('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$')

notepad.callback(set_word_chars, [NOTIFICATION.BUFFERACTIVATED])

# This sets the stdout to be the currently active document, so print "hello world", 
# will insert "hello world" at the current cursor position of the current document
sys.stdout = editor

editor.setVirtualSpaceOptions(3)
# Set the word characters
editor.setWordChars('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$')
#console.show()
于 2012-03-23T18:14:17.283 回答