Support archive listing and extraction

This commit is contained in:
Arun Prakash Jana 2017-09-27 20:19:42 +05:30
parent a594c876be
commit 71d27de517
No known key found for this signature in database
GPG key ID: A75979F35C080412
4 changed files with 48 additions and 5 deletions

View file

@ -67,7 +67,7 @@ Cool things you can do with `nnn`:
- copy absolute file path to clipboard, spawn a terminal and use the file path - copy absolute file path to clipboard, spawn a terminal and use the file path
- navigate instantly using shortcuts like `~`, `-`, `&` or handy bookmarks - navigate instantly using shortcuts like `~`, `-`, `&` or handy bookmarks
- use `cd .....` at chdir prompt to go to a parent directory - use `cd .....` at chdir prompt to go to a parent directory
- see detailed file stats or mediainfo information - detailed file stats, media info, list and extract archives
- open a (supported) archive in vim to view its contents - open a (supported) archive in vim to view its contents
- pin a directory you may need to revisit and jump to it anytime - pin a directory you may need to revisit and jump to it anytime
- set timeout to lock the current terminal - set timeout to lock the current terminal
@ -113,6 +113,7 @@ Have fun with it! PRs are welcome. Check out [#1](https://github.com/jarun/nnn/i
- Invoke file path copier (*easy* shell integration) - Invoke file path copier (*easy* shell integration)
- Change directory at exit (*easy* shell integration) - Change directory at exit (*easy* shell integration)
- Open any file in EDITOR (fallback vi) or PAGER (fallback less) - Open any file in EDITOR (fallback vi) or PAGER (fallback less)
- List and extract archives (needs atool)
- Open current directory in a custom GUI file browser - Open current directory in a custom GUI file browser
- Monitor directory changes - Monitor directory changes
- Terminal screensaver (default vlock, customizable) integration - Terminal screensaver (default vlock, customizable) integration
@ -276,6 +277,7 @@ The following abbreviations are used in the detail view:
export NNN_DE_FILE_MANAGER=thunar export NNN_DE_FILE_MANAGER=thunar
export NNN_DE_FILE_MANAGER=nautilus export NNN_DE_FILE_MANAGER=nautilus
- [mediainfo](https://mediaarea.net/en/MediaInfo) (or exiftool, if specified) is required to view media information - [mediainfo](https://mediaarea.net/en/MediaInfo) (or exiftool, if specified) is required to view media information
- [atool](http://www.nongnu.org/atool/) is required to list and extract archives
#### Help #### Help

4
nnn.1
View file

@ -93,6 +93,10 @@ Open current entry in EDITOR (fallback vi)
Open directory in NNN_DE_FILE_MANAGER Open directory in NNN_DE_FILE_MANAGER
.It Ic p .It Ic p
Open current entry in PAGER (fallback less) Open current entry in PAGER (fallback less)
.It Ic f
List files in archive
.It Ic ^X
Extract archive in current directory
.It Ic ^K .It Ic ^K
Invoke file path copier Invoke file path copier
.It Ic ^L .It Ic ^L

37
nnn.c
View file

@ -251,7 +251,8 @@ static char * const utils[] = {
#else #else
"/usr/bin/xdg-open", "/usr/bin/xdg-open",
#endif #endif
"nlay" "nlay",
"atool"
}; };
/* Common message strings */ /* Common message strings */
@ -1625,6 +1626,23 @@ show_mediainfo(char *fpath, char *arg)
return 0; return 0;
} }
static int
handle_archive(char *fpath, char *arg, char *dir)
{
if (!get_output(g_buf, MAX_CMD_LEN, "which", utils[4], NULL, 0))
return -1;
if (arg[1] == 'x')
spawn(utils[4], arg, fpath, dir, F_NORMAL);
else {
exitcurses();
get_output(NULL, 0, utils[4], arg, fpath, 1);
initcurses();
}
return 0;
}
/* /*
* The help string tokens (each line) start with a HEX value * The help string tokens (each line) start with a HEX value
* which indicates the number of spaces to print before the * which indicates the number of spaces to print before the
@ -1674,6 +1692,8 @@ show_help(char *path)
"ee | Edit entry in EDITOR\n" "ee | Edit entry in EDITOR\n"
"eo | Open dir in file manager\n" "eo | Open dir in file manager\n"
"ep | Open entry in PAGER\n" "ep | Open entry in PAGER\n"
"ef | List archive\n"
"d^X | Extract archive\n"
"d^K | Invoke file path copier\n" "d^K | Invoke file path copier\n"
"d^L | Redraw, clear prompt\n" "d^L | Redraw, clear prompt\n"
"e? | Help, settings\n" "e? | Help, settings\n"
@ -2550,13 +2570,24 @@ nochange:
} }
} }
break; break;
case SEL_LIST: // fallthrough
case SEL_EXTRACT: // fallthrough
case SEL_MEDIA: // fallthrough case SEL_MEDIA: // fallthrough
case SEL_FMEDIA: case SEL_FMEDIA:
if (ndents > 0) { if (ndents > 0) {
mkpath(path, dents[cur].name, oldpath, PATH_MAX); mkpath(path, dents[cur].name, oldpath, PATH_MAX);
if (show_mediainfo(oldpath, run) == -1) { if (sel == SEL_MEDIA || sel == SEL_FMEDIA)
sprintf(g_buf, "%s missing", utils[cfg.metaviewer]); r = show_mediainfo(oldpath, run);
else
r = handle_archive(oldpath, run, path);
if (r == -1) {
if (sel == SEL_MEDIA || sel == SEL_FMEDIA)
sprintf(g_buf, "%s missing", utils[cfg.metaviewer]);
else
sprintf(g_buf, "%s missing", utils[4]);
printmsg(g_buf); printmsg(g_buf);
goto nochange; goto nochange;
} }

8
nnn.h
View file

@ -29,6 +29,8 @@ enum action {
SEL_MEDIA, SEL_MEDIA,
SEL_FMEDIA, SEL_FMEDIA,
SEL_DFB, SEL_DFB,
SEL_LIST,
SEL_EXTRACT,
SEL_FSIZE, SEL_FSIZE,
SEL_BSIZE, SEL_BSIZE,
SEL_MTIME, SEL_MTIME,
@ -45,7 +47,7 @@ enum action {
struct key { struct key {
int sym; /* Key pressed */ int sym; /* Key pressed */
enum action act; /* Action */ enum action act; /* Action */
char *run; /* Program to run */ char *run; /* Program to run or program option */
char *env; /* Environment variable to run */ char *env; /* Environment variable to run */
}; };
@ -131,6 +133,10 @@ static struct key bindings[] = {
{ 'M', SEL_FMEDIA, "-f", "" }, { 'M', SEL_FMEDIA, "-f", "" },
/* Open dir in desktop file manager */ /* Open dir in desktop file manager */
{ 'o', SEL_DFB, "", "" }, { 'o', SEL_DFB, "", "" },
/* List archive */
{ 'f', SEL_LIST, "-l", "" },
/* Extract archive */
{ CONTROL('X'), SEL_EXTRACT, "-x", "" },
/* Toggle sort by size */ /* Toggle sort by size */
{ 's', SEL_FSIZE, "", "" }, { 's', SEL_FSIZE, "", "" },
/* Sort by total block count including dir contents */ /* Sort by total block count including dir contents */