Notepad ++ вертикальный блок выберите копировать вставить не сохраняется в клипах - PullRequest
1 голос
/ 20 марта 2012

Я использую Notepad ++ для вертикального выделения и копирования блоков текста.Вставка последнего блока текста (который в настоящее время находится в буфере буфера обмена) работает нормально, однако при возврате ко второму и третьему предыдущим буферам буфера обмена (которые изначально были скопированы как блоки) не вставляются эти другие буферы как блоки, а скорее какпервая строка, за которой следует новая строка, вторая строка - новая строка и т. д. и т. д.

Например, предположим, что я блокирую копию следующего блока

      test
      test
      test

Последний буфер буфера обмена вставляется как

      test
      test
      test

при условии, что курсор имеет 4 пробела с отступом.Однако, если последний буфер буфера обмена перемещается на второе место в очереди буферов буфера обмена, я получаю следующую вставку:

      test
test
test

Я использую ClipMate для хранения предыдущих буферов буфера обмена.

Почему notepad ++ знает, что нужно вставлять последние текстовые данные буфера обмена (скопированные как блоки), а не вставлять их в буфере буфера обмена с точностью до второго?

Есть ли способ сохранить состояние блока клипов буфера обмена?

Ответы [ 2 ]

1 голос
/ 23 марта 2012

Я написал решение с использованием плагина 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.py до C:\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()
1 голос
/ 21 марта 2012

Похоже, что Notepad ++ вставляется из внутреннего буфера и не получает данные из буфера обмена. Существует частный формат данных MSDEVColumnSelect, но если я попытаюсь заставить ClipMate перехватить его, данные будут пустыми. Так что, похоже, это тот случай, когда приложение играет в копирующие и копирующие игры, а на самом деле это не функция буфера обмена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...