aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsin <sin@2f30.org>2019-08-02 15:43:07 +0100
committersin <sin@2f30.org>2019-08-03 22:28:36 +0100
commit50592339bf450037972b85777d1c524e35545aa8 (patch)
treedc1fcea3d52e382b37f50c45d16cb9dc9b5a8036
parent47d659c5fc930f0815c2bf5a24b3c2228b13695e (diff)
downloadnoice-50592339bf450037972b85777d1c524e35545aa8.tar.gz
Implement nopen(1)
-rw-r--r--Makefile48
-rw-r--r--noice.124
-rw-r--r--noice.c113
-rw-r--r--noiceconf.def.h (renamed from config.def.h)9
-rw-r--r--nopen.131
-rw-r--r--nopen.c95
-rw-r--r--nopenconf.def.h9
-rw-r--r--spawn.c43
-rw-r--r--strverscmp.c2
-rw-r--r--util.h21
10 files changed, 234 insertions, 161 deletions
diff --git a/Makefile b/Makefile
index a9ad868..67efb04 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/noice.1 b/noice.1
index c60f09b..2aa6873 100644
--- a/noice.1
+++ b/noice.1
@@ -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 .
diff --git a/noice.c b/noice.c
index 5379631..ba23f9d 100644
--- a/noice.c
+++ b/noice.c
@@ -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 },
diff --git a/nopen.1 b/nopen.1
new file mode 100644
index 0000000..8d2583a
--- /dev/null
+++ b/nopen.1
@@ -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 .
diff --git a/nopen.c b/nopen.c
new file mode 100644
index 0000000..da5769a
--- /dev/null
+++ b/nopen.c
@@ -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 } },
+};
diff --git a/spawn.c b/spawn.c
new file mode 100644
index 0000000..614ab64
--- /dev/null
+++ b/spawn.c
@@ -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
diff --git a/util.h b/util.h
index 9b564f1..f80dc89 100644
--- a/util.h
+++ b/util.h
@@ -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 *, ...);
Un proyecto texto-plano.xyz