]> Sergey Matveev's repositories - nnn.git/commitdiff
Use readline() at chdir prompt
authorArun Prakash Jana <engineerarun@gmail.com>
Thu, 20 Apr 2017 14:15:52 +0000 (19:45 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Thu, 20 Apr 2017 14:40:58 +0000 (20:10 +0530)
With the features the readline library provides it would be too naive to ignore.
We break out of the curses mode into the prompt and get back in.
This change introduces dependency on libncurses.

Makefile
Makefile.generic
README.md
nnn.c

index c07e9501cf2569407a300a855d57ee918b954482..bb450f910234a2ca3b19a9df21b6b604ae03d506 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,10 +4,11 @@ PREFIX = /usr/local
 MANPREFIX = $(PREFIX)/share/man
 
 CFLAGS += -O3 -march=native -Wall -Wextra -Wno-unused-parameter
+LDLIBS = -lreadline
 ifeq ($(shell uname), Darwin)
-  LDLIBS = -lncurses
+  LDLIBS += -lncurses
 else
-  LDLIBS = -lncursesw
+  LDLIBS += -lncursesw
 endif
 
 DISTFILES = nnn.c config.def.h nnn.1 Makefile README.md LICENSE
index f96cecfc5191c9c78ee42994b606e0b14e1e6524..075ba0ceabdf2e5ebf6fb597617426d2f343b39f 100644 (file)
@@ -4,10 +4,11 @@ PREFIX = /usr/local
 MANPREFIX = $(PREFIX)/share/man
 
 CFLAGS += -O2 -Wall -Wextra -Wno-unused-parameter
+LDLIBS = -lreadline
 ifeq ($(shell uname), Darwin)
-  LDLIBS = -lncurses
+  LDLIBS += -lncurses
 else
-  LDLIBS = -lncursesw
+  LDLIBS += -lncursesw
 endif
 
 DISTFILES = nnn.c config.def.h nnn.1 Makefile README.md LICENSE
index f471d0fdb62fcd3136811d931688da0a69ae7d5b..5c1edf9db0d96bb9a23970b29902aa3e99542594 100644 (file)
--- a/README.md
+++ b/README.md
@@ -141,7 +141,7 @@ nnn vs. ranger memory usage while viewing a directory with 10,178 files, sorted
 
 ### Installation
 
-nnn needs libncursesw on Linux (or ncurses on OS X) and standard libc.
+nnn needs libreadline and libncursesw (on Linux or ncurses on OS X) and standard libc.
 
 - If you are using **Homebrew**, run:
 
diff --git a/nnn.c b/nnn.c
index 7513705184a0a8d8eb4756e9110d0bf89d32e89f..85bbdf515abc24a484fd08c121926e1abcdafc8b 100644 (file)
--- a/nnn.c
+++ b/nnn.c
@@ -1,26 +1,28 @@
 /* See LICENSE file for copyright and license details. */
+#include <readline/readline.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/statvfs.h>
 #include <sys/resource.h>
 
+#include <ctype.h>
 #include <curses.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
 #include <limits.h>
 #include <locale.h>
+#include <pwd.h>
 #include <regex.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <time.h>
-#include <pwd.h>
-#include <grp.h>
+#include <unistd.h>
 
 #define __USE_XOPEN_EXTENDED
 #include <ftw.h>
@@ -118,6 +120,13 @@ typedef struct entry {
 
 typedef unsigned long ulong;
 
+/* Externs */
+#ifdef __APPLE__
+extern int add_history(const char *);
+#else
+extern void add_history(const char *string);
+#endif
+
 /* Global context */
 static struct entry *dents;
 static int ndents, cur;
@@ -375,6 +384,28 @@ xstricmp(const char *s1, const char *s2)
        return (int) (TOUPPER(*s1) - TOUPPER(*s2));
 }
 
+static char *
+strstrip(char *s)
+{
+       size_t size;
+       char *end;
+
+       size = strlen(s);
+
+       if (!size)
+               return s;
+
+       end = s + size - 1;
+       while (end >= s && isspace(*end))
+               end--;
+       *(end + 1) = '\0';
+
+       while (*s && isspace(*s))
+               s++;
+
+       return s;
+}
+
 static char *
 openwith(char *file)
 {
@@ -1420,14 +1451,39 @@ nochange:
                        cur = ndents - 1;
                        break;
                case SEL_CD:
+               {
                        /* Read target dir */
-                       printprompt("chdir: ");
-                       tmp = readln();
+                       char cwd[PATH_MAX];
+                       tmp = getcwd(cwd, PATH_MAX);
                        if (tmp == NULL) {
-                               clearprompt();
+                               printwarn();
+                               goto nochange;
+                       }
+
+                       if (chdir(path) == -1) {
+                               printwarn();
                                goto nochange;
                        }
 
+                       exitcurses();
+                       char *tmp = readline("chdir: ");
+                       initcurses();
+                       tmp = tmp[0] ? tmp : NULL;
+                       if (chdir(cwd) == -1)
+                               printwarn();
+
+                       if (tmp == NULL) {
+                               /* Save current */
+                               if (ndents > 0)
+                                       mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
+
+                               goto begin;
+                       } else
+                               add_history(tmp);
+
+                       char *input = tmp;
+                       tmp = strstrip(tmp);
+
                        if (tmp[0] == '~') {
                                char *home = getenv("HOME");
                                if (home)
@@ -1441,8 +1497,13 @@ nochange:
                                mkpath(path, tmp, newpath, sizeof(newpath));
 
                        if (canopendir(newpath) == 0) {
+                               /* Save current */
+                               if (ndents > 0)
+                                       mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
+
                                printwarn();
-                               goto nochange;
+                               free(input);
+                               goto begin;
                        }
 
                        /* Save last working directory */
@@ -1452,7 +1513,10 @@ nochange:
                        /* Reset filter */
                        xstrlcpy(fltr, ifilter, sizeof(fltr));
                        DPRINTF_S(path);
+                       oldpath[0] = '\0';
+                       free(input);
                        goto begin;
+               }
                case SEL_CDHOME:
                        tmp = getenv("HOME");
                        if (tmp == NULL) {