Let's suppose you want to apply some AWK program to your selected text in Notepad++.
The first thing you require is NppExec plugin ;)
The second thing you require is an AWK executable, for example, "awk95.exe" or "gawk.exe".
When you want to apply some AWK program to your selected text, this AWK program must exist, isn't it? So, create a file "do.awk" in your Notepad++'s folder. The full path to this file is "$(NPP_DIRECTORY)\do.awk".
OK, the file is created, now you need some AWK program. Open the "do.awk" in Notepad++ and type your program, for example:
{ print $0 }
This simple AWK program will print each record (i.e. text line) from the input file given.
Now, open another file in Notepad++ and select some text (few lines, for example).
Now you have the selected text and a tool (awk95.exe or gawk.exe) you want to apply to this selected text.
The only thing remaining is NppExec's script which will allow you to do what you want.
Press F6 (or Plugins -> NppExec -> Execute NppExec Script...) and type:
// full path to AWK executable set local AWK_EXE = C:\tools\awk\awk95.exe // this temporary file name will be used set local TEMP_FILE = $(SYS.TEMP)\npp_sel.txt // save current selection as ANSI text file SEL_SAVETO $(TEMP_FILE) :a // run do.awk for this file "$(AWK_EXE)" -f "$(NPP_DIRECTORY)\do.awk" "$(TEMP_FILE)"
Save this script as "do.awk on selected text" or whatever you want.
Press OK.
You will see the AWK's output in the NppExec's Console window. You can copy it from there with Ctrl+C.
As you understand, such approach can be used for any command-line external tool such as grep, php and so on.
Good luck!
P.S. By the way, if you have nothing selected and you want to select a word under the caret, the following script can be used:
// get current position... SCI_SENDMSG SCI_GETCURRENTPOS set local pos = $(MSG_RESULT) // get start of a word near the pos... SCI_SENDMSG SCI_WORDSTARTPOSITION $(pos) 1 set local wordStart = $(MSG_RESULT) // get end of a word near the pos... SCI_SENDMSG SCI_WORDENDPOSITION $(pos) 1 set local wordEnd = $(MSG_RESULT) // set selection SCI_SENDMSG SCI_SETSEL $(wordStart) $(wordEnd)
If you combine this script with the previous one, you will be able to apply an external tool to a word under the caret. (I.e. first it will select a word under the caret, and then will apply an external tool to that selected word.) Also consider ability to use $(CURRENT_WORD) instead of SEL_SAVETO in this case (see [4.6.3]).
P.P.S. If you don't want to use a temporary file and pass the selected text via a command line instead, refer to the following approach.
We'll be sending the selected string to an external tool by means of cmd /C echo, so let's create an auxiliary NppExec's script that will escape special characters for the echo command:
// escape_string_for_cmd_echo
if $(ARGC) != 2 then
set ECE_RESULT = 0 // failed
exit
endif
set local s ~ strreplace `$(ARGV[1])` `^` `^^^^` // double-escaping the '^' char
set local s ~ strreplace `$(s)` `|` `^^^|` // double-escaping the '|' char
set local s ~ strreplace `$(s)` `&` `^^^&` // double-escaping the '&' char
set local s ~ strreplace `$(s)` `<` `^^^<` // double-escaping the '<' char
set local s ~ strreplace `$(s)` `>` `^^^>` // double-escaping the '>' char
set local s ~ strreplace `$(s)` `(` `^(` // escaping the '(' char
set local s ~ strreplace `$(s)` `)` `^)` // escaping the ')' char
set local s ~ strreplace `$(s)` `"` `^"` // escaping the '"' char
set ECE_STR = $(s) // the escaped string
set ECE_RESULT = 1 // succeeded
Save this script as "escape_string_for_cmd_echo".
Now, having the auxiliary script above, let's create an NppExec's script that will send the selected string to an external tool:
npp_console local - // disabling output to the Console npe_console local -- m- // disabling the internal messages set local AWK_EXE = C:\tools\awk\awk95.exe // path to an external tool npp_exec escape_string_for_cmd_echo `$(SELECTED_TEXT)` if $(ECE_RESULT) != 1 then npp_console local + // enabling the output echo ERROR: Could not escape a string (maybe it contains the ` symbol?) exit endif set local s = $(ECE_STR) // the escaped string npp_console local + // enabling the output cmd /C echo $(s)| "$(AWK_EXE)" -f "$(NPP_DIRECTORY)\do.awk"
This example works with a single-line selection. But what if the selection is multi-line? In such case, we may need to split the selected text to lines and pass each line to an external tool. The corresponding NppExec's script will be noticeably more complicated. Here it is:
npp_console local - // disabling output to the Console
npe_console local -- m- n- // no internal messages, no empty lines condensing
set local AWK_EXE = C:\tools\awk\awk95.exe // path to an external tool
npp_exec escape_string_for_cmd_echo `$(SELECTED_TEXT)`
if $(ECE_RESULT) != 1 then
npp_console local + // enabling the output
echo ERROR: Could not escape a string (maybe it contains the ` symbol?)
exit
endif
set local s = $(ECE_STR) // the escaped string
set local LF ~ chr 0x0A // '\n' character
set local CR ~ chr 0x0D // '\r' character
:Loop
// note: we use `` to preserve leading and trailing spaces in `$(s)`
set local posLF ~ strfind `$(s)` `$(LF)` // position of LF
set local posCR ~ strfind `$(s)` `$(CR)` // position of CR
set local pos = $(posCR)
if $(pos) == -1 then
set local pos = $(posLF) // no CR
else if $(pos) > $(posLF) then
set local pos = $(posLF) // LF is before CR
endif
if $(pos) != -1 then
set local line ~ substr 1 $(pos) `$(s)` // part of the string before CR or LF
else
set local line ~ substr 1 -1 `$(s)` // the remaining string
endif
set local len ~ strlen `$(line)` // note: `` preserves leading/trailing spaces
set local len ~ $(len) - 2 // length without ``
if $(len) != 0 then
set local cmd1 = cmd /C echo $(line)
else
set local cmd1 = cmd /C echo.
endif
npp_console local + // enabling the output
$(cmd1)| "$(AWK_EXE)" -f "$(NPP_DIRECTORY)\do.awk"
npp_console local - // disabling the output
if $(pos) != -1 then
// there is CR or LF remaining
set local pos1 ~ $(pos) + 1 // position considering '`' in `$(s)`
set local c ~ substr $(pos1) 1 `$(s)` // either CR or LF char
set local pos ~ $(pos) + 1 // skip this character
if "$(c)" == "$(CR)" then
set local pos1 ~ $(pos) + 1 // position considering '`' in `$(s)`
set local c ~ substr $(pos1) 1 `$(s)` // check the next char after CR
if "$(c)" == "$(LF)" then
set local pos ~ $(pos) + 1 // skip LF after CR
endif
endif
set local pos1 ~ $(pos) + 1 // position considering '`' in `$(s)`
set local s ~ substr $(pos1) -1 `$(s)` // the remaining part of the string
goto Loop
endif
This last script sends each line of the selected text to a new instance of cmd /C echo. This can be time-consuming for a lot of lines. Instead, if the external tool supports string splitting, we may alter our approach. In particular, we may do the following steps:
In this case, the AWK program "do.awk" will become:
{
sep = "~@#="
n = split($0, a, sep)
for (i = 1; i <= n; i++)
{
print a[i] # print each line
}
}
And here is the corresponding NppExec's script:
npp_console local - // disabling output to the Console npe_console local -- m- n- // no internal msgs, no empty lines condensing set local LF ~ chr 0x0A // '\n' character set local CR ~ chr 0x0D // '\r' character sci_sendmsg SCI_GETEOLMODE // get EOL from Scintilla set local eol = $(MSG_RESULT) if $(eol) == 2 then set local eol = $(LF) // "\n" else if $(eol) == 1 then set local eol = $(CR) // "\r" else set local eol = $(CR)$(LF) // "\r\n" endif set local alt_eol = ~@#= // unique combination of characters set local s ~ strreplace `$(SELECTED_TEXT)` `$(eol)` `$(alt_eol)` if $(LAST_CMD_RESULT) != 1 then npp_console local + // enabling the output echo ERROR: the selected text contains the ` symbol exit endif npp_exec escape_string_for_cmd_echo `$(s)` if $(ECE_RESULT) != 1 then npp_console local + // enabling the output echo ERROR: Could not escape a string (maybe it contains the ` symbol?) exit endif set local s = $(ECE_STR) // the escaped string set local t ~ strstrip 0x23 `$(s)` if `$(t)` != `` then set local cmd1 = cmd /C echo $(s) else set local cmd1 = cmd /C echo. endif npp_console local + // enabling the output $(cmd1)| awk -f "$(NPP_DIRECTORY)\do.awk"
Note: all the three last NppExec's scripts use the "escape_string_for_cmd_echo" script mentioned above. So be sure it has been created and saved.
P.P.P.S. If you want to deal with the entire text of the document rather than with the selected text, the following script can be used:
sci_sendmsg SCI_GETTEXTLENGTH // retrieving the text length into $(MSG_RESULT) set local textLen ~ $(MSG_RESULT) // the text length set local bufSize ~ $(textLen) + 1 // the text length plus the trailing '\0' npe_sendmsgbuflen local $(bufSize) // ensuring the $(bufSize) is allocated for SCI_GETTEXT sci_sendmsg SCI_GETTEXT $(textLen) @"" // retrieving the text into $(MSG_LPARAM) echo $(MSG_LPARAM) // doing something with the retrieved text - e.g. printing
See also: Processing & replacing the selection [4.6.3]; Modify selected text and save to file [4.6.17].