Skip to content
hupfdule edited this page Aug 3, 2026 · 1 revision

About nb-edit-externally

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.

About this wiki

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.

Placeholders

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.

Commandline examples

Running TUI editor in a terminal emulator

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.

urxvt

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.

kitty

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.

Editors

vim (and compatible editors)

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.

Opening file in vim with the current cursor position

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.

Opening file in vim with preselected text

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} == -1 checks 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 else and endif will 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".
    • \zs starts the match at this point. This places the cursor exactly after the character. This is necessary as "selectionStart0" is 0-based.
  • execute 'normal! v starts 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.

Executing several other commands when opening the file in vim

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

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.

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).

Emacs

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.

Opening file in Emacs with the current cursor position

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-wait is silently ignored once --eval is used (per emacsclient's manual), so this call blocks until evaluation finishes.
  • (progn (find-file "${file}") ...): In --eval mode, emacsclient never visits file arguments on its own, so the file has to be opened explicitly with find-file as the first step.
  • (goto-line ${line}) (move-to-column ${column0}): place cursor at the caret's line/column. line is 1-based, column0 is 0-based. Each matches what goto-line/move-to-column natively expect, so no conversion arithmetic is needed here.
Opening file in Emacs with preselected text

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-wait is silently ignored once --eval is used (per emacsclient's manual), so this call blocks until evaluation finishes.
  • (progn (find-file "${file}") ...): In --eval mode, emacsclient never visits file arguments on its own, so the file has to be opened explicitly with find-file as the first step.
  • (if (= ${selectionStart} -1) ... ...): "selectionStart" is -1 when 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. line is 1-based, column0 is 0-based. Each matches what goto-line/move-to-column natively expect, so no conversion arithmetic is needed here.
  • (progn (push-mark ${selectionStart} t t) (goto-char ${selectionEndExclusive})): Selection branch.
    • push-mark POSITION NOMSG ACTIVATE sets Emacs' mark at the selection start; t t suppresses the echo message and activates the mark immediately.
    • goto-char POSITION moves 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/+2 arithmetic is needed.
    • With the mark active, the region between mark and point becomes the visible selection -- Emacs' equivalent of Vim's visual mode.

Notepad++

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}"

Custom shellscript

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.

Window managers

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.

Tips and tricks

Windows file paths

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.