diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | Makefile.generic | 5 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | nnn.c | 78 |
4 files changed, 78 insertions, 12 deletions
@@ -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 f96cecf..075ba0c 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 @@ -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: @@ -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; @@ -376,6 +385,28 @@ xstricmp(const char *s1, const char *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) { regex_t regex; @@ -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) { |