Add support for passing options to file associations - noice - small file brows… | |
git clone git://git.codemadness.org/noice | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 36de02e0658d7ddbf7d63879c812864d984e66a9 | |
parent ae2cb6f11dc6ea982fbb7e70ae6769d4ed66a160 | |
Author: sin <[email protected]> | |
Date: Sun, 31 Mar 2019 11:10:04 +0100 | |
Add support for passing options to file associations | |
Diffstat: | |
M config.def.h | 12 ++++++------ | |
M noice.1 | 17 +---------------- | |
M noice.c | 66 ++++++++++++++++++++++++-----… | |
3 files changed, 58 insertions(+), 37 deletions(-) | |
--- | |
diff --git a/config.def.h b/config.def.h | |
@@ -32,12 +32,12 @@ struct cpair pairs[] = { | |
}; | |
struct assoc assocs[] = { | |
- { "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", "mpv" }, | |
- { "\\.(png|jpg|gif)$", "sxiv" }, | |
- { "\\.(html|svg)$", "firefox" }, | |
- { "\\.pdf$", "mupdf" }, | |
- { "\\.sh$", "sh" }, | |
- { ".", "less" }, | |
+ { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv … | |
+ { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}"… | |
+ { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "… | |
+ { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} … | |
+ { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} }, | |
+ { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } }, | |
}; | |
struct key bindings[] = { | |
diff --git a/noice.1 b/noice.1 | |
@@ -1,4 +1,4 @@ | |
-.Dd Jan 19, 2019 | |
+.Dd March 31, 2019 | |
.Dt NOICE 1 | |
.Os | |
.Sh NAME | |
@@ -99,8 +99,6 @@ command in | |
to edit the file using the | |
.Ev EDITOR | |
environment variable. | |
-.Pp | |
-See the examples section below for more information. | |
.Sh FILTERS | |
Filters allow you to use regexes to display only the matched | |
entries in the current directory view. | |
@@ -127,19 +125,6 @@ environment variables take precedence when dealing with the | |
and | |
.Ic p | |
commands respectively. | |
-.Sh EXAMPLES | |
-The following example shows one possible configuration for | |
-file associations which is also the default: | |
-.Bd -literal | |
-struct assoc assocs[] = { | |
- { "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", "mpv" }, | |
- { "\\.(png|jpg|gif)$", "sxiv" }, | |
- { "\\.(html|svg)$", "firefox" }, | |
- { "\\.pdf$", "mupdf" }, | |
- { "\\.sh$", "sh" }, | |
- { ".", "less" }, | |
-}; | |
-.Ed | |
.Sh KNOWN ISSUES | |
If you are using | |
.Xr urxvt 1 | |
diff --git a/noice.c b/noice.c | |
@@ -33,6 +33,7 @@ | |
#define DPRINTF_P(x) | |
#endif /* DEBUG */ | |
+#define NR_ARGS 32 | |
#define LEN(x) (sizeof(x) / sizeof(*(x))) | |
#undef MIN | |
#define MIN(x, y) ((x) < (y) ? (x) : (y)) | |
@@ -42,7 +43,8 @@ | |
struct assoc { | |
char *regex; /* Regex to match on filename */ | |
- char *bin; /* Program */ | |
+ char *file; | |
+ char *argv[NR_ARGS]; | |
}; | |
struct cpair { | |
@@ -178,7 +180,7 @@ xdirname(const char *path) | |
} | |
void | |
-spawn(char *file, char *arg, char *dir) | |
+spawnvp(char *dir, char *file, char *argv[]) | |
{ | |
pid_t pid; | |
int status; | |
@@ -187,7 +189,7 @@ spawn(char *file, char *arg, char *dir) | |
if (pid == 0) { | |
if (dir != NULL) | |
chdir(dir); | |
- execlp(file, file, arg, NULL); | |
+ execvp(file, argv); | |
_exit(1); | |
} else { | |
/* Ignore interruptions */ | |
@@ -197,6 +199,39 @@ spawn(char *file, char *arg, char *dir) | |
} | |
} | |
+void | |
+spawnlp(char *dir, char *file, char *argv0, ...) | |
+{ | |
+ char *argv[NR_ARGS]; | |
+ va_list ap; | |
+ int argc; | |
+ | |
+ va_start(ap, argv0); | |
+ argv[0] = argv0; | |
+ for (argc = 1; argv[argc] = va_arg(ap, char *); argc++) | |
+ ; | |
+ argv[argc] = NULL; | |
+ va_end(ap); | |
+ spawnvp(dir, file, argv); | |
+} | |
+ | |
+void | |
+spawnassoc(struct assoc *assoc, char *arg) | |
+{ | |
+ char *argv[NR_ARGS]; | |
+ int i; | |
+ | |
+ for (i = 0; assoc->argv[i]; i++) { | |
+ if (strcmp(assoc->argv[i], "{}") == 0) { | |
+ argv[i] = arg; | |
+ continue; | |
+ } | |
+ argv[i] = assoc->argv[i]; | |
+ } | |
+ argv[i] = NULL; | |
+ spawnvp(NULL, assoc->file, argv); | |
+} | |
+ | |
char * | |
xgetenv(char *name, char *fallback) | |
{ | |
@@ -208,11 +243,11 @@ xgetenv(char *name, char *fallback) | |
return value && value[0] ? value : fallback; | |
} | |
-char * | |
+struct assoc * | |
openwith(char *file) | |
{ | |
regex_t regex; | |
- char *bin = NULL; | |
+ struct assoc *assoc = NULL; | |
int i; | |
for (i = 0; i < LEN(assocs); i++) { | |
@@ -220,14 +255,14 @@ openwith(char *file) | |
REG_NOSUB | REG_EXTENDED | REG_ICASE) != 0) | |
continue; | |
if (regexec(®ex, file, 0, NULL, 0) == 0) { | |
- bin = assocs[i].bin; | |
+ assoc = &assocs[i]; | |
regfree(®ex); | |
break; | |
} | |
regfree(®ex); | |
} | |
- DPRINTF_S(bin); | |
- return bin; | |
+ DPRINTF_S(assoc->argv[0]); | |
+ return assoc; | |
} | |
int | |
@@ -653,7 +688,8 @@ browse(char *ipath, char *ifilter) | |
{ | |
char path[PATH_MAX], oldpath[PATH_MAX], newpath[PATH_MAX]; | |
char fltr[LINE_MAX]; | |
- char *bin, *dir, *tmp, *run, *env; | |
+ char *dir, *tmp, *run, *env; | |
+ struct assoc *assoc; | |
struct stat sb; | |
regex_t re; | |
int r, fd; | |
@@ -726,13 +762,13 @@ nochange: | |
strlcpy(fltr, ifilter, sizeof(fltr)); | |
goto begin; | |
case S_IFREG: | |
- bin = openwith(newpath); | |
- if (bin == NULL) { | |
+ assoc = openwith(newpath); | |
+ if (assoc == NULL) { | |
printmsg("No association"); | |
goto nochange; | |
} | |
exitcurses(); | |
- spawn(bin, newpath, NULL); | |
+ spawnassoc(assoc, newpath); | |
initcurses(); | |
continue; | |
default: | |
@@ -845,7 +881,7 @@ nochange: | |
mkpath(path, dents[cur].name, oldpath, sizeof(… | |
run = xgetenv(env, run); | |
exitcurses(); | |
- spawn(run, NULL, path); | |
+ spawnlp(path, run, run, NULL); | |
initcurses(); | |
goto begin; | |
case SEL_RUNARG: | |
@@ -854,7 +890,7 @@ nochange: | |
mkpath(path, dents[cur].name, oldpath, sizeof(… | |
run = xgetenv(env, run); | |
exitcurses(); | |
- spawn(run, dents[cur].name, path); | |
+ spawnlp(path, run, run, dents[cur].name, NULL); | |
initcurses(); | |
goto begin; | |
} | |
@@ -862,7 +898,7 @@ nochange: | |
if (idletimeout != 0 && idle == idletimeout) { | |
idle = 0; | |
exitcurses(); | |
- spawn(idlecmd, NULL, NULL); | |
+ spawnlp(NULL, idlecmd, idlecmd, NULL); | |
initcurses(); | |
} | |
} |