aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--misc/auto-completion/bash/nnn-completion.bash1
-rw-r--r--misc/auto-completion/fish/nnn.fish1
-rw-r--r--misc/auto-completion/zsh/_nnn1
-rwxr-xr-xmisc/clipboard-copier/copier23
-rw-r--r--nnn.18
-rwxr-xr-xplugins/.cbcp45
-rwxr-xr-xplugins/.ntfy (renamed from plugins/.notify)0
-rw-r--r--src/nnn.c55
9 files changed, 89 insertions, 48 deletions
diff --git a/README.md b/README.md
index 34ba51d..e5bc4c4 100644
--- a/README.md
+++ b/README.md
@@ -62,6 +62,7 @@ Add to that an awesome [Wiki](https://github.com/jarun/nnn/wiki)!
- Batch renamer (feature-limited) for selection or dir
- Copy (as), move (as), delete, archive, link selection
- Notification on cp, mv, rm completion
+ - Copy file paths to system clipboard on select
- Create (with parents), rename, duplicate (anywhere) files and dirs
- Launch GUI apps, run commands, execute file, spawn a shell
- Hovered file set as `$nnn` at prompt and spawned shell
@@ -162,7 +163,6 @@ There is no config file. Associated files are stored under `${XDG_CONFIG_HOME:-$
| `NNN_SSHFS_OPTS='sshfs -o reconnect,idmap=user'` | specify SSHFS options |
| `NNN_RCLONE_OPTS='rclone mount --read-only'` | specify rclone options |
| `NNN_IDLE_TIMEOUT=300` | idle seconds to lock terminal [default: disabled] |
-| `NNN_COPIER=copier` | clipboard copier script [default: none] |
| `NNN_TRASH=1` | trash files to the desktop Trash [default: delete] |
#### Cmdline options
@@ -195,6 +195,7 @@ optional args:
-S du mode
-t disable dir auto-select
-v show version
+ -x notis, sel to system clipboard
-h show help
```
diff --git a/misc/auto-completion/bash/nnn-completion.bash b/misc/auto-completion/bash/nnn-completion.bash
index bddf84f..00e34d5 100644
--- a/misc/auto-completion/bash/nnn-completion.bash
+++ b/misc/auto-completion/bash/nnn-completion.bash
@@ -31,6 +31,7 @@ _nnn ()
-S
-t
-v
+ -x
-h
)
if [[ $prev == -b ]]; then
diff --git a/misc/auto-completion/fish/nnn.fish b/misc/auto-completion/fish/nnn.fish
index 3613343..c1f2fac 100644
--- a/misc/auto-completion/fish/nnn.fish
+++ b/misc/auto-completion/fish/nnn.fish
@@ -30,4 +30,5 @@ complete -c nnn -s s -d 'use substring match for filters'
complete -c nnn -s S -d 'start in disk usage analyzer mode'
complete -c nnn -s t -d 'disable dir auto-select'
complete -c nnn -s v -d 'show program version and exit'
+complete -c nnn -s x -d 'notis, sel to system clipboard'
complete -c nnn -s h -d 'show program help'
diff --git a/misc/auto-completion/zsh/_nnn b/misc/auto-completion/zsh/_nnn
index d5d5c1d..34db851 100644
--- a/misc/auto-completion/zsh/_nnn
+++ b/misc/auto-completion/zsh/_nnn
@@ -28,6 +28,7 @@ args=(
'(-S)-S[start in disk usage analyzer mode]'
'(-t)-t[disable dir auto-select]'
'(-v)-v[show program version and exit]'
+ '(-x)-x[notis, sel to system clipboard]'
'(-h)-h[show program help]'
'*:filename:_files'
)
diff --git a/misc/clipboard-copier/copier b/misc/clipboard-copier/copier
deleted file mode 100755
index 6ac3ba6..0000000
--- a/misc/clipboard-copier/copier
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env sh
-
-# Description: Copy selection to clipboard
-#
-# Shell: POSIX compliant
-# Author: Arun Prakash Jana
-
-SELECTION=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection
-
-# Linux
-xargs -0 < "$SELECTION" | xsel -bi
-
-# macOS
-# xargs -0 < "$SELECTION" | pbcopy
-
-# Termux
-# xargs -0 < "$SELECTION" | termux-clipboard-set
-
-# Cygwin
-# xargs -0 < "$SELECTION" | clip
-
-# Wayland
-# xargs -0 < "$SELECTION" | wl-copy
diff --git a/nnn.1 b/nnn.1
index cb0f299..a9fd662 100644
--- a/nnn.1
+++ b/nnn.1
@@ -23,6 +23,7 @@
.Op Ar -s
.Op Ar -S
.Op Ar -v
+.Op Ar -x
.Op Ar -h
.Op Ar PATH
.Sh DESCRIPTION
@@ -100,6 +101,9 @@ supports the following options:
.Fl v
show version and exit
.Pp
+.Fl x
+ show notis on selection cp, mv, rm completion; copy path to system clipboard on select
+.Pp
.Fl h
show program help and exit
.Sh CONFIGURATION
@@ -166,7 +170,7 @@ There are 3 groups of shortcuts to add files to selection:
.Pp
The selection can now be listed, copied, moved, removed, archived or linked.
.Pp
-Absolute paths of the selected files are copied to the temporary file \fB.selection\fR in the config directory. The path is shown in the help and configuration screen. If \fB$NNN_COPIER\fR is set (see ENVIRONMENT section below) the file paths are also copied to the system clipboard.
+Absolute paths of the selected files are copied to the temporary file \fB.selection\fR in the config directory. The path is shown in the help and configuration screen.
.Pp
To flush the selection without running any operation use the _edit, flush selection_ key. The list is flushed even if unchanged. Use this key to remove a file from selection after you navigate away from its directory. Flushing doesn't end the selection mode. You can add more files to the selection and edit/flush the list again. Flushing doesn't end the selection mode. You can add more files to the selection and edit/flush the list again.
.Pp
@@ -239,8 +243,6 @@ when dealing with the !, e and p commands respectively. A single combination to
.Pp
\fBNNN_IDLE_TIMEOUT:\fR set idle timeout (in seconds) to invoke terminal locker (default: disabled).
.Pp
-\fBNNN_COPIER:\fR system clipboard copier script. The project page has some sample copier scripts.
-.Pp
\fBNNN_TRASH:\fR trash (instead of \fIdelete\fR) files to desktop Trash.
.Bd -literal
export NNN_TRASH=1
diff --git a/plugins/.cbcp b/plugins/.cbcp
new file mode 100755
index 0000000..022e88a
--- /dev/null
+++ b/plugins/.cbcp
@@ -0,0 +1,45 @@
+#!/usr/bin/env sh
+
+# Description: Copy selection to system clipboard as newline-separated entries
+# Requires: tr and
+# xclip/xsel (Linux)
+# pbcopy (macOS)
+# termux-clipboard-set (Termux)
+# clip.exe (WSL)
+# clip (Cygwin)
+# wl-copy (Wayland)
+#
+# LIMITATION: breaks if a filename has newline in it
+#
+# Note: For a space-separated list:
+# xargs -0 < "$SELECTION"
+#
+# Shell: POSIX compliant
+# Author: Arun Prakash Jana
+
+IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
+
+SELECTION=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection
+
+if which xsel >/dev/null 2>&1; then
+ # Linux
+ tr '\0' '\n' < "$SELECTION" | xsel -bi
+elif which xclip >/dev/null 2>&1; then
+ # Linux
+ tr '\0' '\n' < "$SELECTION" | xclip -sel clip
+elif which pbcopy >/dev/null 2>&1; then
+ # macOS
+ tr '\0' '\n' < "$SELECTION" | pbcopy
+elif which termux-clipboard-set >/dev/null 2>&1; then
+ # Termux
+ tr '\0' '\n' < "$SELECTION" | termux-clipboard-set
+elif which clip.exe >/dev/null 2>&1; then
+ # WSL
+ tr '\0' '\n' < "$SELECTION" | clip.exe
+elif which clip >/dev/null 2>&1; then
+ # Cygwin
+ tr '\0' '\n' < "$SELECTION" | clip
+elif which wl-copy >/dev/null 2>&1; then
+ # Wayland
+ tr '\0' '\n' < "$SELECTION" | wl-copy
+fi
diff --git a/plugins/.notify b/plugins/.ntfy
index fe0e18a..fe0e18a 100755
--- a/plugins/.notify
+++ b/plugins/.ntfy
diff --git a/src/nnn.c b/src/nnn.c
index 7500d01..c398179 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -227,8 +227,9 @@ typedef struct {
uint selmode : 1; /* Set when selecting files */
uint showdetail : 1; /* Clear to show fewer file info */
uint ctxactive : 1; /* Context active or not */
- uint reserved : 3;
+ uint reserved : 2;
/* The following settings are global */
+ uint x11 : 1; /* Copy to system clipboard and show notis */
uint curctx : 2; /* Current context number */
uint dircolor : 1; /* Current status of dir color */
uint picker : 1; /* Write selection to user-specified file */
@@ -281,6 +282,7 @@ static settings cfg = {
0, /* showdetail */
1, /* ctxactive */
0, /* reserved */
+ 0, /* x11 */
0, /* curctx */
0, /* dircolor */
0, /* picker */
@@ -310,7 +312,6 @@ static uint idletimeout, selbufpos, lastappendpos, selbuflen;
static char *bmstr;
static char *pluginstr;
static char *opener;
-static char *copier;
static char *editor;
static char *enveditor;
static char *pager;
@@ -379,7 +380,8 @@ static bool g_plinit = FALSE;
#define UTIL_SH 14
#define UTIL_FZF 15
#define UTIL_FZY 16
-#define UTIL_NOTIFY 17
+#define UTIL_NTFY 17
+#define UTIL_CBCP 18
/* Utilities to open files, run actions */
static char * const utils[] = {
@@ -412,7 +414,8 @@ static char * const utils[] = {
"sh",
"fzf",
"fzy",
- ".notify",
+ ".ntfy",
+ ".cbcp",
};
/* Common strings */
@@ -507,18 +510,16 @@ static const char * const messages[] = {
#define NNN_OPENER 1
#define NNN_CONTEXT_COLORS 2
#define NNN_IDLE_TIMEOUT 3
-#define NNN_COPIER 4
-#define NNNLVL 5
-#define NNN_PIPE 6 /* strings end here */
-#define NNN_USE_EDITOR 7 /* flags begin here */
-#define NNN_TRASH 8
+#define NNNLVL 4
+#define NNN_PIPE 5 /* strings end here */
+#define NNN_USE_EDITOR 6 /* flags begin here */
+#define NNN_TRASH 7
static const char * const env_cfg[] = {
"NNN_BMS",
"NNN_OPENER",
"NNN_CONTEXT_COLORS",
"NNN_IDLE_TIMEOUT",
- "NNN_COPIER",
"NNNLVL",
"NNN_PIPE",
"NNN_USE_EDITOR",
@@ -597,6 +598,7 @@ static inline bool getutil(char *util);
static size_t mkpath(const char *dir, const char *name, char *out);
static void updateselbuf(const char *path, char *newpath);
static char *xgetenv(const char *name, char *fallback);
+static void run_plugin(const char *plugin, char *newpath, const uchar flags);
/* Functions */
@@ -1040,7 +1042,8 @@ static void endselection(const char *path, char *newpath)
if (selbufpos) { /* File path(s) written to the buffer */
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
- spawn(copier, NULL, NULL, NULL, F_NOTRACE);
+ if (cfg.x11)
+ run_plugin(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
}
}
}
@@ -1127,7 +1130,6 @@ static int editselection(void)
nselected = lines;
writesel(pselbuf, selbufpos - 1);
- spawn(copier, NULL, NULL, NULL, F_NOTRACE);
return 1;
@@ -3631,6 +3633,13 @@ static bool run_selected_plugin(char **path, const char *file, char *newpath, ch
return TRUE;
}
+static void run_plugin(const char *plugin, char *newpath, const uchar flags)
+{
+ mkpath(plugindir, plugin, newpath);
+ if (!access(newpath, X_OK))
+ spawn(newpath, NULL, NULL, NULL, flags);
+}
+
static void launch_app(const char *path, char *newpath)
{
int r = F_NORMAL;
@@ -4854,7 +4863,8 @@ nochange:
selbufpos = lastappendpos;
appendfpath(newpath, mkpath(path, dents[cur].name, newpath));
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
- spawn(copier, NULL, NULL, NULL, F_NOTRACE);
+ if (cfg.x11)
+ run_plugin(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
lastappendpos = selbufpos;
selbufpos = utmp;
}
@@ -4938,7 +4948,8 @@ nochange:
if (selbufpos != utmp) {
writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */
- spawn(copier, NULL, NULL, NULL, F_NOTRACE);
+ if (cfg.x11)
+ run_plugin(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
/* Restore current selection buffer position */
lastappendpos = selbufpos;
selbufpos = utmp;
@@ -4962,7 +4973,8 @@ nochange:
= (!r ? messages[MSG_0_SELECTED] : messages[MSG_FAILED]);
printwait(msg, &presel);
goto nochange;
- }
+ } else if (cfg.x11)
+ run_plugin(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE);
break;
case SEL_CP: // fallthrough
case SEL_MV: // fallthrough
@@ -4975,8 +4987,8 @@ nochange:
goto nochange;
/* Show notification on operation complete */
- mkpath(plugindir, utils[UTIL_NOTIFY], newpath);
- spawn(newpath, NULL, NULL, NULL, F_NOWAIT | F_NOTRACE);
+ if (cfg.x11)
+ run_plugin(utils[UTIL_NTFY], newpath, F_NOWAIT | F_NOTRACE);
if (ndents)
copycurname();
@@ -5479,6 +5491,7 @@ static void usage(void)
" -S du mode\n"
" -t disable dir auto-select\n"
" -v show version\n"
+ " -x notis, sel to system clipboard\n"
" -h show help\n\n"
"v%s\n%s\n", __func__, VERSION, GENERAL_INFO);
}
@@ -5621,7 +5634,7 @@ int main(int argc, char *argv[])
bool progress = FALSE;
#endif
- while ((opt = getopt(argc, argv, "HSKiab:cde:Efnop:rRstvh")) != -1) {
+ while ((opt = getopt(argc, argv, "HSKiab:cde:Efnop:rRstvxh")) != -1) {
switch (opt) {
case 'S':
cfg.blkorder = 1;
@@ -5699,6 +5712,9 @@ int main(int argc, char *argv[])
case 'v':
fprintf(stdout, "%s\n", VERSION);
return _SUCCESS;
+ case 'x':
+ cfg.x11 = 1;
+ break;
case 'h':
usage();
return _SUCCESS;
@@ -5837,9 +5853,6 @@ int main(int argc, char *argv[])
if (!set_tmp_path())
return _FAILURE;
- /* Get the clipboard copier, if set */
- copier = getenv(env_cfg[NNN_COPIER]);
-
#ifdef __linux__
if (!progress) {
cp[5] = cp[4];