]> Sergey Matveev's repositories - nnn.git/commitdiff
Support archive listing and extraction
authorArun Prakash Jana <engineerarun@gmail.com>
Wed, 27 Sep 2017 14:49:42 +0000 (20:19 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Wed, 27 Sep 2017 16:44:01 +0000 (22:14 +0530)
README.md
nnn.1
nnn.c
nnn.h

index e07bf9f784f5164bd07c3713949bf8a0e9fe3e8f..9b86c3a862b58b52422de8040821adfd4c8081dc 100644 (file)
--- a/README.md
+++ b/README.md
@@ -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
 - 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 @@ Have fun with it! PRs are welcome. Check out [#1](https://github.com/jarun/nnn/i
   - 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 @@ The following abbreviations are used in the detail view:
         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 (file)
--- a/nnn.1
+++ b/nnn.1
@@ -93,6 +93,10 @@ Open current entry in EDITOR (fallback vi)
 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 (file)
--- a/nnn.c
+++ b/nnn.c
@@ -251,7 +251,8 @@ static char * const utils[] = {
 #else
        "/usr/bin/xdg-open",
 #endif
-       "nlay"
+       "nlay",
+       "atool"
 };
 
 /* Common message strings */
@@ -1625,6 +1626,23 @@ show_mediainfo(char *fpath, char *arg)
        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 @@ show_help(char *path)
              "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 @@ nochange:
                                }
                        }
                        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 (file)
--- a/nnn.h
+++ b/nnn.h
@@ -29,6 +29,8 @@ enum action {
        SEL_MEDIA,
        SEL_FMEDIA,
        SEL_DFB,
+       SEL_LIST,
+       SEL_EXTRACT,
        SEL_FSIZE,
        SEL_BSIZE,
        SEL_MTIME,
@@ -45,7 +47,7 @@ enum 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 @@ static struct key bindings[] = {
        { '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 */