-
Notifications
You must be signed in to change notification settings - Fork 0
Home
nb-edit-externally is a NetBeans plugin that allows editing files in an external editor.
The main purpose of this plugin is to use sophisticated editing capabilities that go beyond NetBeans' capabilities.
The commandlines to call the external editors are freely configurable and support several placeholders that will be filled by the plugin to be able to jump to the same cursor position in the file or preselect the same text as currently in the NetBeans editor.
The intention of this wiki is to help users writing such commandlines to get the biggest benefit out of the plugin and their editor.
This wiki is free for editing by its users and it is meant to be filled by users.
Do you have an example for a specific editor you use? Please provide an example so other users can benefit from it without having to look up the whole documentation of that editor.
You created a nifty commandline that utilized all the power of your editor? Please describe it here. Others may not only benefit by copying your example, but may also be inspired to solve the same problem in other editors, or to find a different way to solve it.
You do not need commit permissions to this repository, but you need to have a valid GitHub account. If you do not have a GitHub account, but still want to provide an example, do so by opening a discussion.
nb-edit-externally provides the following placeholders that can be used in the commandline that will be prefilled when calling the commandline.
Such placeholders need to be enclosed in braces with a preceding dollar sign:
${placeholder}
This is just a short reference of the available placeholders. See the README for a more thorough explanation.
The following placeholders are always available, for files that are open in an editor (edit externally) as well as for files without an associated editor window (open externally).
| Placeholder | Meaning |
|---|---|
${file} |
The absolute path to the file |
${fileName} |
The file name of the file |
${fileBasename} |
The file name of the file without extension |
${fileExt} |
The file extension of the file |
The following placeholders are only available for files with an associated editor window.
| Placeholder | Meaning |
|---|---|
${line0} |
The line of the cursor location (0-based). |
${line} |
The line of the cursor location (1-based). |
${column0} |
The column of the cursor location (0-based). |
${column} |
The column of the cursor location (1-based). |
${selectedText} |
The currently selected text or an empty string if no text is selected. |
${selectionStart0} |
The location of the first character of a selection (number of chars in the file, 0-based) or -1 if no text is selected. |
${selectionStart} |
The location of the first character of a selection (number of chars in the file, 1-based) or -1 if no text is selected. |
${selectionEnd0} |
The location of the last character of a selection (number of chars in the file, 0-based) or -1 if no text is selected. |
${selectionEnd} |
The location of the last character of a selection (number of chars in the file, 1-based) or -1 if no text is selected. |
${selectionEndExclusive0} |
The location of the first character after the selection (number of chars in the file, 0-based) or -1 if no text is selected. |
${selectionEndExclusive} |
The location of the first character after the selection (number of chars in the file, 1-based) or -1 if no text is selected. |
TUI editors usually need a terminal emulator to run in. Therefore it is not enough to call the editor directly, but as a command to execute in a terminal emulator.
Here are some examples of how to do this for certain terminal emulators. The actual editor commands are only simple examples (to leave the focus on the terminal emulator wrapper), but can usually be arbitrarily complex. Examples for the actual editor commands are given further down in this document.
To run an editor in urxvt use its -e option. The remainder of the commandline is the actual editor command and its arguments. No special escaping is necessary.
urxvt -e vim ${file} -y "+call cursor(${line}, ${column})"This opens vim in urxvt and sets the cursor to same location as in the NetBeans editor ("+call cursor(${line}, ${column})").
The option -y is given to vim (not urxvt) and starts vim in easy-mode.
Running an editor in kitty is easy. Just add the command with all its options after kitty's options:
kitty vim ${file} -y "+call cursor(${line}, ${column})"This opens vim in kitty and sets the cursor to same location as in the NetBeans editor ("+call cursor(${line}, ${column})").
The option -y is given to vim (not kitty) and starts vim in easy-mode.
The following should apply to the original vim as well as most of its clones, like neovim, neovide, etc.
Vim allows for executing arbitrary vimscript on the command line. This allows for some nifty tricks that utilize the full power of nb-edit-externally.
Due to the flexibility of vim there are several ways to achieve the same goal. This is only one example of setting the cursor location to the location in NetBeans.
vim ${file} "+call cursor(${line}, ${column})"This uses the builtin function cursor() to jump to the given position.
It is a good idea to always wrap these commands in quotes. In most cases this is necessary as any but the most simple commands will include some whitespace.
While not as straight-forward as positioning the cursor, it is also possible to select the same text (in visual mode) that is currently selected in the NetBeans editor.
vim ${file}
"+if ${selectionStart0} == -1
| call cursor(${line}, ${column})
| else
| call cursor(1, 1)
| call search('\\%^\\_.\\{${selectionStart0}\\}\\zs', '')
| execute 'normal! v'
| call search('\\%^\\_.\\{${selectionEnd0}\\}\\zs', '')
| endif
"Explanation:
-
if ${selectionStart0} == -1checks whether any text is selected.
A value of -1 for any of the selection indexes means there is no selection. -
call cursor(${line}, ${column})will be executed if there is no selection.
This is just the behaviour as in the example above to place the cursor at the given location. - All the commands between
elseandendifwill be executed if there is a selection. -
call cursor(1, 1)Position the cursor at the first character. Should usually not be necessary, but is good practice to be explicit about the intention. -
call search('\\%^\\_.\\{${selectionStart0}\\}\\zs', '')This jumps to the selection start by using the builtin search() function.
This is a vim regex. The backslashes are escaped by doubling them. In the following explanation they are not escaped for better readability.-
\%^anchors the search at the beginning of the file -
\_.matches any character, including line breaks -
\{x}matches x characters. In this case the number represented by "selectionStart0". -
\zsstarts the match at this point. This places the cursor exactly after the character. This is necessary as "selectionStart0" is 0-based.
-
-
execute 'normal! vstarts character-wise visual mode -
call search('\\%^\\_.\\{${selectionEnd0}\\}\\zs', '')same as above, only this time for the last character of the selection.
Caveat: This command does not place the cursor at the same location as in NetBeans. While the cursor in NetBeans may be at the start or the end of the selection, this approach always places the cursor at the end of the selection in vim. Resembling the cursor location from NetBeans in vim will require more effort.
Vim allows concatenating several commands in a single line by separating
them with a bar |. This is already used in the example above for Opening
a file in vim with preselected
text. But it can be used to
execute any other vim commands like:
vim "+call cursor(${line}, ${column}) | set bg=dark | colorscheme gruvbox"In this case additionally to placing the cursor, the editor is set to dark mode and the gruvbox colorscheme is selected.
Neovide is a graphical Neovim UI and therefore the examples in the vim section apply to this one as well.
But Neovide, being a graphical UI has some additional functionality that can be utilized.
First, it does not need to be run in a terminal emulator. But it supports additional options that can be utilized, e.g. a fullscreen mode.
neovide ${file} "+let g:neovide_fullscreen=v:true | colorscheme gruvbox"Running neovide in fullscreen mode can be achieved by setting the vim
variable g:neovide_fullscreen along with all the other typical vimscript
commands. The example above not only sets the fullscreen mode (neovide
specific), but also sets the colorscheme to gruvbox (common vim
functionality).
Using Emacs as editor should probably be done by using an Emacs server
(started via emacs --daemon or inside a running Emacs session via M-x server-start). This makes opening a file in Emacs nearly instant. Therefore
the following examples use emacsclient to utilize that daemon.
If you are only interested in positioning the cursor, this command can be used:
emacsclient -n --eval '
(progn
(find-file "${file}")
(goto-line ${line})
(move-to-column ${column0}))
'-
emacsclient -n --eval '...': talks to the running Emacs server.-n/--no-waitis silently ignored once--evalis used (peremacsclient's manual), so this call blocks until evaluation finishes. -
(progn (find-file "${file}") ...): In--evalmode,emacsclientnever visits file arguments on its own, so the file has to be opened explicitly withfind-fileas the first step. -
(goto-line ${line}) (move-to-column ${column0}): place cursor at the caret's line/column.lineis 1-based,column0is 0-based. Each matches whatgoto-line/move-to-columnnatively expect, so no conversion arithmetic is needed here.
If you also want to apply a selection, this command can be used. It differentiates whether a selection exists or not (in which case only the cursor is placed).
emacsclient -n --eval '
(progn
(find-file "${file}")
(if (= ${selectionStart} -1)
(progn
(goto-line ${line})
(move-to-column ${column0}))
(progn
(push-mark ${selectionStart} t t)
(goto-char ${selectionEndExclusive}))))
'-
emacsclient -n --eval '...': talks to the running Emacs server.-n/--no-waitis silently ignored once--evalis used (peremacsclient's manual), so this call blocks until evaluation finishes. -
(progn (find-file "${file}") ...): In--evalmode,emacsclientnever visits file arguments on its own, so the file has to be opened explicitly withfind-fileas the first step. -
(if (= ${selectionStart} -1) ... ...): "selectionStart" is-1when nothing is selected, so this is a plain numeric check, no string comparison needed. -
(progn (goto-line ${line}) (move-to-column ${column0})): No-selection branch:
place point at the caret's line/column.lineis 1-based,column0is 0-based. Each matches whatgoto-line/move-to-columnnatively expect, so no conversion arithmetic is needed here. -
(progn (push-mark ${selectionStart} t t) (goto-char ${selectionEndExclusive})): Selection branch.-
push-mark POSITION NOMSG ACTIVATEsets Emacs' mark at the selection start;t tsuppresses the echo message and activates the mark immediately. -
goto-char POSITIONmoves point to the selection end. - Both placeholders are already 1-based boundary positions -- the same
convention Emacs' own point/mark use -- so, unlike the earlier version of
this command, no
+1/+2arithmetic is needed. - With the mark active, the region between mark and point becomes the visible selection -- Emacs' equivalent of Vim's visual mode.
-
Notepad++ does not support setting the selection via commandline. Therefore we can only place the cursor at the desired location.
"c:/Program Files/Notepad++/notepad++.exe" -n${line} -c${column} "${file}"Of course instead of directly calling an editor a custom script (POSIX Shell, Python, ...) can be used. That is especially handy if there are lots of complicated calculations necessary to convert the valued nb-edit-externally provides to the parameters the actual editor expects.
But in the end what you are able to do is still restricted by the possibilities your editor provides.
Note
There could be some tricks, like explicitly setting the focus to the opened editor, that might be worth mentioning.
Do not hesitate to add them here.
Since file paths under MS Windows usually use the backslash as file separator. Such backslashed must be escaped by additional backslashes:
"C:\\Program Files\\Notepad++\\notepad++.exe" -multiInst -n${line} -c${column} "${file}"
An easier, and more readable, approach is using a forward slash as path separator:
"C:/Program Files/Notepad++/notepad++.exe" -multiInst -n${line} -c${column} "${file}"
Note
Do you have any tips and tricks worth mentioning? Feel free to add them here.