Commit Diff


commit - 889512811d7ae410eb4ab60be3568278b3e23f2e
commit + e2a280541eab62717d6a9a72d047c832e5cb1edc
blob - 9eab758ca5b51a6b5ca1fc81d5ab095a1e3fde27
blob + fbb3f761b0c5a63bc705b4999174d8a8f543621d
--- dmenu.1
+++ dmenu.1
@@ -100,6 +100,12 @@ Confirm input.  Prints the input text to stdout and ex
 .B Escape
 Exit without selecting an item, returning failure.
 .TP
+.B Ctrl-Left
+Move cursor to the start of the current word
+.TP
+.B Ctrl-Right
+Move cursor to the end of the current word
+.TP
 C\-a
 Home
 .TP
@@ -160,6 +166,12 @@ Paste from primary X selection
 C\-Y
 Paste from X clipboard
 .TP
+M\-b
+Move cursor to the start of the current word
+.TP
+M\-f
+Move cursor to the end of the current word
+.TP
 M\-g
 Home
 .TP
blob - a2461115ec253a051d2f3438890eb7944ffe2ccf
blob + 5e9c36735152d883d00df4cc21eaad5b3172ce40
--- dmenu.c
+++ dmenu.c
@@ -288,6 +288,22 @@ nextrune(int inc)
 }
 
 static void
+movewordedge(int dir)
+{
+	if (dir < 0) { /* move cursor to the start of the word*/
+		while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
+			cursor = nextrune(-1);
+		while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
+			cursor = nextrune(-1);
+	} else { /* move cursor to the end of the word */
+		while (text[cursor] && strchr(worddelimiters, text[cursor]))
+			cursor = nextrune(+1);
+		while (text[cursor] && !strchr(worddelimiters, text[cursor]))
+			cursor = nextrune(+1);
+	}
+}
+
+static void
 keypress(XKeyEvent *ev)
 {
 	char buf[32];
@@ -334,6 +350,14 @@ keypress(XKeyEvent *ev)
 			XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
 			                  utf8, utf8, win, CurrentTime);
 			return;
+		case XK_Left:
+			movewordedge(-1);
+			ksym = NoSymbol;
+			break;
+		case XK_Right:
+			movewordedge(+1);
+			ksym = NoSymbol;
+			break;
 		case XK_Return:
 		case XK_KP_Enter:
 			break;
@@ -345,6 +369,14 @@ keypress(XKeyEvent *ev)
 		}
 	else if (ev->state & Mod1Mask)
 		switch(ksym) {
+		case XK_b:
+			movewordedge(-1);
+			ksym = NoSymbol;
+			break;
+		case XK_f:
+			movewordedge(+1);
+			ksym = NoSymbol;
+			break;
 		case XK_g: ksym = XK_Home;  break;
 		case XK_G: ksym = XK_End;   break;
 		case XK_h: ksym = XK_Up;    break;
@@ -359,6 +391,8 @@ keypress(XKeyEvent *ev)
 		if (!iscntrl(*buf))
 			insert(buf, len);
 		break;
+	case NoSymbol:
+		break;
 	case XK_Delete:
 		if (text[cursor] == '\0')
 			return;