README.md | 4 +++- nnn.1 | 4 ++++ nnn.c | 37 ++++++++++++++++++++++++++++++++++--- nnn.h | 8 +++++++- diff --git a/README.md b/README.md index e07bf9f784f5164bd07c3713949bf8a0e9fe3e8f..9b86c3a862b58b52422de8040821adfd4c8081dc 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ - run desktop search utility (gnome-search-tool or catfish) in any directory - copy absolute file path to clipboard, spawn a terminal and use the file path - navigate instantly using shortcuts like `~`, `-`, `&` or handy bookmarks - 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 - pin a directory you may need to revisit and jump to it anytime - set timeout to lock the current terminal @@ -113,6 +113,7 @@ - Spawn SHELL (fallback sh) in the current directory - Invoke file path copier (*easy* shell integration) - Change directory at exit (*easy* shell integration) - 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 - Monitor directory changes - Terminal screensaver (default vlock, customizable) integration @@ -276,6 +277,7 @@ export NNN_DE_FILE_MANAGER=thunar export NNN_DE_FILE_MANAGER=nautilus - [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 diff --git a/nnn.1 b/nnn.1 index e239f73c8908ff07fe188231a74ef890a7fad92b..b085e975ec8a2793cb9887782fe0d6e8d47ac9d9 100644 --- a/nnn.1 +++ b/nnn.1 @@ -93,6 +93,10 @@ .It Ic o Open directory in NNN_DE_FILE_MANAGER .It Ic p 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 Invoke file path copier .It Ic ^L diff --git a/nnn.c b/nnn.c index 5c465b07e74756858a91a32b3ea934290f91e4da..e7318d0a40a26efb5b8feb1015e046c79f6d0d82 100644 --- a/nnn.c +++ b/nnn.c @@ -251,7 +251,8 @@ "/usr/bin/open", #else "/usr/bin/xdg-open", #endif - "nlay" + "nlay", + "atool" }; /* Common message strings */ @@ -1625,6 +1626,23 @@ initcurses(); 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 * which indicates the number of spaces to print before the @@ -1674,6 +1692,8 @@ "e! | Spawn SHELL in dir\n" "ee | Edit entry in EDITOR\n" "eo | Open dir in file manager\n" "ep | Open entry in PAGER\n" + "ef | List archive\n" + "d^X | Extract archive\n" "d^K | Invoke file path copier\n" "d^L | Redraw, clear prompt\n" "e? | Help, settings\n" @@ -2550,13 +2570,24 @@ } } } break; + case SEL_LIST: // fallthrough + case SEL_EXTRACT: // fallthrough case SEL_MEDIA: // fallthrough case SEL_FMEDIA: if (ndents > 0) { mkpath(path, dents[cur].name, oldpath, PATH_MAX); - if (show_mediainfo(oldpath, run) == -1) { - sprintf(g_buf, "%s missing", utils[cfg.metaviewer]); + if (sel == SEL_MEDIA || sel == SEL_FMEDIA) + 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); goto nochange; } diff --git a/nnn.h b/nnn.h index 2de943d44bae14a543cfd545d766e788fd1cbf98..a298b067955fe63d73297eeddb41e8c4c0402a86 100644 --- a/nnn.h +++ b/nnn.h @@ -29,6 +29,8 @@ SEL_STATS, SEL_MEDIA, SEL_FMEDIA, SEL_DFB, + SEL_LIST, + SEL_EXTRACT, SEL_FSIZE, SEL_BSIZE, SEL_MTIME, @@ -45,7 +47,7 @@ /* Associate a pressed key to an action */ struct key { int sym; /* Key pressed */ enum action act; /* Action */ - char *run; /* Program to run */ + char *run; /* Program to run or program option */ char *env; /* Environment variable to run */ }; @@ -131,6 +133,10 @@ /* Show media info full, run is hacked */ { 'M', SEL_FMEDIA, "-f", "" }, /* Open dir in desktop file manager */ { 'o', SEL_DFB, "", "" }, + /* List archive */ + { 'f', SEL_LIST, "-l", "" }, + /* Extract archive */ + { CONTROL('X'), SEL_EXTRACT, "-x", "" }, /* Toggle sort by size */ { 's', SEL_FSIZE, "", "" }, /* Sort by total block count including dir contents */