From e787ae4501f53e0dddbfeed00c1d3bb8ade21cda Mon Sep 17 00:00:00 2001 From: NRK Date: Sat, 4 Jan 2025 14:19:28 +0000 Subject: [PATCH 1/2] add support for custom trash command this makes it so that if $NNN_TRASH is set to a string other than "1" or "2" then it is accepted as the trash command to run. this allows us to support arbritary trashing utilities while also maintaining backwards compatibility for older "1" & "2" values. Fixes: https://github.com/jarun/nnn/issues/1168 Fixes: https://github.com/jarun/nnn/discussions/1963 Fixes: https://github.com/jarun/nnn/discussions/1960 Fixes: https://github.com/jarun/nnn/discussions/1761 --- nnn.1 | 10 ++++++++-- plugins/.nmv | 4 +++- src/nnn.c | 38 +++++++++++++++----------------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/nnn.1 b/nnn.1 index e7422895..a52db91f 100644 --- a/nnn.1 +++ b/nnn.1 @@ -564,8 +564,14 @@ separated by \fI;\fR: .Pp \fBNNN_TRASH:\fR trash (instead of \fIrm -rf\fR) files to desktop Trash. .Bd -literal - export NNN_TRASH=n - # n=1: trash-cli, n=2: gio trash + export NNN_TRASH=cmd + + NOTES: + 1. \fBcmd\fR is the name/path of the binary that nnn will call for + trashing files. E.g to use macOS's native `trash' command: + export NNN_TRASH="trash" + 2. Special value "1" and "2" for cmd will use trash-cli and + gio trash respectively. .Ed .Pp \fBNNN_SEL:\fR absolute path to custom selection file. diff --git a/plugins/.nmv b/plugins/.nmv index 67abe166..ffa2021d 100755 --- a/plugins/.nmv +++ b/plugins/.nmv @@ -31,8 +31,10 @@ case "$NNN_TRASH" in RM_UTIL="trash-put" ;; 2) RM_UTIL="gio trash" ;; - *) + "") RM_UTIL="rm -ri --" ;; + *) + RM_UTIL="$NNN_TRASH" ;; esac exit_status=0 diff --git a/src/nnn.c b/src/nnn.c index bffc8f0d..9a78fb55 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -392,12 +392,11 @@ typedef struct { uint_t selbm : 1; /* Select a bookmark from bookmarks directory */ uint_t selmode : 1; /* Set when selecting files */ uint_t stayonsel : 1; /* Disable auto-advance on selection */ - uint_t trash : 2; /* Trash method 0: rm -rf, 1: trash-cli, 2: gio trash */ uint_t uidgid : 1; /* Show owner and group info */ uint_t usebsdtar : 1; /* Use bsdtar as default archive utility */ uint_t xprompt : 1; /* Use native prompt instead of readline prompt */ uint_t showlines : 1; /* Show line numbers */ - uint_t reserved : 3; /* Adjust when adding/removing a field */ + uint_t reserved : 5; /* Adjust when adding/removing a field */ } runstate; /* Contexts or workspaces */ @@ -462,6 +461,7 @@ static char *listroot; static char *plgpath; static char *pnamebuf, *pselbuf, *findselpos; static char *mark; +static char *trashcmd; #ifndef NOX11 static char hostname[_POSIX_HOST_NAME_MAX + 1]; #endif @@ -709,8 +709,8 @@ static const char * const messages[] = { #define NNN_SEL 9 #define NNN_ARCHIVE 10 #define NNN_ORDER 11 -#define NNN_HELP 12 /* strings end here */ -#define NNN_TRASH 13 /* flags begin here */ +#define NNN_HELP 12 +#define NNN_TRASH 13 static const char * const env_cfg[] = { "NNN_OPTS", @@ -2527,17 +2527,6 @@ static char *xgetenv(const char * const name, char *fallback) return value && value[0] ? value : fallback; } -/* Checks if an env variable is set to 1 */ -static inline uint_t xgetenv_val(const char *name) -{ - char *str = getenv(name); - - if (str && str[0]) - return atoi(str); - - return 0; -} - /* Check if a dir exists, IS a dir, and is readable */ static bool xdiraccess(const char *path) { @@ -2579,7 +2568,7 @@ static bool rmmulstr(char *buf, bool use_trash) r, selpath); else snprintf(buf, CMD_LEN_MAX, "xargs -0 %s < %s", - utils[(g_state.trash == 1) ? UTIL_TRASH_CLI : UTIL_GIO_TRASH], selpath); + trashcmd, selpath); return TRUE; } @@ -2597,8 +2586,7 @@ static bool xrm(char * const fpath, bool use_trash) rm_opts[3] = r; spawn("rm", rm_opts, "--", fpath, F_NORMAL | F_CHKRTN); } else - spawn(utils[(g_state.trash == 1) ? UTIL_TRASH_CLI : UTIL_GIO_TRASH], - fpath, NULL, NULL, F_NORMAL | F_MULTI); + spawn(trashcmd, fpath, NULL, NULL, F_NORMAL | F_MULTI); return (access(fpath, F_OK) == -1); /* File is removed */ } @@ -2723,7 +2711,7 @@ static bool cpmvrm_selection(enum action sel, char *path) } break; default: /* SEL_TRASH, SEL_RM_ONLY */ - if (!rmmulstr(g_buf, g_state.trash && sel == SEL_TRASH)) { + if (!rmmulstr(g_buf, trashcmd && sel == SEL_TRASH)) { printmsg(messages[MSG_CANCEL]); return FALSE; } @@ -7757,7 +7745,7 @@ nochange: tmp = (listpath && xstrcmp(path, listpath) == 0) ? listroot : path; mkpath(tmp, pdents[cur].name, newpath); - if (!xrm(newpath, g_state.trash && sel == SEL_TRASH)) + if (!xrm(newpath, trashcmd && sel == SEL_TRASH)) continue; xrmfromsel(tmp, newpath); @@ -9045,9 +9033,13 @@ int main(int argc, char *argv[]) #endif /* Configure trash preference */ - opt = xgetenv_val(env_cfg[NNN_TRASH]); - if (opt && opt <= 2) - g_state.trash = opt; + trashcmd = getenv(env_cfg[NNN_TRASH]); + if (trashcmd) { + if (strcmp(trashcmd, "1") == 0) + trashcmd = utils[UTIL_TRASH_CLI]; + else if (strcmp(trashcmd, "2") == 0) + trashcmd = utils[UTIL_GIO_TRASH]; + } /* Ignore/handle certain signals */ struct sigaction act = {.sa_handler = sigint_handler}; From d07dde54ae6fc285af2ee17383632ebdb85bcb46 Mon Sep 17 00:00:00 2001 From: NRK Date: Sat, 4 Jan 2025 16:12:22 +0000 Subject: [PATCH 2/2] fix patch --- patches/restorepreview/mainline.diff | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/patches/restorepreview/mainline.diff b/patches/restorepreview/mainline.diff index a1d6b791..b1515258 100644 --- a/patches/restorepreview/mainline.diff +++ b/patches/restorepreview/mainline.diff @@ -7,20 +7,20 @@ # Authors: Luuk van Baal diff --git a/src/nnn.c b/src/nnn.c -index 0388b23c..66d3316a 100644 +index 9a78fb55..ca4ac0f7 100644 --- a/src/nnn.c +++ b/src/nnn.c -@@ -391,7 +391,8 @@ typedef struct { +@@ -396,7 +396,8 @@ typedef struct { uint_t usebsdtar : 1; /* Use bsdtar as default archive utility */ uint_t xprompt : 1; /* Use native prompt instead of readline prompt */ uint_t showlines : 1; /* Show line numbers */ -- uint_t reserved : 3; /* Adjust when adding/removing a field */ +- uint_t reserved : 5; /* Adjust when adding/removing a field */ + uint_t previewer : 1; /* Run state of previewer */ -+ uint_t reserved : 2; /* Adjust when adding/removing a field */ ++ uint_t reserved : 4; /* Adjust when adding/removing a field */ } runstate; /* Contexts or workspaces */ -@@ -516,6 +517,9 @@ alignas(max_align_t) static char g_tmpfpath[TMP_LEN_MAX]; +@@ -527,6 +528,9 @@ alignas(max_align_t) static char g_tmpfpath[TMP_LEN_MAX]; /* Buffer to store plugins control pipe location */ alignas(max_align_t) static char g_pipepath[TMP_LEN_MAX]; @@ -30,7 +30,7 @@ index 0388b23c..66d3316a 100644 /* Non-persistent runtime states */ static runstate g_state; -@@ -696,12 +700,13 @@ static const char * const messages[] = { +@@ -705,12 +709,13 @@ static const char * const messages[] = { #define NNN_FCOLORS 5 #define NNNLVL 6 #define NNN_PIPE 7 @@ -38,19 +38,19 @@ index 0388b23c..66d3316a 100644 -#define NNN_SEL 9 -#define NNN_ARCHIVE 10 -#define NNN_ORDER 11 --#define NNN_HELP 12 /* strings end here */ --#define NNN_TRASH 13 /* flags begin here */ +-#define NNN_HELP 12 +-#define NNN_TRASH 13 +#define NNN_PPIPE 8 +#define NNN_MCLICK 9 +#define NNN_SEL 10 +#define NNN_ARCHIVE 11 +#define NNN_ORDER 12 -+#define NNN_HELP 13 /* strings end here */ -+#define NNN_TRASH 14 /* flags begin here */ ++#define NNN_HELP 13 ++#define NNN_TRASH 14 static const char * const env_cfg[] = { "NNN_OPTS", -@@ -712,6 +717,7 @@ static const char * const env_cfg[] = { +@@ -721,6 +726,7 @@ static const char * const env_cfg[] = { "NNN_FCOLORS", "NNNLVL", "NNN_PIPE", @@ -58,7 +58,7 @@ index 0388b23c..66d3316a 100644 "NNN_MCLICK", "NNN_SEL", "NNN_ARCHIVE", -@@ -850,7 +856,7 @@ static int set_sort_flags(int r); +@@ -859,7 +865,7 @@ static int set_sort_flags(int r); static void statusbar(char *path); static bool get_output(char *file, char *arg1, char *arg2, int fdout, bool page); #ifndef NOFIFO @@ -67,7 +67,7 @@ index 0388b23c..66d3316a 100644 #endif /* Functions */ -@@ -3140,7 +3146,7 @@ try_quit: +@@ -3166,7 +3172,7 @@ try_quit: } else { #ifndef NOFIFO if (!g_state.fifomode) @@ -76,7 +76,7 @@ index 0388b23c..66d3316a 100644 #endif escaped = TRUE; settimeout(); -@@ -5258,15 +5264,20 @@ static void run_cmd_as_plugin(const char *file, uchar_t flags) +@@ -5372,15 +5378,20 @@ static void run_cmd_as_plugin(const char *file, uchar_t flags) static bool plctrl_init(void) { @@ -101,7 +101,7 @@ index 0388b23c..66d3316a 100644 return EXIT_SUCCESS; } -@@ -5295,6 +5306,21 @@ static ssize_t read_nointr(int fd, void *buf, size_t count) +@@ -5409,6 +5420,21 @@ static ssize_t read_nointr(int fd, void *buf, size_t count) return len; } @@ -123,7 +123,7 @@ index 0388b23c..66d3316a 100644 static char *readpipe(int fd, char *ctxnum, char **path) { char ctx, *nextpath = NULL; -@@ -5979,7 +6005,7 @@ static void populate(char *path, char *lastname) +@@ -6097,7 +6123,7 @@ static void populate(char *path, char *lastname) } #ifndef NOFIFO @@ -132,7 +132,7 @@ index 0388b23c..66d3316a 100644 { if (!fifopath) return; -@@ -5995,6 +6021,12 @@ static void notify_fifo(bool force) +@@ -6113,6 +6139,12 @@ static void notify_fifo(bool force) } } @@ -145,7 +145,7 @@ index 0388b23c..66d3316a 100644 static struct entry lastentry; if (!force && !memcmp(&lastentry, &pdents[cur], sizeof(struct entry))) // NOLINT -@@ -6027,7 +6059,7 @@ static void send_to_explorer(int *presel) +@@ -6145,7 +6177,7 @@ static void send_to_explorer(int *presel) if (fd > 1) close(fd); } else @@ -154,7 +154,7 @@ index 0388b23c..66d3316a 100644 } #endif -@@ -6060,7 +6092,7 @@ static void move_cursor(int target, int ignore_scrolloff) +@@ -6178,7 +6210,7 @@ static void move_cursor(int target, int ignore_scrolloff) #ifndef NOFIFO if (!g_state.fifomode) @@ -163,7 +163,7 @@ index 0388b23c..66d3316a 100644 #endif } -@@ -6733,7 +6765,7 @@ static bool browse(char *ipath, const char *session, int pkey) +@@ -6851,7 +6883,7 @@ static bool browse(char *ipath, int pkey) pEntry pent; enum action sel; struct stat sb; @@ -172,7 +172,7 @@ index 0388b23c..66d3316a 100644 const uchar_t opener_flags = (cfg.cliopener ? F_CLI : (F_NOTRACE | F_NOSTDIN | F_NOWAIT)); bool watch = FALSE, cd = TRUE; ino_t inode = 0; -@@ -6991,7 +7023,7 @@ nochange: +@@ -7110,7 +7142,7 @@ nochange: move_cursor(r, 1); #ifndef NOFIFO else if ((event.bstate == BUTTON1_PRESSED) && !g_state.fifomode) @@ -181,7 +181,7 @@ index 0388b23c..66d3316a 100644 #endif /* Handle right click selection */ if (event.bstate == BUTTON3_PRESSED) { -@@ -7153,7 +7185,14 @@ nochange: +@@ -7272,7 +7304,14 @@ nochange: && strstr(g_buf, "text") #endif ) { @@ -196,7 +196,7 @@ index 0388b23c..66d3316a 100644 if (cfg.filtermode) { presel = FILTER; clearfilter(); -@@ -7471,8 +7510,14 @@ nochange: +@@ -7597,8 +7636,14 @@ nochange: copycurname(); goto nochange; case SEL_EDIT: @@ -211,7 +211,7 @@ index 0388b23c..66d3316a 100644 continue; default: /* SEL_LOCK */ lock_terminal(); -@@ -7860,6 +7905,7 @@ nochange: +@@ -7987,6 +8032,7 @@ nochange: cd = FALSE; goto begin; } @@ -219,7 +219,7 @@ index 0388b23c..66d3316a 100644 case SEL_PLUGIN: /* Check if directory is accessible */ if (!xdiraccess(plgpath)) { -@@ -7885,6 +7931,12 @@ nochange: +@@ -8012,6 +8058,12 @@ nochange: goto nochange; } @@ -232,7 +232,7 @@ index 0388b23c..66d3316a 100644 if (tmp[0] == '-' && tmp[1]) { ++tmp; r = FALSE; /* Do not refresh dir after completion */ -@@ -7943,7 +7995,13 @@ nochange: +@@ -8070,7 +8122,13 @@ nochange: case SEL_SHELL: // fallthrough case SEL_LAUNCH: // fallthrough case SEL_PROMPT: @@ -246,7 +246,7 @@ index 0388b23c..66d3316a 100644 /* Continue in type-to-nav mode, if enabled */ if (cfg.filtermode) -@@ -8492,8 +8550,10 @@ static void cleanup(void) +@@ -8623,8 +8681,10 @@ static void cleanup(void) if (g_state.autofifo) unlink(fifopath); #endif @@ -258,7 +258,7 @@ index 0388b23c..66d3316a 100644 #ifdef DEBUG disabledbg(); #endif -@@ -9020,7 +9080,7 @@ int main(int argc, char *argv[]) +@@ -9169,7 +9229,7 @@ int main(int argc, char *argv[]) #ifndef NOFIFO if (!g_state.fifomode)