Question

I'm using Notepad++ to vertically select and copy blocks of text. Pasting the latest block of text (that is currently in the clipboard buffer) works fine, however going back to the second and third previous clipboard buffers (which were originally copied as blocks) does not paste these other buffers as blocks, but rather as a first line followed by newline, second line newline, etc, etc.

For example, suppose I block copy the following block

      test
      test
      test

The latest clipboard buffer pastes as

      test
      test
      test

assuming the cursor is 4 spaces indented. However, if the latest clipboard buffer is moved to the second place in the clipboard buffer queue, I get the following paste:

      test
test
test

I'm using ClipMate to store previous clipboard buffers.

Why does notepad++ know to block-paste the latest clipboard text data (copied as a block) but not the second to last clipboard buffer?

Is there a way to store a clipboard clips' block state?

Was it helpful?

Solution

It looks like Notepad++ is pasting from an internal buffer, and not taking the data from the clipboard. There IS a private data format called MSDEVColumnSelect, but if I try to force ClipMate to capture it, the data is empty. So this seems to be a case where the application is playing smoke-and-mirrors games with copy/paste, and it's not really a clipboard feature at all.

OTHER TIPS

I've written a solution using the Python Script Scintilla wrapper notepad++ plugin.

Use this for copy.
Save as C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Copy.py
Map to shortcuts Ctrl+c and 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()

Use this for cut.
Save as C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Cut.py
Map to shortcuts Ctrl+x and 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()

Now download pyperclip.py to C:\Program Files\Notepad++\plugins\PythonScript\lib
Use this for paste.
Save as C:\Program Files\Notepad++\plugins\PythonScript\scripts\Samples\Paste.py
Map to shortcuts Ctrl+v and 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)

This assumes that VirtualSpaceOptions are set to 3.
Modify file C:\projects\misc\PythonScriptNppPlugin\startup.py to the following
code below and ensure it runs on every notepad++ start.

# $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()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top