Explorar el Código

Polish change directory logic

1. Strip end spaces and slashes
2. Do NOT change dir if in the same dir
3. Don't go back beyond startup dir with '-'
4. Reset oldpath on cd (other than cd . and ..)
5. Reset filter
6. Update features in README
master
Arun Prakash Jana hace 7 años
padre
commit
3096dfefde
No se encontró ninguna clave conocida en la base de datos para esta firma ID de clave GPG: A75979F35C080412
Se han modificado 3 ficheros con 91 adiciones y 43 borrados
  1. +8
    -3
      README.md
  2. +1
    -1
      config.def.h
  3. +82
    -39
      nnn.c

+ 8
- 3
README.md Ver fichero

@@ -33,6 +33,7 @@ Noice is Not Noice, a noicer fork...
- [How to](#how-to)
- [cd on quit](#cd-on-quit)
- [Copy current file path to clipboard](#copy-current-file-path-to-clipboard)
- [Boost chdir prompt](#boost-chdir-prompt)
- [Change file associations](#change-file-associations)
- [Why fork?](#why-fork)
- [Developers](#developers)
@@ -54,12 +55,12 @@ Have fun with it! PRs are welcome. Check out [#1](https://github.com/jarun/nnn/i
### Features

- Super-easy navigation with roll-over at edges
- Jump HOME or back to the last visited directory (as you normally do!)
- Jump HOME or back to the last visited directory (as usual!)
- Jump to initial dir, chdir prompt, cd ..... (with . as PWD)
- Desktop opener integration to handle mime types
- Customizable bash script nlay to handle known file types
- Disk usage analyzer mode
- Basic and detail views
- Show stat and file information
- Basic and detail view (with stat and file information)
- Show media information (needs mediainfo)
- Sort by modification time, size
- Sort numeric names in numeric order (1, 2, ... 10, 11, ...)
@@ -260,6 +261,10 @@ export `NNN_OPENER`:

Start nnn and use `^K` to copy the absolute path (from `/`) of the file under the cursor to clipboard.

#### Boost chdir prompt

nnn uses libreadline for the chdir prompt input. So all the fantastic features of readline (e.g. case insensitive tab completion, history, reverse-i-search) is available to you based on your readline [configuration](https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC9).

#### Change file associations

If `NNN_OPENER` is not set, nnn tries to recognize a file by the file extension and invokes nlay. To change the extensions recognized by nnn, modify the `assocs` structure in [config.def.h](https://github.com/jarun/nnn/blob/master/config.def.h) (it's easy). Then re-compile and install.


+ 1
- 1
config.def.h Ver fichero

@@ -66,7 +66,7 @@ static struct key bindings[] = {
/* Initial directory */
{ '&', SEL_CDBEGIN, "", "" },
/* Last visited dir */
{ '-', SEL_LAST, "", "" },
{ '-', SEL_CDLAST, "", "" },
/* Toggle hide .dot files */
{ '.', SEL_TOGGLEDOT, "", "" },
/* Detailed listing */


+ 82
- 39
nnn.c Ver fichero

@@ -90,7 +90,7 @@ enum action {
SEL_CD,
SEL_CDHOME,
SEL_CDBEGIN,
SEL_LAST,
SEL_CDLAST,
SEL_TOGGLEDOT,
SEL_DETAIL,
SEL_STATS,
@@ -386,22 +386,18 @@ xstricmp(const char *s1, const char *s2)
return (int) (TOUPPER(*s1) - TOUPPER(*s2));
}

/* Trim all white space from both ends */
/* Trim all whitespace from both ends, / from end */
static char *
strstrip(char *s)
{
size_t size;
char *end;

size = strlen(s);

if (!size)
if (!s || !*s)
return s;

end = s + size - 1;
while (end >= s && isspace(*end))
end--;
*(end + 1) = '\0';
size_t len = strlen(s) - 1;

while (len != 0 && (isspace(s[len]) || s[len] == '/'))
len--;
s[len + 1] = '\0';

while (*s && isspace(*s))
s++;
@@ -1281,10 +1277,10 @@ browse(char *ipath, char *ifilter)
enum action sel = SEL_RUNARG + 1;

xstrlcpy(path, ipath, sizeof(path));
xstrlcpy(lastdir, ipath, sizeof(lastdir));
xstrlcpy(fltr, ifilter, sizeof(fltr));
oldpath[0] = '\0';
newpath[0] = '\0';
lastdir[0] = '\0'; /* Can't move back from initial directory */
begin:

if (sel == SEL_GOIN && S_ISDIR(sb.st_mode))
@@ -1471,56 +1467,66 @@ nochange:
break;
case SEL_CD:
{
/* Read target dir */
static char *tmp, *input;
static int truecd;

/* Save the program start dir */
tmp = getcwd(newpath, PATH_MAX);
if (tmp == NULL) {
printwarn();
goto nochange;
}

/* Switch to current path for readline(3) */
if (chdir(path) == -1) {
printwarn();
goto nochange;
}

exitcurses();
char *tmp = readline("chdir: ");
tmp = readline("chdir: ");
initcurses();

/* Change back to program start dir */
if (chdir(newpath) == -1)
printwarn();

/* Save current */
if (ndents > 0)
mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));

if (tmp[0] == '\0')
break;
else
/* Add to readline(3) history */
add_history(tmp);

char *input = tmp;
input = tmp;
tmp = strstrip(tmp);
if (tmp[0] == '\0') {
free(input);
break;
}

truecd = 0;

if (tmp[0] == '~') {
/* Expand ~ to HOME absolute path */
char *home = getenv("HOME");
if (home)
snprintf(newpath, PATH_MAX,
"%s%s", home, tmp + 1);
else
mkpath(path, tmp, newpath, sizeof(newpath));

oldpath[0] = '\0';
snprintf(newpath, PATH_MAX, "%s%s", home, tmp + 1);
else {
free(input);
break;
}
} else if (tmp[0] == '-' && tmp[1] == '\0') {
xstrlcpy(newpath, lastdir, sizeof(newpath));
oldpath[0] = '\0';
if (lastdir[0] == '\0') {
free(input);
break;
}

/* Switch to last visited dir */
xstrlcpy(newpath, lastdir, sizeof(newpath));
truecd = 1;
} else if ((r = all_dots(tmp))) {
if (r == 1) {
/* Always in the current dir */
free(input);
break;
}
@@ -1529,15 +1535,17 @@ nochange:
dir = path;

for (fd = 0; fd < r; fd++) {
/* There is no going back */
/* Reached / ? */
if (strcmp(path, "/") == 0 ||
strchr(path, '/') == NULL) {
/* If it's a cd .. at / */
if (fd == 0) {
printmsg("You are at /");
free(input);
goto nochange;
}

/* Can't cd beyond / anyway */
break;
} else {
dir = xdirname(dir);
@@ -1549,28 +1557,44 @@ nochange:
}
}

/* Save history */
xstrlcpy(oldpath, path, sizeof(oldpath));
truecd = 1;

/* Save the path in case of cd ..
We mark the current dir in parent dir */
if (r == 1) {
xstrlcpy(oldpath, path, sizeof(oldpath));
truecd = 2;
}

xstrlcpy(newpath, dir, sizeof(newpath));
} else {
} else
mkpath(path, tmp, newpath, sizeof(newpath));
oldpath[0] = '\0';
}

if (canopendir(newpath) == 0) {
/* Save current */
if (ndents > 0)
mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));

printwarn();
free(input);
break;
}

if (truecd == 0) {
/* Probable change in dir */
/* No-op if it's the same directory */
if (strcmp(path, newpath) == 0) {
free(input);
break;
}

oldpath[0] = '\0';
} else if (truecd == 1)
/* Sure change in dir */
oldpath[0] = '\0';

/* Save last working directory */
xstrlcpy(lastdir, path, sizeof(lastdir));

/* Save the newly opted dir in path */
xstrlcpy(path, newpath, sizeof(path));

/* Reset filter */
xstrlcpy(fltr, ifilter, sizeof(fltr));
DPRINTF_S(path);
@@ -1583,15 +1607,20 @@ nochange:
clearprompt();
goto nochange;
}

if (canopendir(tmp) == 0) {
printwarn();
goto nochange;
}

if (strcmp(path, tmp) == 0)
break;

/* Save last working directory */
xstrlcpy(lastdir, path, sizeof(lastdir));

xstrlcpy(path, tmp, sizeof(path));
oldpath[0] = '\0';
/* Reset filter */
xstrlcpy(fltr, ifilter, sizeof(fltr));
DPRINTF_S(path);
@@ -1602,19 +1631,33 @@ nochange:
goto nochange;
}

if (strcmp(path, ipath) == 0)
break;

/* Save last working directory */
xstrlcpy(lastdir, path, sizeof(lastdir));

xstrlcpy(path, ipath, sizeof(path));
oldpath[0] = '\0';
/* Reset filter */
xstrlcpy(fltr, ifilter, sizeof(fltr));
DPRINTF_S(path);
goto begin;
case SEL_LAST:
case SEL_CDLAST:
if (lastdir[0] == '\0')
break;

if (canopendir(lastdir) == 0) {
printwarn();
goto nochange;
}

xstrlcpy(newpath, lastdir, sizeof(newpath));
xstrlcpy(lastdir, path, sizeof(lastdir));
xstrlcpy(path, newpath, sizeof(path));
oldpath[0] = '\0';
/* Reset filter */
xstrlcpy(fltr, ifilter, sizeof(fltr));
DPRINTF_S(path);
goto begin;
case SEL_TOGGLEDOT:


Cargando…
Cancelar
Guardar