diff --git a/Makefile b/Makefile index c07e9501..bb450f91 100644 --- 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 diff --git a/Makefile.generic b/Makefile.generic index f96cecfc..075ba0ce 100644 --- a/Makefile.generic +++ b/Makefile.generic @@ -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 diff --git a/README.md b/README.md index f471d0fd..5c1edf9d 100644 --- 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 75137051..85bbdf51 100644 --- a/nnn.c +++ b/nnn.c @@ -1,26 +1,28 @@ /* See LICENSE file for copyright and license details. */ +#include #include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include -#include #include -#include -#include +#include #define __USE_XOPEN_EXTENDED #include @@ -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) {