aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Anna Arad <4895022+annagrram@users.noreply.github.com>2019-10-23 13:04:12 +0300
committerGravatar Mischievous Meerkat <engineerarun@gmail.com>2019-10-23 15:34:12 +0530
commit9afd7cf3bf8badb7e704fb1e1fbdb8031572c722 (patch)
tree90669833f994bfcff8b8f9edc0b044f2ea2f2e89 /plugins
parent0144f440609b4fb7dcdf9e3325e6d1de3e6085bf (diff)
downloadnnn-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-helper33
-rw-r--r--plugins/README.md65
-rwxr-xr-xplugins/fzcd32
-rwxr-xr-xplugins/getplugs24
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