commit 089bf7bba73d942a750de55a5be8569be9fd6710
parent a6df12242456734d736730960dc310905af779ab
Author: Kris Maglione <kris@suckless.org>
Date: Thu, 7 Oct 2010 16:31:42 -0400
[wimenu] Add paste key binding.
Diffstat:
15 files changed, 270 insertions(+), 48 deletions(-)
diff --git a/cmd/menu/Makefile b/cmd/menu/Makefile
@@ -11,7 +11,7 @@ bindings.c: keys.txt Makefile
TARG = wimenu
HFILES= dat.h fns.h
-TAGFILES= dat.h
+TAGFILES= dat.h $(ROOT)/include/*.h $(ROOT)/include/stuff/*.h
PACKAGES += $(X11PACKAGES)
diff --git a/cmd/menu/dat.h b/cmd/menu/dat.h
@@ -38,6 +38,7 @@ enum {
LLITERAL,
LNEXT,
LNEXTPAGE,
+ LPASTE,
LPREV,
LPREVPAGE,
LREJECT,
diff --git a/cmd/menu/keys.c b/cmd/menu/keys.c
@@ -84,6 +84,7 @@ char *symtab[] = {
"literal",
"next",
"nextpage",
+ "paste",
"prev",
"prevpage",
"reject",
diff --git a/cmd/menu/keys.txt b/cmd/menu/keys.txt
@@ -1,49 +1,51 @@
-Control-j Accept
-Control-m Accept
-Return Accept
-Control-Shift-j Accept literal
-Control-Shift-m Accept literal
-Shift-Return Accept literal
+Control-j Accept
+Control-m Accept
+Return Accept
+Control-Shift-j Accept literal
+Control-Shift-m Accept literal
+Shift-Return Accept literal
Escape Reject
Control-Bracketleft Reject
-Left Backward char
-Control-b Backward char
-Right Forward char
-Control-f Forward char
-
-Mod1-b Backward word
-Mod1-f Forward word
-
-Control-a Backward line
-Control-e Forward line
-
-Control-p History backward
-Up History backward
-Control-n History forward
-Down History forward
-
-Backspace Kill char
-Control-h Kill char
-Control-Backspace Kill word
-Control-w Kill word
-Control-u Kill line
-
-Tab Complete next
-Control-i Complete next
-Mod1-l Complete next
-
-Shift-Tab Complete prev
-Control-Shift-i Complete prev
-Mod1-h Complete prev
-
-Prior Complete prevpage
-Mod1-k Complete prevpage
-Next Complete nextpage
-Mod1-j Complete nextpage
-Home Complete first
-Mod1-g Complete first
-End Complete last
-Mod1-Shift-g Complete last
+Left Backward char
+Control-b Backward char
+Right Forward char
+Control-f Forward char
+
+Mod1-b Backward word
+Mod1-f Forward word
+
+Control-a Backward line
+Control-e Forward line
+
+Control-p History backward
+Up History backward
+Control-n History forward
+Down History forward
+
+Backspace Kill char
+Control-h Kill char
+Control-Backspace Kill word
+Control-w Kill word
+Control-u Kill line
+
+Tab Complete next
+Control-i Complete next
+Mod1-l Complete next
+
+Mod1-p Paste PRIMARY
+
+Shift-Tab Complete prev
+Control-Shift-i Complete prev
+Mod1-h Complete prev
+
+Prior Complete prevpage
+Mod1-k Complete prevpage
+Next Complete nextpage
+Mod1-j Complete nextpage
+Home Complete first
+Mod1-g Complete first
+End Complete last
+Mod1-Shift-g Complete last
diff --git a/cmd/menu/main.c b/cmd/menu/main.c
@@ -172,6 +172,11 @@ init_screens(void) {
menu_show();
}
+ErrorCode ignored_xerrors[] = {
+ { 0, BadWindow },
+ { X_GetAtomName, BadAtom },
+};
+
int
main(int argc, char *argv[]) {
static char *address;
diff --git a/cmd/menu/menu.c b/cmd/menu/menu.c
@@ -213,6 +213,13 @@ selectitem(Item *i) {
}
}
+static void
+paste(void *aux, char *str) {
+ if(str)
+ caret_insert(str, false);
+ menu_draw();
+}
+
static bool
kdown_event(Window *w, void *aux, XKeyEvent *e) {
char **action, **p;
@@ -321,6 +328,9 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) {
caret_move(FORWARD, amount);
update_input();
break;
+ case LPASTE:
+ getselection(action[1] ? action[1] : "PRIMARY", paste, nil);
+ break;
case LREJECT:
srv.running = false;
result = 1;
diff --git a/include/stuff/x11.h b/include/stuff/x11.h
@@ -277,6 +277,7 @@ ulong getproperty(Window*, char *prop, char *type, Atom *actual, ulong offset, u
Rectangle getwinrect(Window*);
int grabkeyboard(Window*);
int grabpointer(Window*, Window *confine, Cursor, int mask);
+void getselection(char*, void (*)(void*, char*), void*);
bool havexft(void);
void initdisplay(void);
KeyCode keycode(const char*);
diff --git a/lib/libstuff/Makefile b/lib/libstuff/Makefile
@@ -96,6 +96,7 @@ OBJ=\
x11/ignored_xerrors \
x11/freestringlist \
x11/initdisplay \
+ x11/selection \
x11/sendevent \
x11/sendmessage \
x11/sync \
diff --git a/lib/libstuff/x11/selection.c b/lib/libstuff/x11/selection.c
@@ -0,0 +1,63 @@
+/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
+ * See LICENSE file for license details.
+ */
+#include "x11.h"
+
+static Handlers handlers;
+
+typedef struct Data Data;
+
+struct Data {
+ long selection;
+ void (*callback)(void*, char*);
+ void* aux;
+};
+
+static bool
+_getselection(Window *w, long selection, char *type) {
+ XConvertSelection(display, selection, xatom(type),
+ selection, w->xid, CurrentTime);
+ return true;
+}
+
+void
+getselection(char *selection, void (*callback)(void*, char*), void *aux) {
+ Window *w;
+ Data *d;
+
+ d = emallocz(sizeof *d);
+ d->selection = xatom(selection);
+ d->callback = callback;
+ d->aux = aux;
+
+ w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, nil, 0);
+ w->aux = d;
+ sethandler(w, &handlers);
+
+ _getselection(w, d->selection, "UTF8_STRING");
+}
+
+static bool
+selection_event(Window *w, void *aux, XSelectionEvent *ev) {
+ Data *d;
+ char **ret;
+
+ d = aux;
+ if(ev->property == None && ev->target != xatom("STRING"))
+ return _getselection(w, d->selection, "STRING");
+ else if(ev->property == None)
+ d->callback(d->aux, nil);
+ else {
+ getprop_textlist(w, atomname(ev->property), &ret);
+ delproperty(w, atomname(ev->property));
+ d->callback(d->aux, ret ? *ret : nil);
+ free(ret);
+ }
+ destroywindow(w);
+ return false;
+}
+
+static Handlers handlers = {
+ .selection = selection_event,
+};
+
diff --git a/lib/libstuff/x11/xatom.c b/lib/libstuff/x11/xatom.c
@@ -24,7 +24,7 @@ atomname(ulong atom) {
e = map_get(&atomnamemap, atom, true);
if(*e == nil) {
*e = XGetAtomName(display, atom);
- if(&e == nil) {
+ if(*e == nil) {
map_rm(&atomnamemap, atom);
return nil;
}
diff --git a/man/wimenu.1 b/man/wimenu.1
@@ -85,6 +85,84 @@ as a menu option, and the text to the right is displayed when a
selection is made.
.RE
+.SH KEY BINDINGS
+.P
+\fBwimenu\fR's default key bindings are based largely on the
+movement keys of vi and the standard UNIX shell input bindings.
+
+.TP
+Return, C\-j, C\-m
+Accept the input, and select the first matching
+completion if the cursor is at the end of the input.
+.TP
+S\-Return, C\-S\-j, C\-S\-m
+Accept the input literally.
+.TP
+Esc, C\-[
+Quit without returning any output, and exit with
+non\-zero status.
+
+.TP
+A\-p
+Paste the PRIMARY selection.
+
+.TP
+Left, C\-b
+Move backward one character.
+.TP
+Right, C\-f
+Move forward one character.
+
+.TP
+A\-b
+Move backward one word.
+.TP
+A\-f
+Move forward one word.
+
+.TP
+C\-a
+Move to the begining of the line.
+.TP
+C\-e
+Move to the end of the line.
+
+.TP
+C\-p, up
+Move backward through the input history.
+.TP
+C\-n, up
+Move forward through the input history.
+
+.TP
+Backspace, C\-h
+Delete the previous character.
+.TP
+C\-Backspace, C\-w
+Delete the previous word.
+.TP
+C\-u
+Delete the previous portion of the line.
+
+.TP
+Tab, C\-i¸ A\-l
+Select the next completion.
+.TP
+S\-Tab, C\-S\-i, A\-h
+Select the previous completion.
+.TP
+PageUp, A\-k
+Select the previous completion page.
+.TP
+PageDown, A\-j
+Select the next completion page.
+.TP
+Home, A\-g
+Select the first completion page.
+.TP
+End, A\-S\-g
+Select the last completion page.
+
.SH CUSTOM COMPLETION
.P
Custom, multipart completion data may be proveded by an
diff --git a/man/wimenu.man1 b/man/wimenu.man1
@@ -76,6 +76,63 @@ following. More advanced options are documented below.
as a menu option, and the text to the right is displayed when a
selection is made.
+= KEY BINDINGS =
+
+`wimenu`'s default key bindings are based largely on the
+movement keys of vi and the standard UNIX shell input bindings.
+
+: Return, C-j, C-m
+ Accept the input, and select the first matching
+ completion if the cursor is at the end of the input.
+: S-Return, C-S-j, C-S-m
+ Accept the input literally.
+: Esc, C-[
+ Quit without returning any output, and exit with
+ non-zero status.
+
+: A-p
+ Paste the PRIMARY selection.
+
+: Left, C-b
+ Move backward one character.
+: Right, C-f
+ Move forward one character.
+
+: A-b
+ Move backward one word.
+: A-f
+ Move forward one word.
+
+: C-a
+ Move to the begining of the line.
+: C-e
+ Move to the end of the line.
+
+: C-p, Up
+ Move backward through the input history.
+: C-n, Down
+ Move forward through the input history.
+
+: Backspace, C-h
+ Delete the previous character.
+: C-Backspace, C-w
+ Delete the previous word.
+: C-u
+ Delete the previous portion of the line.
+
+: Tab, C-i¸ A-l
+ Select the next completion.
+: S-Tab, C-S-i, A-h
+ Select the previous completion.
+: PageUp, A-k
+ Select the previous completion page.
+: PageDown, A-j
+ Select the next completion page.
+: Home, A-g
+ Select the first completion page.
+: End, A-S-g
+ Select the last completion page.
+:
= CUSTOM COMPLETION =
Custom, multipart completion data may be proveded by an
diff --git a/mk/common.mk b/mk/common.mk
@@ -42,7 +42,7 @@ tags:
[ -f "$$f.c" ] && files="$$files $$f.c"; \
done; \
echo CTAGS $$files $(TAGFILES); \
- $(DEBUG) $(CTAGS) $$files $(TAGFILES)
+ if [ -n "$$files" ]; then $(DEBUG) $(CTAGS) $$files $(TAGFILES); fi
.PHONY: all options clean dist install uninstall depend cleandep tags
.PHONY: simpleuninstall simpleinstall
diff --git a/mk/dir.mk b/mk/dir.mk
@@ -21,12 +21,15 @@ duninstall:
+dirs="$(INSTDIRS)"; $(MKSUBDIR)
ddepend:
+dirs="$(DIRS)"; $(MKSUBDIR)
+dtags:
+ +dirs="$(DIRS)"; $(MKSUBDIR)
all: dall
clean: dclean
install: dinstall
uninstall: duninstall
depend: ddepend
+tags: dtags
INSTDIRS = $(DIRS)
diff --git a/mk/hdr.mk b/mk/hdr.mk
@@ -34,7 +34,7 @@ CLEANNAME=$(SHELL) $(ROOT)/util/cleanname
SOEXT=so
TAGFILES=
-CTAGS=ctags
+CTAGS=ctags --fields=+S --c-kinds=+px
PACKAGES =