diff options
author | Anna Arad <4895022+annagrram@users.noreply.github.com> | 2019-10-23 13:04:12 +0300 |
---|---|---|
committer | Mischievous Meerkat <engineerarun@gmail.com> | 2019-10-23 15:34:12 +0530 |
commit | 9afd7cf3bf8badb7e704fb1e1fbdb8031572c722 (patch) | |
tree | 90669833f994bfcff8b8f9edc0b044f2ea2f2e89 /plugins | |
parent | 0144f440609b4fb7dcdf9e3325e6d1de3e6085bf (diff) | |
download | nnn-9afd7cf3bf8badb7e704fb1e1fbdb8031572c722.tar.gz |
Implement plugins control of nnn + plugins (#364)
* Implement plugins control of nnn + plugins
* Refactor plugins control code and fix getplugs to recognize hidden files
* Fix bug when going to dir on non-current context from plugin
* Fix some plugins to work on openbsd and freebsd
* Renamings
* Switch to -R flag in cp instead of -r; BSDs complain
* Change braces of function location
* Rewrite plugin creation in README and add new plugins to the table
* Update the fzcd script to include fzy or fzf
* Change plugin name resolve-link-dir -> lncd
* Fixing plugins README table
* Remove some cd plugins but add them as examples to plugins README
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/.nnn-plugin-helper | 33 | ||||
-rw-r--r-- | plugins/README.md | 65 | ||||
-rwxr-xr-x | plugins/fzcd | 32 | ||||
-rwxr-xr-x | plugins/getplugs | 24 |
4 files changed, 136 insertions, 18 deletions
diff --git a/plugins/.nnn-plugin-helper b/plugins/.nnn-plugin-helper new file mode 100644 index 0000000..ec66a29 --- /dev/null +++ b/plugins/.nnn-plugin-helper @@ -0,0 +1,33 @@ +#!/usr/bin/env sh + +# Description: Helper script for plugins +# +# Shell: POSIX compliant +# Author: Anna Arad + +selection=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection + +## Ask nnn to switch to directory $1 in context $2. +## If $2 is not provided, the function asks explicitly. +nnn_cd () { + dir=$1 + + if [ -z "$NNN_PIPE" ]; then + echo "No pipe file found" 1>&2 + return + fi + + if [ -n "$2" ]; then + context=$2 + else + echo -n "Choose context 1-4 (blank for current): " + read context + fi + + echo -n ${context:-0}$dir > $NNN_PIPE +} + +cmd_exists () { + which "$1" > /dev/null 2>&1 + echo $? +} diff --git a/plugins/README.md b/plugins/README.md index 85550ca..9d48ec3 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -14,6 +14,7 @@ The currently available plugins are listed below. | checksum | sh | md5sum,<br>sha256sum | Create and verify checksums | | drag-file | sh | [dragon](https://github.com/mwh/dragon) | Drag and drop files from nnn | | drop-file | sh | [dragon](https://github.com/mwh/dragon) | Drag and drop files into nnn | +| fzcd | sh | fzy/fzf<br>(optional fd) | Change to the directory of a file/directory selected by fzy/fzf | | fzy-open | sh | fzy, xdg-open | Fuzzy find a file in dir subtree and edit or xdg-open | | getplugs | sh | curl | Update plugins | | gutenread | sh | curl, unzip, w3m<br>[epr](https://github.com/wustho/epr) (optional)| Browse, download, read from Project Gutenberg | @@ -67,28 +68,68 @@ With this, plugin `fzy-open` can be run with the keybind <kbd>:o</kbd>, `mocplay **Method 2:** Use the _pick plugin_ shortcut to visit the plugin directory and execute a plugin. Repeating the same shortcut cancels the operation and puts you back in the original directory. -## File access from plugins +## Create your own plugins + +Plugins are a powerful yet easy way to extend the capabilities of `nnn`. -Plugins can access: -- all files in the directory (`nnn` switches to the dir where the plugin is to be run so the dir is `$PWD` for the plugin) -- the current file under the cursor (the file name is passed as the first argument to a plugin) -- the traversed path where plugin is invoked (this is the second argument to the plugin; for all practical purposes this is the same as `$PWD` except paths with symlinks) -- the current selection (by reading the file `.selection` in config dir, see the plugin `ndiff`) +Plugins are scripts that can be written in any scripting language. However, POSIX-compliant shell scripts runnable in `sh` are preferred. Each script has a _Description_ section which provides more details on what the script does, if applicable. -## Create your own plugins +The plugins reside in `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`. + +When `nnn` executes a plugin, it does the following: +- Change to the directory where the plugin is to be run (`$PWD` pointing to the active directory) +- Passes two arguments to the script: + 1. The hovered file's name + 2. The working directory (might differ from `$PWD` in case of symlinked paths; non-canonical) +- Sets the environment variable `NNN_PIPE` used to control `nnn` active directory. + +Plugins can also access the current selections by reading the `.selections` file in the config directory (See the `ndiff` plugin for example). -Plugins are scripts and all scripting languages should work. However, POSIX-compliant shell scripts runnable in `sh` are preferred. If that's too rudimentary for your use case, use Python, Perl or Ruby. +#### Controlling `nnn`'s active directory +`nnn` provides a mechanism for plugins to control its active directory. +The way to do so is by writing to the pipe pointed by the environment variable `NNN_PIPE`. +The plugin should write a single string in the format `<number><path>` without a newline at the end. For example, `1/etc`. +The number indicates the context to change the active directory of (0 is used to indicate the current context). -You can create your own plugins by putting them in `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`. +For convenience, we provided a helper script named `.nnn-plugin-helper` and a function named `nnn_cd` to ease this process. `nnn_cd` receives the path to change to as the first argument, and the context as an optional second argument. +If a context is not provided, it is asked for explicitly. +Usage examples can be found in the Examples section below. -For example, you could create a executable shell script `git-changes`: +#### Examples +There are many plugins provided by `nnn` which can be used as examples. Here are a few simple selected examples. +- Show the git log of changes to the particular file along with the code for a quick and easy review. + ```sh #!/usr/bin/env sh - git log -p -- "$@" + git log -p -- "$1" + ``` + +- Change to directory in clipboard using helper script + ```sh + #!/usr/bin/env sh + . $(dirname $0/.nnn-plugin-helper) + + nnn_cd "$(xsel -ob)" + ``` -And then trigger it by hitting the pick plugin key and selecting `git-changes` which will conveniently show the git log of changes to the particular file along with the code for a quick and easy review. +- Change direcory to the location of a link using helper script with specific context (current) + ```sh + #!/usr/bin/env sh + . $(dirname $0/.nnn-plugin-helper) + + nnn_cd "$(dirname $(readlink -fn $1))" 0 + ``` + +- Change to arbitrary directory without helper script + ```sh + #!/usr/bin/env sh + echo -n "cd to: " + read dir + + echo -n "0$dir" > $NNN_PIPE + ``` ## Contributing plugins diff --git a/plugins/fzcd b/plugins/fzcd new file mode 100755 index 0000000..443ac2d --- /dev/null +++ b/plugins/fzcd @@ -0,0 +1,32 @@ +#!/usr/bin/env sh + +# Description: Run fzf and go to the directory of the file selected +# +# Shell: POSIX compliant +# Author: Anna Arad + +. $(dirname $0)/.nnn-plugin-helper + +if [ "$(cmd_exists fzy)" -eq "0" ]; then + if [ "$(cmd_exists fd)" -eq "0" ]; then + fd=fd + elif [ "$(cmd_exists fdfind)" -eq "0" ]; then + fd=fdfind + else + fd=find + fi + + sel=$($fd | fzy) +elif [ "$(cmd_exists fzf)" -eq "0" ]; then + sel=$(fzf --print0) +else + exit 1 +fi + +if [ "$?" -eq "0" ]; then + case "$(file -bi "$sel")" in + *directory*) ;; + *) sel=$(dirname $sel) ;; + esac + nnn_cd "$PWD/$sel" +fi diff --git a/plugins/getplugs b/plugins/getplugs index e144be3..42d5400 100755 --- a/plugins/getplugs +++ b/plugins/getplugs @@ -8,15 +8,27 @@ CONFIG_DIR=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/ PLUGIN_DIR=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins +is_cmd_exists () { + which "$1" > /dev/null 2>&1 + echo $? +} + +if [ "$(is_cmd_exists sudo)" == "0" ]; then + sucmd=sudo +elif [ "$(is_cmd_exists doas)" == "0" ]; then + sucmd=doas +else + sucmd=: # noop +fi + # backup any earlier plugins if [ -d $PLUGIN_DIR ]; then - tar -C $CONFIG_DIR -cf $CONFIG_DIR"plugins-$(date '+%Y%m%d%H%M').tar.bz2" plugins/ + tar -C $CONFIG_DIR -czf $CONFIG_DIR"plugins-$(date '+%Y%m%d%H%M').tar.gz" plugins/ fi -mkdir -p $PLUGIN_DIR -cd $PLUGIN_DIR +cd $CONFIG_DIR curl -Ls -O https://github.com/jarun/nnn/archive/master.tar.gz -tar -xf master.tar.gz -cp -vf nnn-master/plugins/* . -sudo mv -vf nnn-master/misc/nlaunch/nlaunch /usr/local/bin/ +tar -zxf master.tar.gz +cp -vRf nnn-master/plugins . +$sucmd mv -vf nnn-master/misc/nlaunch/nlaunch /usr/local/bin/ rm -rf nnn-master/ master.tar.gz README.md |