4.6.11. Clone current document to new editor pane

Let's consider the following scenario: you want to copy the entire content of the current document (opened in Notepad++) and paste it to a new editor pane.

The first implementation that comes to your mind is:

  1. save the current position of the caret;
  2. select all the text and copy it to the clipboard;
  3. restore the position of the caret;
  4. open a new editor pane and paste the text from the clipboard.

As Notepad++ uses Scintilla component to handle the text and all the text operations, let's deal directly with Scintilla to implement all of the above. Let's refer to Scintilla's documentation to get an idea of how to do it:

Looking at the documentation, we may end up with the following NppExec script:

// saving the caret pos & anchor
sci_sendmsg SCI_GETCURRENTPOS
set local pos = $(MSG_RESULT)
sci_sendmsg SCI_GETANCHOR
set local anchor = $(MSG_RESULT)

// selecting all
sci_sendmsg SCI_SELECTALL

// copying the selection to the clipboard
sci_sendmsg SCI_COPY

// restoring the caret pos & anchor
sci_sendmsg SCI_SETSEL $(anchor) $(pos)

// open new editor pane
NPP_SENDMSG WM_COMMAND IDM_FILE_NEW

// pasting the text from the clipboard
sci_sendmsg SCI_PASTE

Inspecting the Scintilla's documentation further, we can notice SCI_COPYRANGE that allows to simplify the entire script:

// getting the length of the document
sci_sendmsg SCI_GETTEXTLENGTH
set local textlength = $(MSG_RESULT)

// copying the entire text to the clipboard
sci_sendmsg SCI_COPYRANGE 0 $(textlength)

// open new editor pane
NPP_SENDMSG WM_COMMAND IDM_FILE_NEW

// pasting the text from the clipboard
sci_sendmsg SCI_PASTE

Looking into "Notepad_plus_msgs.h" ("PowerEditor\src\MISC\PluginsManager\Notepad_plus_msgs.h"), we can implement an advanced version of this script that:

Here is the final NppExec's script:

// getting the current buffer id
npp_sendmsg NPPM_GETCURRENTBUFFERID
set local originalBufferId = $(MSG_RESULT)

// getting the current buffer encoding & lang type
npp_sendmsg NPPM_GETBUFFERENCODING $(originalBufferId)
set local bufEnc = $(MSG_RESULT)
npp_sendmsg NPPM_GETBUFFERLANGTYPE $(originalBufferId)
set local bufLangType = $(MSG_RESULT)

// getting the caret pos & anchor
sci_sendmsg SCI_GETCURRENTPOS
set local pos = $(MSG_RESULT)
sci_sendmsg SCI_GETANCHOR
set local anchor = $(MSG_RESULT)
sci_sendmsg SCI_GETFIRSTVISIBLELINE
set local firstvisibleline = $(MSG_RESULT)

// getting the length of the document
sci_sendmsg SCI_GETTEXTLENGTH
set local textlength = $(MSG_RESULT)

// copying the entire text to the clipboard
sci_sendmsg SCI_COPYRANGE 0 $(textlength)

// opening a new editor pane (new document)
NPP_SENDMSG WM_COMMAND IDM_FILE_NEW

// getting the new buffer id
npp_sendmsg NPPM_GETCURRENTBUFFERID
set local newBufferId = $(MSG_RESULT)

// setting the new buffer encoding & lang type
npp_sendmsg NPPM_SETBUFFERENCODING $(newBufferId) $(bufEnc)
npp_sendmsg NPPM_SETBUFFERLANGTYPE $(newBufferId) $(bufLangType)

// pasting the text from the clipboard
sci_sendmsg SCI_PASTE

// setting the caret pos & anchor
sci_sendmsg SCI_SETSEL $(anchor) $(pos)
sci_sendmsg SCI_SETFIRSTVISIBLELINE $(firstvisibleline)

Note: in this last script, originally I was thinking to use SCI_GETCODEPAGE and SCI_SETCODEPAGE to deal with the text encoding. But it appeared that Notepad++ does not seem to be aware of the encoding change by SCI_SETCODEPAGE. So I've used the Notepad++'s way of dealing with encoding via NPPM_GETBUFFERENCODING and NPPM_SETBUFFERENCODING.