mirror of
https://github.com/jarun/nnn.git
synced 2024-11-24 11:51:27 +00:00
Mount archives using archivemount
This commit is contained in:
parent
c54f50cf4f
commit
19df7777db
|
@ -44,7 +44,7 @@ Add to that an awesome [Wiki](https://github.com/jarun/nnn/wiki)!
|
||||||
- Subtree search to open or edit files (using plugin)
|
- Subtree search to open or edit files (using plugin)
|
||||||
- Mimes
|
- Mimes
|
||||||
- Open with desktop opener or specify a custom app
|
- Open with desktop opener or specify a custom app
|
||||||
- Create, list, extract archives
|
- Create, list, extract, mount (FUSE based) archives
|
||||||
- Option to open all text files in EDITOR
|
- Option to open all text files in EDITOR
|
||||||
- Information
|
- Information
|
||||||
- Detailed file information
|
- Detailed file information
|
||||||
|
@ -90,6 +90,7 @@ A curses library with wide char support (e.g. ncursesw), libreadline (`make O_NO
|
||||||
| xdg-open (Linux), open(1) (macOS), cygstart (Cygwin) | base | desktop opener |
|
| xdg-open (Linux), open(1) (macOS), cygstart (Cygwin) | base | desktop opener |
|
||||||
| file, coreutils (cp, mv, rm), findutils (xargs) | base | file type, copy, move and remove |
|
| file, coreutils (cp, mv, rm), findutils (xargs) | base | file type, copy, move and remove |
|
||||||
| tar, (un)zip [atool/bsdtar for more formats] | base | create, list, extract tar, gzip, bzip2, zip |
|
| tar, (un)zip [atool/bsdtar for more formats] | base | create, list, extract tar, gzip, bzip2, zip |
|
||||||
|
| archivemount | optional | mount archives over FUSE |
|
||||||
| sshfs, fusermount(3) | optional | mount, unmount over SSHFS |
|
| sshfs, fusermount(3) | optional | mount, unmount over SSHFS |
|
||||||
| trash-cli | optional | trash files (default action: delete) |
|
| trash-cli | optional | trash files (default action: delete) |
|
||||||
| vlock (Linux), bashlock (macOS), lock(1) (BSD) | optional | terminal locker (fallback: [cmatrix](https://github.com/abishekvashok/cmatrix)) |
|
| vlock (Linux), bashlock (macOS), lock(1) (BSD) | optional | terminal locker (fallback: [cmatrix](https://github.com/abishekvashok/cmatrix)) |
|
||||||
|
@ -211,14 +212,14 @@ The list below is from the **dev branch**. Press <kbd>?</kbd> in `nnn` to see th
|
||||||
a Select all K Edit selection
|
a Select all K Edit selection
|
||||||
P Copy selection X Delete selection
|
P Copy selection X Delete selection
|
||||||
V Move selection ^X Delete entry
|
V Move selection ^X Delete entry
|
||||||
f Create archive C Execute entry
|
f Create archive T Mount archive
|
||||||
^F Extract archive F List archive
|
^F Extract archive F List archive
|
||||||
e Edit in EDITOR p Open in PAGER
|
e Edit in EDITOR p Open in PAGER
|
||||||
ORDER TOGGLES
|
ORDER TOGGLES
|
||||||
A Apparent du S du
|
A Apparent du S du
|
||||||
s Size E Extn t Time
|
s Size E Extn t Time
|
||||||
MISC
|
MISC
|
||||||
! ^] Shell = Launcher
|
! ^] Shell = Launch C Execute entry
|
||||||
R ^V Pick plugin :K xK Execute plugin K
|
R ^V Pick plugin :K xK Execute plugin K
|
||||||
c SSHFS mount u Unmount
|
c SSHFS mount u Unmount
|
||||||
^P Prompt/run cmd L Lock
|
^P Prompt/run cmd L Lock
|
||||||
|
|
87
src/nnn.c
87
src/nnn.c
|
@ -383,6 +383,7 @@ static char mv[] = "mvg -gi";
|
||||||
#define STR_TMPFILE 3
|
#define STR_TMPFILE 3
|
||||||
#define NONE_SELECTED 4
|
#define NONE_SELECTED 4
|
||||||
#define UTIL_MISSING 5
|
#define UTIL_MISSING 5
|
||||||
|
#define MOUNT_FAILED 6
|
||||||
|
|
||||||
static const char * const messages[] = {
|
static const char * const messages[] = {
|
||||||
"no traversal",
|
"no traversal",
|
||||||
|
@ -391,6 +392,7 @@ static const char * const messages[] = {
|
||||||
"/.nnnXXXXXX",
|
"/.nnnXXXXXX",
|
||||||
"0 selected",
|
"0 selected",
|
||||||
"missing dep",
|
"missing dep",
|
||||||
|
"mount failed",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Supported configuration environment variables */
|
/* Supported configuration environment variables */
|
||||||
|
@ -2793,6 +2795,50 @@ static bool create_dir(const char *path)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool archive_mount(char *name, char *path, char *newpath, int *presel)
|
||||||
|
{
|
||||||
|
char *dir, *cmd = "archivemount";
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!getutil(cmd)) {
|
||||||
|
printwait(messages[UTIL_MISSING], presel);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = strdup(name);
|
||||||
|
if (!dir)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
len = strlen(dir);
|
||||||
|
|
||||||
|
while (len > 1)
|
||||||
|
if (dir[--len] == '.') {
|
||||||
|
dir[len] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF_S(dir);
|
||||||
|
|
||||||
|
/* Create the mount point */
|
||||||
|
mkpath(cfgdir, dir, newpath);
|
||||||
|
free(dir);
|
||||||
|
|
||||||
|
if (!create_dir(newpath)) {
|
||||||
|
printwait(strerror(errno), presel);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mount archive */
|
||||||
|
DPRINTF_S(name);
|
||||||
|
DPRINTF_S(newpath);
|
||||||
|
if (spawn(cmd, name, newpath, path, F_NORMAL)) {
|
||||||
|
printwait(messages[MOUNT_FAILED], presel);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static bool sshfs_mount(char *newpath, int *presel)
|
static bool sshfs_mount(char *newpath, int *presel)
|
||||||
{
|
{
|
||||||
uchar flag = F_NORMAL;
|
uchar flag = F_NORMAL;
|
||||||
|
@ -2828,18 +2874,23 @@ static bool sshfs_mount(char *newpath, int *presel)
|
||||||
|
|
||||||
/* Connect to remote */
|
/* Connect to remote */
|
||||||
if (spawn(env, tmp, newpath, NULL, flag)) {
|
if (spawn(env, tmp, newpath, NULL, flag)) {
|
||||||
printwait("mount failed", presel);
|
printwait(messages[MOUNT_FAILED], presel);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sshfs_unmount(char *newpath, int *presel)
|
/*
|
||||||
|
* Unmounts if the directory represented by name is a mount point.
|
||||||
|
* Otherwise, asks for hostname
|
||||||
|
*/
|
||||||
|
static bool unmount(char *name, char *newpath, int *presel)
|
||||||
{
|
{
|
||||||
static char cmd[] = "fusermount3"; /* Arch Linux utility */
|
static char cmd[] = "fusermount3"; /* Arch Linux utility */
|
||||||
static bool found = FALSE;
|
static bool found = FALSE;
|
||||||
char *tmp;
|
char *tmp = name;
|
||||||
|
struct stat sb, psb;
|
||||||
|
|
||||||
/* On Ubuntu it's fusermount */
|
/* On Ubuntu it's fusermount */
|
||||||
if (!found && !getutil(cmd)) {
|
if (!found && !getutil(cmd)) {
|
||||||
|
@ -2847,9 +2898,19 @@ static bool sshfs_unmount(char *newpath, int *presel)
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = xreadline(NULL, "host: ");
|
if (tmp) {
|
||||||
if (!tmp[0])
|
mkpath(cfgdir, tmp, newpath);
|
||||||
return FALSE;
|
if ((lstat(newpath, &sb) == -1) || (lstat(dirname(newpath), &psb) == -1)) {
|
||||||
|
*presel = MSGWAIT;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tmp || (sb.st_dev == psb.st_dev)) {
|
||||||
|
tmp = xreadline(NULL, "host: ");
|
||||||
|
if (!tmp[0])
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the mount point */
|
/* Create the mount point */
|
||||||
mkpath(cfgdir, tmp, newpath);
|
mkpath(cfgdir, tmp, newpath);
|
||||||
|
@ -2919,14 +2980,14 @@ static void show_help(const char *path)
|
||||||
"ca Select all K Edit selection\n"
|
"ca Select all K Edit selection\n"
|
||||||
"cP Copy selection X Delete selection\n"
|
"cP Copy selection X Delete selection\n"
|
||||||
"cV Move selection ^X Delete entry\n"
|
"cV Move selection ^X Delete entry\n"
|
||||||
"cf Create archive C Execute entry\n"
|
"cf Create archive T Mount archive\n"
|
||||||
"b^F Extract archive F List archive\n"
|
"b^F Extract archive F List archive\n"
|
||||||
"ce Edit in EDITOR p Open in PAGER\n"
|
"ce Edit in EDITOR p Open in PAGER\n"
|
||||||
"1ORDER TOGGLES\n"
|
"1ORDER TOGGLES\n"
|
||||||
"cA Apparent du S du\n"
|
"cA Apparent du S du\n"
|
||||||
"cs Size E Extn t Time\n"
|
"cs Size E Extn t Time\n"
|
||||||
"1MISC\n"
|
"1MISC\n"
|
||||||
"9! ^] Shell = Launcher\n"
|
"9! ^] Shell = Launch C Execute entry\n"
|
||||||
"9R ^V Pick plugin :K xK Execute plugin K\n"
|
"9R ^V Pick plugin :K xK Execute plugin K\n"
|
||||||
"cc SSHFS mount u Unmount\n"
|
"cc SSHFS mount u Unmount\n"
|
||||||
"b^P Prompt/run cmd L Lock\n"};
|
"b^P Prompt/run cmd L Lock\n"};
|
||||||
|
@ -4577,8 +4638,11 @@ nochange:
|
||||||
|
|
||||||
/* Repopulate as directory content may have changed */
|
/* Repopulate as directory content may have changed */
|
||||||
goto begin;
|
goto begin;
|
||||||
|
case SEL_ARCHIVEMNT:
|
||||||
|
if (!ndents || !archive_mount(dents[cur].name, path, newpath, &presel))
|
||||||
|
goto nochange; // fallthrough
|
||||||
case SEL_SSHFS:
|
case SEL_SSHFS:
|
||||||
if (!sshfs_mount(newpath, &presel))
|
if (sel == SEL_SSHFS && !sshfs_mount(newpath, &presel))
|
||||||
goto nochange;
|
goto nochange;
|
||||||
|
|
||||||
lastname[0] = '\0';
|
lastname[0] = '\0';
|
||||||
|
@ -4592,7 +4656,8 @@ nochange:
|
||||||
setdirwatch();
|
setdirwatch();
|
||||||
goto begin;
|
goto begin;
|
||||||
case SEL_UMOUNT:
|
case SEL_UMOUNT:
|
||||||
sshfs_unmount(newpath, &presel);
|
tmp = ndents ? dents[cur].name : NULL;
|
||||||
|
unmount(tmp, newpath, &presel);
|
||||||
goto nochange;
|
goto nochange;
|
||||||
case SEL_QUITCD: // fallthrough
|
case SEL_QUITCD: // fallthrough
|
||||||
case SEL_QUIT:
|
case SEL_QUIT:
|
||||||
|
|
|
@ -88,6 +88,7 @@ enum action {
|
||||||
SEL_NEW,
|
SEL_NEW,
|
||||||
SEL_RENAME,
|
SEL_RENAME,
|
||||||
SEL_RENAMEMUL,
|
SEL_RENAMEMUL,
|
||||||
|
SEL_ARCHIVEMNT,
|
||||||
SEL_SSHFS,
|
SEL_SSHFS,
|
||||||
SEL_UMOUNT,
|
SEL_UMOUNT,
|
||||||
SEL_HELP,
|
SEL_HELP,
|
||||||
|
@ -229,6 +230,8 @@ static struct key bindings[] = {
|
||||||
{ KEY_F(2), SEL_RENAME },
|
{ KEY_F(2), SEL_RENAME },
|
||||||
/* Rename contents of current dir */
|
/* Rename contents of current dir */
|
||||||
{ 'r', SEL_RENAMEMUL },
|
{ 'r', SEL_RENAMEMUL },
|
||||||
|
/* Mount an archive */
|
||||||
|
{ 'T', SEL_ARCHIVEMNT },
|
||||||
/* Connect to server over SSHFS */
|
/* Connect to server over SSHFS */
|
||||||
{ 'c', SEL_SSHFS },
|
{ 'c', SEL_SSHFS },
|
||||||
/* Disconnect a SSHFS mount point */
|
/* Disconnect a SSHFS mount point */
|
||||||
|
|
Loading…
Reference in a new issue