Makefile | 5 +++-- Makefile.generic | 5 +++-- README.md | 2 +- nnn.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++----- diff --git a/Makefile b/Makefile index c07e9501cf2569407a300a855d57ee918b954482..bb450f910234a2ca3b19a9df21b6b604ae03d506 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 f96cecfc5191c9c78ee42994b606e0b14e1e6524..075ba0ceabdf2e5ebf6fb597617426d2f343b39f 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 f471d0fdb62fcd3136811d931688da0a69ae7d5b..5c1edf9db0d96bb9a23970b29902aa3e99542594 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ ``` ### 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 --- 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 @@ -117,6 +119,13 @@ off_t bsize; } *pEntry; 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; @@ -373,6 +382,28 @@ if (!*s1 && !*s2) return 1; 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 * @@ -1420,14 +1451,39 @@ case SEL_END: 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 @@ else 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 @@ xstrlcpy(path, newpath, sizeof(path)); /* 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) {