Copy with line numbers
-
I think TextFX plugin had a “copy with line numbers” option, but I’ve long since stopped using TextFX and moved to N++ 64-bit where there is no TextFX option. Most of it’s features are available anyway. But “copy with line numbers” is very useful for the few and far between times I do need to use it.
I’m pretty good with NppExec, so here’s a little script I whipped up to do “copy with line numbers”:
SCI_SENDMSG SCI_GETSELECTIONSTART SCI_SENDMSG SCI_LINEFROMPOSITION $(MSG_RESULT) SET LOCAL START = $(MSG_RESULT) SCI_SENDMSG SCI_GETSELECTIONEND SCI_SENDMSG SCI_LINEFROMPOSITION $(MSG_RESULT) SET LOCAL END = $(MSG_RESULT) SCI_SENDMSG SCI_GETCURRENTPOS SCI_SENDMSG SCI_GETCOLUMN $(MSG_RESULT) SET LOCAL COLUMNEND = $(MSG_RESULT) :LOOP IF $(START)==$(END) THEN IF $(COLUMNEND)==0 GOTO END ENDIF ENDIF SCI_SENDMSG SCI_GETLINE $(START) @"" SET LOCAL LINE ~ $(START) + 1 ECHO $(LINE): $(MSG_LPARAM) IF $(START)==$(END) GOTO END SET LOCAL START ~ $(START) + 1 GOTO LOOP :END
Note the “space” between the colon and dollar sign in the `ECHO $(LINE): $(MSG_LPARAM)" line is actually a TAB which makes the output look better. Of course, this only outputs to the NppExec Console; you need to then highlight it and copy to be able to paste it somewhere.
NppExec has a “clip_settext” command which can set the clipboard text, but you can see the problem in my loop is that i output the text rather than concatenate it to a variable.
QUESTION:
It seems NppExec doesn’t have a way to do “string addition” or string concatenation? Unless I’m missing something?I’m sure this is pretty trivial in [Python|Lua]Script plugins.
Cheers.
-
@Michael-Vincent said in Copy with line numbers:
It seems NppExec doesn’t have a way to do “string addition” or string concatenation?
No, it has.
Please remind: NppExec works like a console script language, not like a normal programming language.
Type the following commands into a NppExec console window or add them as a script to the
npes_saved.txt
file:set local Foo = Bar echo $(Foo) set local Foo = $(Foo) Bar echo $(Foo) set local Foo = $(Foo) $(Foo) echo $(Foo)
You can also use the following notation:
set local $(Foo) = Bar echo $(Foo) set local $(Foo) = $(Foo) Bar ...
-
@dinkumoil said in Copy with line numbers:
No, it has.
I’m embarrassed to say I didn’t even try that and of course it “works” but it’s not preserving the line endings so it’s just adding one big line of text. Partial success.
my first line
my second line
my third lineOutput should be:
1 my first line
2 my second line
3 my third linebut instead is:
1 my first line2 my second line3 my third line
I think the ECHO in my first “solution” is helping by adding in that carriage return / line feed which I was assuming should be part of the captured text from the SCI_GETLINE call.
Cheers.
-
OK - weird workaround, but pasting a unix line ending into Windows Notepad results in a zero-length character that you can actually “highlight” (it doesn’t look like anything highlights) and then copy and paste it into the script:
ECHO $(LINE): $(MSG_LPARAM)
becomes:
SET LOCAL OUTTEXT = $(OUTTEXT)$(LINE): $(MSG_LPARAM)
where the zero-length carriage return is between …EXT)[HERE]$(LIN…
And then after :END, use:
CLIP_SETTEXT $(OUTTEXT)
Cheers.
-
@Michael-Vincent said in Copy with line numbers:
I’m sure this is pretty trivial in [Python|Lua]Script plugins.
Yep, the following Pythonscript will copy to the clipboard the lines touched by the currently active selection, prepended with their line numbers:
# -*- coding: utf-8 -*- from Npp import editor, notepad, NOTIFICATION import math def main(): start_line = editor.lineFromPosition(editor.getSelectionStart()) sel_end = editor.getSelectionEnd() end_line = editor.lineFromPosition(sel_end) if editor.positionFromLine(end_line) == sel_end: end_line -= 1 field_width_for_line_number = int(math.log(end_line + 1, 10)) + 1 accum = '' for line_number in range(start_line, end_line + 1): accum += '{ln:{width}}:{contents}'.format(ln=line_number+1, width=field_width_for_line_number, contents=editor.getLine(line_number)) editor.copyText(accum) main()
Example output:
8: sel_end = editor.getSelectionEnd() 9: end_line = editor.lineFromPosition(sel_end) 10: if editor.positionFromLine(end_line) == sel_end: end_line -= 1
-
@Michael-Vincent said in Copy with line numbers:
OK - weird workaround
Much better:
::copylinenums NPP_CONSOLE keep SET LOCAL CR ~ STRFROMHEX 0xd SET LOCAL LF ~ STRFROMHEX 0xa SCI_SENDMSG SCI_GETSELECTIONSTART SCI_SENDMSG SCI_LINEFROMPOSITION $(MSG_RESULT) SET LOCAL START = $(MSG_RESULT) SCI_SENDMSG SCI_GETSELECTIONEND SCI_SENDMSG SCI_LINEFROMPOSITION $(MSG_RESULT) SET LOCAL END = $(MSG_RESULT) SCI_SENDMSG SCI_GETCURRENTPOS SCI_SENDMSG SCI_GETCOLUMN $(MSG_RESULT) SET LOCAL COLUMNEND = $(MSG_RESULT) :LOOP IF $(START)==$(END) THEN IF $(COLUMNEND)==0 GOTO END ENDIF ENDIF SCI_SENDMSG SCI_GETLINE $(START) @"" SET LOCAL LINE ~ $(START) + 1 // ECHO $(LINE): $(MSG_LPARAM) SET LOCAL OUTTEXT = $(OUTTEXT)$(LINE): $(MSG_LPARAM)$(CR)$(LF) IF $(START)==$(END) GOTO END SET LOCAL START ~ $(START) + 1 GOTO LOOP :END CLIP_SETTEXT $(OUTTEXT)
Cheers.