(Rule[]){ /* Match URLS and open them with the browser */
{ ISSET, "BROWSER", NULL },
{ MATCHES, "data", "^(https?|ftp)://.*" },
- { LAUNCH, "$BROWSER $0", NULL },
+ { LAUNCH, "$BROWSER \"$0\"", NULL },
{ COMPLETE, NULL, NULL }
},
(Rule[]){ /* Open files with addresses in the editor */
- { ISSET, "EDITOR", NULL },
{ MATCHES, "data", "^([^:]+):([0-9]+)" },
{ ISFILE, "$1", NULL },
{ LAUNCH, "edit \"$0\"", NULL },
(Rule[]){ /* If it's an existing text file, open it with editor */
{ ISSET, "EDITOR", NULL },
{ ISFILE, "$data", NULL },
- { EXEC, "file --mime '$file' | grep -q 'text/'", NULL },
- { LAUNCH, "$EDITOR '$file'", NULL },
+ { EXEC, "file --mime \"$file\" | grep -q 'text/'", NULL },
+ { LAUNCH, "edit \"$file\"", NULL },
{ COMPLETE, NULL, NULL }
},
(Rule[]){ /* Look it up in ctags database */
- { ISSET, "EDITOR", NULL },
{ ISFILE, "tags", NULL },
{ EXEC, "grep -q '^$data\\s\\+' tags", NULL },
{ LAUNCH, "picktag fetch tags '$data' | xargs -r edit", NULL },
{ COMPLETE, NULL, NULL }
},
(Rule[]){ /* Look up .c or .h files in Code/ */
- { ISSET, "EDITOR", NULL },
{ MATCHES, "data", "\\.[ch]$" },
{ ISDIR, "Code", NULL },
{ EXEC, "[[ $(find Code -type f -name '*$data') ]]", NULL },
- { LAUNCH, "find Code -type f -name '*$data' | xargs -r $EDITOR", NULL },
+ { LAUNCH, "find Code -type f -name '*$data' | xargs -r edit", NULL },
{ COMPLETE, NULL, NULL }
},
(Rule[]){ /* If it's an existing directory, open it with system default */
#include <unistd.h>
#include <stdc.h>
+#include "config.h"
+
Atom XA_REGISTRAR, XA_OPEN, XA_DONE;
int spawn(char* cmd) {
}
void edit_file(XConf* x, Window registrar, char* path, char* addr) {
- static char wdirbuf[32768] = {0};
- char* wdir = getcwd(wdirbuf, sizeof(wdirbuf));
- if (!wdir) return;
char* rpath = realpath(path, NULL);
- prop_set(x, x->self, "WDIR", wdir);
prop_set(x, x->self, "FILE", (rpath ? rpath : path));
prop_set(x, x->self, "ADDR", addr);
free(rpath);
/* wait for the "done" message */
for (XEvent e;;) {
XNextEvent(x->display, &e);
- if (e.type == ClientMessage && e.xclient.message_type == XA_DONE)
- break;
+ if (e.type == ClientMessage) {
+ if (e.xclient.message_type == XA_DONE) {
+ break;
+ } else if (e.xclient.message_type == XA_OPEN) {
+ if (!fork()) {
+ EditCmd[2] = addr, EditCmd[3] = path;
+ exit(execvp(EditCmd[0], EditCmd));
+ }
+ break;
+ }
+ }
}
}
char* path;
} TWindow;
-Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE, XA_WDIR, XA_FILE, XA_ADDR;
+Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE;
TWindow* Windows = NULL;
-char* readprop(XConf* x, Window win, Atom prop, size_t* length) {
- Atom type;
+char* readprop(XConf* x, Window win, char* prop, size_t* length) {
+ Atom type, xa_prop = XInternAtom(x->display, prop, False);
int format;
unsigned long datalen, nleft;
unsigned char* data = NULL;
XGetWindowProperty(
- x->display, win, prop, 0, -1, True, XA_STRING,
+ x->display, win, xa_prop, 0, -1, True, XA_STRING,
&type, &format, &datalen, &nleft, &data);
if (length) *length = datalen;
return (char*)data;
TWindow* win = calloc(1, sizeof(TWindow));
win->win = id;
win->next = Windows;
- win->path = readprop(x, id, XA_FILE, 0);
+ win->path = readprop(x, id, "FILE", 0);
Windows = win;
}
XFlush(x->display);
}
-void win_open(XConf* x, char* wdir, char* path, char* addr) {
+void win_open(XConf* x, Window winid, char* path, char* addr) {
if (!path) return;
/* search for an existing window */
for (TWindow* win = Windows; win; win = win->next) {
win_send(x, win->win, x->root, SubstructureRedirectMask|SubstructureNotifyMask, "_NET_ACTIVE_WINDOW", 0);
XMapRaised(x->display, win->win);
win_send(x, x->self, win->win, 0, "GOTO", strtoul(addr, NULL, 0));
+ win_send(x, x->self, winid, 0, "DONE", 0);
return;
}
}
- /* if we don't find it, spawn a new one */
- if (!fork()) {
- if (wdir) chdir(wdir);
- EditCmd[2] = addr, EditCmd[3] = path;
- exit(execvp(EditCmd[0], EditCmd));
- }
+ /* if we don't find it, tell sender to spawn a new one */
+ win_send(x, x->self, winid, 0, "OPEN", 0);
}
void selclear(XConf* x, XEvent* e) {
x->display, x->self, XA_OPEN, 0, -1, True, XA_WINDOW,
&type, &format, &datalen, &nleft, &data);
for (Window* win = (Window*)data; datalen && win && *win; win++, datalen--) {
- char* wdir = readprop(x, *win, XA_WDIR, NULL);
- char* file = readprop(x, *win, XA_FILE, NULL);
- char* addr = readprop(x, *win, XA_ADDR, NULL);
- win_open(x, wdir, file, (addr ? addr : "0"));
- win_send(x, x->self, *win, 0, "DONE", 0);
- if(wdir) XFree(wdir);
+ char* file = readprop(x, *win, "FILE", NULL);
+ char* addr = readprop(x, *win, "ADDR", NULL);
+ win_open(x, *win, file, (addr ? addr : "0"));
if(file) XFree(file);
if(addr) XFree(addr);
}
XA_DEL = XInternAtom(x.display, "DEL", 0);
XA_OPEN = XInternAtom(x.display, "OPEN", 0);
XA_DONE = XInternAtom(x.display, "DONE", 0);
- XA_WDIR = XInternAtom(x.display, "WDIR", 0);
- XA_FILE = XInternAtom(x.display, "FILE", 0);
- XA_ADDR = XInternAtom(x.display, "ADDR", 0);
x.eventfns[SelectionClear] = selclear;
x.eventfns[ClientMessage] = clientmsg;
x.eventfns[PropertyNotify] = propnotify;