Feature idea: Pushd and popd #1603
Replies: 3 comments 5 replies
-
pushd and popd are indeed very useful on shell. But I'm not sure if they make in sense for Also we offer going back to the previous dir with - as well (but it's only for "1 level"). |
Beta Was this translation helpful? Give feedback.
-
Sorry, no plans. |
Beta Was this translation helpful? Give feedback.
-
Forgot to post this, but I did play around with the idea a bit. Didn't like it. Ideally you'd want to show the stack to the user, but I don't know how to do that without adding a lot of visual clutter to the UI. Here's the patch if you want to play with it yourself. From b613e9fdcb092035e824a26c2429a34d45d38771 Mon Sep 17 00:00:00 2001
From: NRK <nrk@disroot.org>
Date: Fri, 3 Mar 2023 02:10:53 +0000
Subject: [PATCH] add some basic stack push/pop
ref: https://github.com/jarun/nnn/discussions/1603
---
src/nnn.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/nnn.h | 5 +++++
2 files changed, 63 insertions(+)
diff --git a/src/nnn.c b/src/nnn.c
index 5c7e136f..02c97d7b 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -409,6 +409,10 @@ typedef struct {
char c_fltr[REGEX_MAX]; /* Current filter */
settings c_cfg; /* Current configuration */
uint_t color; /* Color code for directories */
+ struct stack {
+ char *buf;
+ size_t cnt, cap;
+ } stack;
} context;
#ifndef NOSSN
@@ -6879,6 +6883,48 @@ static void showselsize(const char *path)
printmsg(coolsize(cfg.blkorder ? sz << blk_shift : sz));
}
+static void stack_push(void)
+{
+ context *ctx = g_ctx + cfg.curctx;
+ char *cwd = ctx->c_path;
+ size_t avail = ctx->stack.cap - ctx->stack.cnt;
+ size_t cwdlen = xstrlen(cwd) + 1;
+ if (avail < cwdlen) {
+ size_t newcap = ctx->stack.cap + (PATH_MAX * 2);
+ char *tmp = realloc(ctx->stack.buf, newcap);
+ if (!tmp) {
+ printwarn(NULL);
+ return;
+ }
+ ctx->stack.cap = newcap;
+ ctx->stack.buf = tmp;
+ }
+ char *target = ctx->stack.buf + ctx->stack.cnt;
+ memcpy(target, cwd, cwdlen);
+ ctx->stack.cnt += cwdlen;
+ printwait(target, NULL);
+}
+
+static bool stack_pop(char out[static PATH_MAX])
+{
+ context *ctx = g_ctx + cfg.curctx;
+ if (ctx->stack.cnt == 0) {
+ return false;
+ }
+ size_t len;
+ char *pop = xmemrchr((uchar_t *)ctx->stack.buf, '\0', ctx->stack.cnt - 1);
+ if (!pop) {
+ pop = ctx->stack.buf;
+ len = ctx->stack.cnt;
+ } else {
+ ++pop;
+ len = ((ctx->stack.buf + ctx->stack.cnt) - pop) + 1;
+ }
+ memcpy(out, pop, len);
+ ctx->stack.cnt -= len;
+ return true;
+}
+
static bool browse(char *ipath, int pkey)
{
alignas(max_align_t) char newpath[PATH_MAX];
@@ -8219,6 +8265,18 @@ nochange:
}
return EXIT_FAILURE;
+ case SEL_STACK_PUSH:
+ stack_push();
+ goto nochange;
+ case SEL_STACK_POP:
+ if (!stack_pop(newpath))
+ goto nochange;
+ if (chdir(newpath) == -1) {
+ printwarn(&presel);
+ goto nochange;
+ }
+ cdprep(lastdir, lastname, path, newpath) ? (presel = FILTER) : (watch = TRUE);
+ goto begin;
default:
if (xlines != LINES || xcols != COLS)
continue;
diff --git a/src/nnn.h b/src/nnn.h
index 3bf6b8f1..2f9cf92d 100644
--- a/src/nnn.h
+++ b/src/nnn.h
@@ -119,6 +119,8 @@ enum action {
SEL_QUITCD,
SEL_QUIT,
SEL_QUITERR,
+ SEL_STACK_PUSH,
+ SEL_STACK_POP,
#ifndef NOMOUSE
SEL_CLICK,
#endif
@@ -287,6 +289,9 @@ static struct key bindings[] = {
{ CONTROL('Q'), SEL_QUIT },
/* Quit with an error code */
{ 'Q', SEL_QUITERR },
+ /* stack */
+ { '<', SEL_STACK_PUSH },
+ { 'M', SEL_STACK_POP },
#ifndef NOMOUSE
{ KEY_MOUSE, SEL_CLICK },
#endif
--
2.46.2 |
Beta Was this translation helpful? Give feedback.
-
Hello, it says "feel free to discuss feature ideas", so I'll try to do that.
https://en.wikipedia.org/wiki/Pushd_and_popd are often claimed to be immensely useful and time-saving power features of bash (and others) because they allow users to quickly jump between frequently used directories, easily navigate between multiple directories, and reduce the risk of making mistakes while typing long paths.
Going back to where you're from is one of the most often performed filesystem movements. You're working in one directory, but some task requires you to go somewhere else. You need to get back to your working directory when you're done, etc. Once you get used to thinking in terms of the location stack, you push and pop more than you walk up and down. Maintaining such a location stack might be a great feature in nnn. There just need to be two more commands: one to push the current location on the stack, and the other to go back to the last pushed location.
Beta Was this translation helpful? Give feedback.
All reactions