diff options
author | sin <sin@2f30.org> | 2019-08-02 15:43:07 +0100 |
---|---|---|
committer | sin <sin@2f30.org> | 2019-08-03 22:28:36 +0100 |
commit | 50592339bf450037972b85777d1c524e35545aa8 (patch) | |
tree | dc1fcea3d52e382b37f50c45d16cb9dc9b5a8036 | |
parent | 47d659c5fc930f0815c2bf5a24b3c2228b13695e (diff) | |
download | noice-50592339bf450037972b85777d1c524e35545aa8.tar.gz |
Implement nopen(1)
-rw-r--r-- | Makefile | 48 | ||||
-rw-r--r-- | noice.1 | 24 | ||||
-rw-r--r-- | noice.c | 113 | ||||
-rw-r--r-- | noiceconf.def.h (renamed from config.def.h) | 9 | ||||
-rw-r--r-- | nopen.1 | 31 | ||||
-rw-r--r-- | nopen.c | 95 | ||||
-rw-r--r-- | nopenconf.def.h | 9 | ||||
-rw-r--r-- | spawn.c | 43 | ||||
-rw-r--r-- | strverscmp.c | 2 | ||||
-rw-r--r-- | util.h | 21 |
10 files changed, 234 insertions, 161 deletions
@@ -1,45 +1,53 @@ VERSION = 0.8 - PREFIX = /usr/local MANPREFIX = $(PREFIX)/man #CPPFLAGS = -DDEBUG #CFLAGS = -g -LDLIBS = -lcurses -DISTFILES = noice.c strlcat.c strlcpy.c strverscmp.c util.h config.def.h\ - noice.1 Makefile README LICENSE -OBJ = noice.o strlcat.o strlcpy.o strverscmp.o -BIN = noice +NOICELDLIBS = -lcurses +NOPENLDLIBS = +NOICEOBJ = noice.o spawn.o strlcat.o strlcpy.o strverscmp.o +NOPENOBJ = nopen.o spawn.o +BIN = noice nopen +MAN = noice.1 nopen.1 all: $(BIN) -$(BIN): $(OBJ) - $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(LDLIBS) +noice: $(NOICEOBJ) + $(CC) $(CFLAGS) -o $@ $(NOICEOBJ) $(LDFLAGS) $(NOICELDLIBS) + +nopen: $(NOPENOBJ) + $(CC) $(CFLAGS) -o $@ $(NOPENOBJ) $(LDFLAGS) $(NOPENLDLIBS) -noice.o: util.h config.h +noice.o: noiceconf.h util.h +nopen.o: nopenconf.h util.h +spawn.o: util.h strlcat.o: util.h strlcpy.o: util.h +strverscmp.o: util.h + +noiceconf.h: + cp noiceconf.def.h $@ -config.h: - cp config.def.h $@ +nopenconf.h: + cp nopenconf.def.h $@ install: all mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - cp -f $(BIN).1 $(DESTDIR)$(MANPREFIX)/man1 + cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1 uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN) - rm -f $(DESTDIR)$(MANPREFIX)/man1/$(BIN).1 + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) + cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) -dist: +dist: clean mkdir -p noice-$(VERSION) - cp $(DISTFILES) noice-$(VERSION) - tar -cf noice-$(VERSION).tar noice-$(VERSION) - gzip noice-$(VERSION).tar - rm -rf noice-$(VERSION) + cp `find . -maxdepth 1 -type f` noice-$(VERSION) + tar -c noice-$(VERSION) | gzip > noice-$(VERSION).tar.gz clean: - rm -f $(BIN) $(OBJ) noice-$(VERSION).tar.gz + rm -f $(BIN) $(NOICEOBJ) $(NOPENOBJ) noice-$(VERSION).tar.gz + rm -rf noice-$(VERSION) @@ -1,4 +1,4 @@ -.Dd March 31, 2019 +.Dd August 2, 2019 .Dt NOICE 1 .Os .Sh NAME @@ -84,23 +84,13 @@ directory you came out of. .Sh CONFIGURATION .Nm is configured by modifying -.Pa config.h +.Pa noiceconf.h and recompiling the code. .Pp -The file associations are specified by regexes -matching on the currently selected filename. -If a match is found the associated program is executed -with the filename passed in as the argument. -If no match is found the program -.Xr less 1 -is invoked. -This is useful for editing text files as one can use the -.Ic v -command in -.Xr less 1 -to edit the file using the -.Ev EDITOR -environment variable. +.Nm +invokes +.Xr nopen 1 +to open a file in the user's preferred application. .Sh FILTERS Filters allow you to use regexes to display only the matched entries in the current directory view. @@ -131,6 +121,8 @@ commands respectively. If you are using .Xr urxvt 1 you might have to set backspace key to DEC. +.Sh SEE ALSO +.Xr nopen 1 .Sh AUTHORS .An Lazaros Koromilas Aq Mt lostd@2f30.org , .An Dimitris Papastamos Aq Mt sin@2f30.org . @@ -1,7 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <sys/stat.h> #include <sys/types.h> -#include <sys/wait.h> #include <curses.h> #include <dirent.h> @@ -20,21 +19,12 @@ #include "util.h" -#define NR_ARGS 32 -#define LEN(x) (sizeof(x) / sizeof(*(x))) #undef MIN #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define ISODD(x) ((x) & 1) #define CONTROL(c) ((c) ^ 0x40) #define META(c) ((c) ^ 0x80) -struct assoc { - char *regex; /* Regex to match on filename */ - char *file; - char *argv[NR_ARGS]; - regex_t regcomp; -}; - struct cpair { int fg; int bg; @@ -71,7 +61,7 @@ struct key { char *env; /* Environment variable to run */ }; -#include "config.h" +#include "noiceconf.h" struct entry { char name[PATH_MAX]; @@ -167,59 +157,6 @@ xdirname(const char *path) return out; } -void -spawnvp(char *dir, char *file, char *argv[]) -{ - pid_t pid; - int status; - - pid = fork(); - if (pid == 0) { - if (dir != NULL) - chdir(dir); - execvp(file, argv); - _exit(1); - } else { - /* Ignore interruptions */ - while (waitpid(pid, &status, 0) == -1) - DPRINTF_D(status); - DPRINTF_D(pid); - } -} - -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) { @@ -231,21 +168,6 @@ xgetenv(char *name, char *fallback) return value && value[0] ? value : fallback; } -struct assoc * -openwith(char *file) -{ - int i; - - for (i = 0; i < LEN(assocs); i++) { - if (regexec(&assocs[i].regcomp, file, 0, NULL, 0) == 0) { - DPRINTF_S(assocs[i].argv[0]); - return &assocs[i]; - } - } - - return NULL; -} - int setfilter(regex_t *regex, char *filter) { @@ -671,7 +593,6 @@ browse(char *ipath, char *ifilter) char path[PATH_MAX], oldpath[PATH_MAX], newpath[PATH_MAX]; char fltr[LINE_MAX]; char *dir, *tmp, *run, *env; - struct assoc *assoc; struct stat sb; regex_t re; int r, fd; @@ -744,13 +665,8 @@ nochange: strlcpy(fltr, ifilter, sizeof(fltr)); goto begin; case S_IFREG: - assoc = openwith(newpath); - if (assoc == NULL) { - printmsg("No association"); - goto nochange; - } exitcurses(); - spawnassoc(assoc, newpath); + spawnlp(path, "nopen", "nopen", newpath, (void *)0); initcurses(); continue; default: @@ -869,7 +785,7 @@ nochange: mkpath(path, dents[cur].name, oldpath, sizeof(oldpath)); run = xgetenv(env, run); exitcurses(); - spawnlp(path, run, run, NULL); + spawnlp(path, run, run, (void *)0); initcurses(); goto begin; case SEL_RUNARG: @@ -878,7 +794,7 @@ nochange: mkpath(path, dents[cur].name, oldpath, sizeof(oldpath)); run = xgetenv(env, run); exitcurses(); - spawnlp(path, run, run, dents[cur].name, NULL); + spawnlp(path, run, run, dents[cur].name, (void *)0); initcurses(); goto begin; } @@ -886,31 +802,13 @@ nochange: if (idletimeout != 0 && idle == idletimeout) { idle = 0; exitcurses(); - spawnlp(NULL, idlecmd, idlecmd, NULL); + spawnlp(NULL, idlecmd, idlecmd, (void *)0); initcurses(); } } } void -initassocs(void) -{ - char errbuf[256]; - int i, r; - - for (i = 0; i < LEN(assocs); i++) { - r = regcomp(&assocs[i].regcomp, assocs[i].regex, - REG_NOSUB | REG_EXTENDED | REG_ICASE); - if (r != 0) { - regerror(r, &assocs[i].regcomp, errbuf, sizeof(errbuf)); - fprintf(stderr, "invalid regex assocs[%d]: %s: %s\n", - i, assocs[i].regex, errbuf); - exit(1); - } - } -} - -void usage(char *argv0) { fprintf(stderr, "usage: %s [dir]\n", argv0); @@ -954,7 +852,6 @@ main(int argc, char *argv[]) /* Set locale before curses setup */ setlocale(LC_ALL, ""); - initassocs(); initcurses(); browse(ipath, ifilter); exitcurses(); diff --git a/config.def.h b/noiceconf.def.h index dafc891..4a3513c 100644 --- a/config.def.h +++ b/noiceconf.def.h @@ -32,15 +32,6 @@ struct cpair pairs[] = { { COLOR_CYAN, -1 }, }; -struct assoc assocs[] = { - { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv = { "mpv", "{}", NULL } }, - { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}", NULL} }, - { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "{}", NULL } }, - { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} }, - { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} }, - { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } }, -}; - struct key bindings[] = { /* Quit */ { 'q', SEL_QUIT }, @@ -0,0 +1,31 @@ +.Dd August 2, 2019 +.Dt NOPEN 1 +.Os +.Sh NAME +.Nm nopen +.Nd opens a file in the user's preferred application +.Sh SYNOPSIS +.Nm +.Ar file... +.Sh DESCRIPTION +.Nm +opens the files provided as arguments with the user's proferred +application. +.Pp +The file associations are specified by regexes +matching on the currently selected filename. +If a match is found the associated program is executed +with the filename passed in as the argument. +If no match is found the program +.Xr less 1 +is invoked. +.Sh CONFIGURATION +.Nm +is configured by modifying +.Pa nopenconf.h +and recompiling the code. +.Sh SEE ALSO +.Xr noice 1 +.Sh AUTHORS +.An Lazaros Koromilas Aq Mt lostd@2f30.org , +.An Dimitris Papastamos Aq Mt sin@2f30.org . @@ -0,0 +1,95 @@ +/* See LICENSE file for copyright and license details. */ +#include <sys/types.h> +#include <sys/wait.h> + +#include <err.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "util.h" + +struct assoc { + char *regex; /* Regex to match on filename */ + char *file; + char *argv[NR_ARGS]; + regex_t regcomp; +}; + +#include "nopenconf.h" + +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); +} + +struct assoc * +openwith(char *file) +{ + int i; + + for (i = 0; i < LEN(assocs); i++) { + if (regexec(&assocs[i].regcomp, file, 0, NULL, 0) == 0) + return &assocs[i]; + } + + return NULL; +} + +void +initassocs(void) +{ + char errbuf[256]; + int i, r; + + for (i = 0; i < LEN(assocs); i++) { + r = regcomp(&assocs[i].regcomp, assocs[i].regex, + REG_NOSUB | REG_EXTENDED | REG_ICASE); + if (r != 0) { + regerror(r, &assocs[i].regcomp, errbuf, sizeof(errbuf)); + fprintf(stderr, "invalid regex assocs[%d]: %s: %s\n", + i, assocs[i].regex, errbuf); + exit(1); + } + } +} + +void +usage(char *argv0) +{ + fprintf(stderr, "usage: %s file...\n", argv0); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + if (argc == 1) + usage(argv[0]); + argc--; + argv++; + initassocs(); + for (; *argv != NULL; argv++) { + struct assoc *assoc; + + assoc = openwith(argv[0]); + if (assoc == NULL) + continue; + spawnassoc(assoc, argv[0]); + } + return 0; +} diff --git a/nopenconf.def.h b/nopenconf.def.h new file mode 100644 index 0000000..58c7569 --- /dev/null +++ b/nopenconf.def.h @@ -0,0 +1,9 @@ +/* See LICENSE file for copyright and license details. */ +struct assoc assocs[] = { + { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv = { "mpv", "{}", NULL } }, + { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}", NULL} }, + { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "{}", NULL } }, + { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} }, + { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} }, + { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } }, +}; @@ -0,0 +1,43 @@ +/* See LICENSE file for copyright and license details. */ +#include <sys/types.h> +#include <sys/wait.h> + +#include <stdarg.h> +#include <unistd.h> + +#include "util.h" + +void +spawnvp(char *dir, char *file, char *argv[]) +{ + pid_t pid; + int status; + + pid = fork(); + if (pid == 0) { + if (dir != NULL) + chdir(dir); + execvp(file, argv); + _exit(1); + } else { + /* Ignore interruptions */ + while (waitpid(pid, &status, 0) == -1) + ; + } +} + +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); +} diff --git a/strverscmp.c b/strverscmp.c index a3628a9..5e28694 100644 --- a/strverscmp.c +++ b/strverscmp.c @@ -1,6 +1,8 @@ +/* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <stdlib.h> #include <string.h> + #include "util.h" int @@ -1,12 +1,6 @@ /* See LICENSE file for copyright and license details. */ -#undef strlcat -size_t strlcat(char *, const char *, size_t); -#undef strlcpy -size_t strlcpy(char *, const char *, size_t); -#undef dprintf -int dprintf(int, const char *, ...); -#undef strverscmp -int strverscmp(const char *, const char *); +#define LEN(x) (sizeof(x) / sizeof(*(x))) +#define NR_ARGS 32 #ifdef DEBUG #define DEBUG_FD 8 @@ -22,3 +16,14 @@ int strverscmp(const char *, const char *); #define DPRINTF_P(x) #define DPRINTF_LLU(x) #endif /* DEBUG */ + +#undef strlcat +size_t strlcat(char *, const char *, size_t); +#undef strlcpy +size_t strlcpy(char *, const char *, size_t); +#undef dprintf +int dprintf(int, const char *, ...); + +int strverscmp(const char *, const char *); +void spawnvp(char *, char *, char *[]); +void spawnlp(char *, char *, char *, ...); |