From 04f995e80615a3ac80431367026581bf628ce4a3 Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Sun, 29 Sep 2024 17:10:59 +0530 Subject: [PATCH] Add support for 16 prompt commands history --- src/nnn.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/nnn.c b/src/nnn.c index 0413249d..dcef995b 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -284,6 +284,10 @@ #define VFS_USED 1 #define VFS_SIZE 2 +/* Command history */ +#define MAX_HISTORY 0x10 +#define INVALID_POS 0xFF + /* TYPE DEFINITIONS */ typedef unsigned int uint_t; typedef unsigned char uchar_t; @@ -439,6 +443,8 @@ static ushort_t xlines, xcols; static ushort_t idle; static uchar_t maxbm, maxplug, maxorder; static uchar_t cfgsort[CTX_MAX + 1]; +static uchar_t cmdpos = 0, lastcmdpos = -1; +static char *cmd_hist[MAX_HISTORY] = {0}; static char *bmstr; static char *pluginstr; static char *orderstr; @@ -462,7 +468,6 @@ static char hostname[_POSIX_HOST_NAME_MAX + 1]; #ifndef NOFIFO static char *fifopath; #endif -static char *lastcmd; static ullong_t *ihashbmp; static struct entry *pdents; static blkcnt_t dir_blocks; @@ -3582,6 +3587,43 @@ static int filterentries(char *path, char *lastname) return *ch; } +static char *getcmdfromhist(bool up) +{ + uchar_t pos = cmdpos; + + if (lastcmdpos > 0) { + if (up) + cmdpos = (cmdpos == 0) ? lastcmdpos : (cmdpos - 1); + else + cmdpos = (cmdpos == lastcmdpos) ? 0 : (cmdpos + 1); + } + + return cmd_hist[pos]; +} + +static void addcmdtohist(char *cmd) +{ + bool add = FALSE; + + if (lastcmdpos == INVALID_POS) + add = TRUE; + else if (xstrcmp(cmd_hist[cmdpos], cmd)) { + if (lastcmdpos == (MAX_HISTORY - 1)) { + free(cmd_hist[0]); + for (uchar_t pos = 0; pos < lastcmdpos; ++pos) + cmd_hist[pos] = cmd_hist[pos + 1]; + --lastcmdpos; + } + + add = TRUE; + } + + if (add) { + cmd_hist[++lastcmdpos] = xstrdup(cmd); + cmdpos = lastcmdpos; + } +} + /* Show a prompt with input string and return the changes */ static char *xreadline(const char *prefill, const char *prompt) { @@ -3750,10 +3792,14 @@ static char *xreadline(const char *prefill, const char *prompt) break; case KEY_UP: // fallthrough case KEY_DOWN: - if (prompt && lastcmd && (xstrcmp(prompt, PROMPT) == 0)) { + { + char *cmd = getcmdfromhist(*ch == KEY_UP); + + if (prompt && cmd && (xstrcmp(prompt, PROMPT) == 0)) { printmsg(prompt); - len = pos = mbstowcs(buf, lastcmd, READLINE_MAX); // fallthrough + len = pos = mbstowcs(buf, cmd, READLINE_MAX); // fallthrough } + } default: break; } @@ -5551,11 +5597,13 @@ static bool prompt_run(void) cmdline = getreadline("\n"PROMPT); #endif // Check for an empty command - if (!cmdline || !cmdline[0]) + if (!cmdline || !cmdline[0]) { + if (lastcmdpos != INVALID_POS) + cmdpos = lastcmdpos; break; + } - free(lastcmd); - lastcmd = xstrdup(cmdline); + addcmdtohist(cmdline); ret = TRUE; len = xstrlen(cmdline); @@ -8559,7 +8607,9 @@ static void cleanup(void) free(ihashbmp); free(bookmark); free(plug); - free(lastcmd); + if (lastcmdpos != INVALID_POS) + for (uchar_t pos = 0; pos <= lastcmdpos; ++pos) + free(cmd_hist[pos]); #ifndef NOFIFO if (g_state.autofifo) unlink(fifopath);