diff options
-rw-r--r-- | dmenu.1 | 46 | ||||
-rw-r--r-- | dmenu.c | 84 |
2 files changed, 59 insertions, 71 deletions
@@ -14,12 +14,22 @@ dmenu \- dynamic menu | |||
14 | .RB [ \-sb " <color>]" | 14 | .RB [ \-sb " <color>]" |
15 | .RB [ \-sf " <color>]" | 15 | .RB [ \-sf " <color>]" |
16 | .RB [ \-v ] | 16 | .RB [ \-v ] |
17 | |||
18 | .B dmenu_run | ||
19 | [<options...>] | ||
20 | |||
21 | .BR dmenu_path | ||
17 | .SH DESCRIPTION | 22 | .SH DESCRIPTION |
18 | .SS Overview | 23 | .SS Overview |
19 | dmenu is a generic menu for X, originally designed for | 24 | dmenu is a generic menu for X, originally designed for |
20 | .BR dwm (1). | 25 | .BR dwm (1). |
21 | It manages huge amounts (up to 10.000 and more) of user defined menu items | 26 | It manages huge amounts (up to 10.000 and more) of user defined menu items |
22 | efficiently. | 27 | efficiently. |
28 | |||
29 | dmenu_run is a dmenu script used by dwm which lists executables in the user's PATH | ||
30 | and executes the selected item. | ||
31 | |||
32 | dmenu_path is a script used by dmenu_run to find and cache a list of executables. | ||
23 | .SS Options | 33 | .SS Options |
24 | .TP | 34 | .TP |
25 | .B \-i | 35 | .B \-i |
@@ -33,7 +43,7 @@ reparents dmenu to the window specified by xid. | |||
33 | .TP | 43 | .TP |
34 | .B \-l <lines> | 44 | .B \-l <lines> |
35 | activates vertical list mode. | 45 | activates vertical list mode. |
36 | The given number of lines will be displayed. Window height will get adjusted. | 46 | The given number of lines will be displayed. Window height will be adjusted. |
37 | .TP | 47 | .TP |
38 | .B \-fn <font> | 48 | .B \-fn <font> |
39 | defines the font. | 49 | defines the font. |
@@ -60,20 +70,9 @@ dmenu reads a list of newline-separated items from standard input and creates a | |||
60 | menu. When the user selects an item or enters any text and presses Return, his/her | 70 | menu. When the user selects an item or enters any text and presses Return, his/her |
61 | choice is printed to standard output and dmenu terminates. | 71 | choice is printed to standard output and dmenu terminates. |
62 | .P | 72 | .P |
63 | dmenu is completely controlled by the keyboard. The following keys are recognized: | 73 | dmenu is completely controlled by the keyboard. Besides standard Unix line editing, |
64 | .TP | 74 | and item selection (Up/Down or Left/Right, PageUp/PageDown, Home/End), the following |
65 | .B Any printable character | 75 | keys are recognized: |
66 | Appends the character to the text in the input field. This works as a filter: | ||
67 | only items containing this text will be displayed. | ||
68 | .TP | ||
69 | .B Left/Right (Up/Down) (Mod1\-h/Mod1\-l) | ||
70 | Select the previous/next item. | ||
71 | .TP | ||
72 | .B PageUp/PageDown (Mod1\-k/Mod1\-j) | ||
73 | Select the first item of the previous/next 'page' of items. | ||
74 | .TP | ||
75 | .B Home/End (Mod1\-g/Mod1\-G) | ||
76 | Select the first/last item. | ||
77 | .TP | 76 | .TP |
78 | .B Tab (Control\-i) | 77 | .B Tab (Control\-i) |
79 | Copy the selected item to the input field. | 78 | Copy the selected item to the input field. |
@@ -84,24 +83,19 @@ Confirm selection and quit (print the selected item to standard output). Returns | |||
84 | on termination. | 83 | on termination. |
85 | .TP | 84 | .TP |
86 | .B Shift\-Return (Control\-Shift\-j) | 85 | .B Shift\-Return (Control\-Shift\-j) |
87 | Confirm selection and quit (print the text in the input field to standard output). | 86 | Confirm input and quit (print the text in the input field to standard output). |
88 | Returns | 87 | Returns |
89 | .B 0 | 88 | .B 0 |
90 | on termination. | 89 | on termination. |
91 | .TP | 90 | .TP |
92 | .B Escape (Control\-bracketleft) | 91 | .B Escape (Control\-c) |
93 | Quit without selecting an item. Returns | 92 | Quit without selecting an item. Returns |
94 | .B 1 | 93 | .B 1 |
95 | on termination. | 94 | on termination. |
96 | .TP | 95 | .TP |
97 | .B Backspace (Control\-h) | 96 | .B Control\-y |
98 | Remove a character from the input field. | 97 | Pastes the X selection into the input field. This requires |
99 | .TP | 98 | .BR sselp (1). |
100 | .B Control\-u | ||
101 | Remove all characters from the input field. | ||
102 | .TP | ||
103 | .B Control\-w | ||
104 | Remove all characters of current word from the input field. | ||
105 | .SH SEE ALSO | 99 | .SH SEE ALSO |
106 | .BR dwm (1), | 100 | .BR dwm (1), |
107 | .BR wmii (1) . | 101 | .BR wmii (1). |
@@ -355,17 +355,23 @@ kpress(XKeyEvent * e) { | |||
355 | /* first check if a control mask is omitted */ | 355 | /* first check if a control mask is omitted */ |
356 | if(e->state & ControlMask) { | 356 | if(e->state & ControlMask) { |
357 | switch(tolower(ksym)) { | 357 | switch(tolower(ksym)) { |
358 | default: /* ignore other control sequences */ | 358 | default: |
359 | return; | 359 | return; |
360 | case XK_a: | 360 | case XK_a: |
361 | ksym = XK_Home; | 361 | ksym = XK_Home; |
362 | break; | 362 | break; |
363 | case XK_b: | ||
364 | ksym = XK_Left; | ||
365 | break; | ||
363 | case XK_c: | 366 | case XK_c: |
364 | ksym = XK_Escape; | 367 | ksym = XK_Escape; |
365 | break; | 368 | break; |
366 | case XK_e: | 369 | case XK_e: |
367 | ksym = XK_End; | 370 | ksym = XK_End; |
368 | break; | 371 | break; |
372 | case XK_f: | ||
373 | ksym = XK_Right; | ||
374 | break; | ||
369 | case XK_h: | 375 | case XK_h: |
370 | ksym = XK_BackSpace; | 376 | ksym = XK_BackSpace; |
371 | break; | 377 | break; |
@@ -378,6 +384,12 @@ kpress(XKeyEvent * e) { | |||
378 | case XK_k: | 384 | case XK_k: |
379 | text[cursor] = '\0'; | 385 | text[cursor] = '\0'; |
380 | break; | 386 | break; |
387 | case XK_n: | ||
388 | ksym = XK_Down; | ||
389 | break; | ||
390 | case XK_p: | ||
391 | ksym = XK_Up; | ||
392 | break; | ||
381 | case XK_u: | 393 | case XK_u: |
382 | memmove(text, text + cursor, sizeof text - cursor + 1); | 394 | memmove(text, text + cursor, sizeof text - cursor + 1); |
383 | cursor = 0; | 395 | cursor = 0; |
@@ -393,31 +405,7 @@ kpress(XKeyEvent * e) { | |||
393 | match(text); | 405 | match(text); |
394 | } | 406 | } |
395 | break; | 407 | break; |
396 | } | 408 | case XK_y: |
397 | } | ||
398 | if(CLEANMASK(e->state) & Mod1Mask) { | ||
399 | switch(ksym) { | ||
400 | default: | ||
401 | return; | ||
402 | case XK_h: | ||
403 | ksym = XK_Left; | ||
404 | break; | ||
405 | case XK_l: | ||
406 | ksym = XK_Right; | ||
407 | break; | ||
408 | case XK_j: | ||
409 | ksym = XK_Next; | ||
410 | break; | ||
411 | case XK_k: | ||
412 | ksym = XK_Prior; | ||
413 | break; | ||
414 | case XK_g: | ||
415 | ksym = XK_Home; | ||
416 | break; | ||
417 | case XK_G: | ||
418 | ksym = XK_End; | ||
419 | break; | ||
420 | case XK_p: | ||
421 | { | 409 | { |
422 | FILE *fp; | 410 | FILE *fp; |
423 | char *s; | 411 | char *s; |
@@ -453,6 +441,8 @@ kpress(XKeyEvent * e) { | |||
453 | match(text); | 441 | match(text); |
454 | break; | 442 | break; |
455 | case XK_Delete: | 443 | case XK_Delete: |
444 | if(cursor == len) | ||
445 | return; | ||
456 | for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); | 446 | for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); |
457 | memmove(text + cursor, text + cursor + i, sizeof text - cursor); | 447 | memmove(text + cursor, text + cursor + i, sizeof text - cursor); |
458 | match(text); | 448 | match(text); |
@@ -482,18 +472,20 @@ kpress(XKeyEvent * e) { | |||
482 | calcoffsets(); | 472 | calcoffsets(); |
483 | break; | 473 | break; |
484 | case XK_Left: | 474 | case XK_Left: |
485 | case XK_Up: | 475 | if(cursor > 0 && (!sel || !sel->left)) { |
486 | if(sel && sel->left){ | ||
487 | sel = sel->left; | ||
488 | if(sel->right == curr) { | ||
489 | curr = prev; | ||
490 | calcoffsets(); | ||
491 | } | ||
492 | } | ||
493 | else if(cursor > 0) | ||
494 | while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); | 476 | while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); |
495 | else | 477 | break; |
478 | } | ||
479 | if(lines > 0) | ||
496 | return; | 480 | return; |
481 | case XK_Up: | ||
482 | if(!sel || !sel->left) | ||
483 | return; | ||
484 | sel = sel->left; | ||
485 | if(sel->right == curr) { | ||
486 | curr = prev; | ||
487 | calcoffsets(); | ||
488 | } | ||
497 | break; | 489 | break; |
498 | case XK_Next: | 490 | case XK_Next: |
499 | if(!next) | 491 | if(!next) |
@@ -516,18 +508,20 @@ kpress(XKeyEvent * e) { | |||
516 | running = False; | 508 | running = False; |
517 | return; | 509 | return; |
518 | case XK_Right: | 510 | case XK_Right: |
519 | case XK_Down: | 511 | if(cursor < len) { |
520 | if(cursor < len) | ||
521 | while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); | 512 | while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); |
522 | else if(sel && sel->right) { | 513 | break; |
523 | sel = sel->right; | ||
524 | if(sel == next) { | ||
525 | curr = next; | ||
526 | calcoffsets(); | ||
527 | } | ||
528 | } | 514 | } |
529 | else | 515 | if(lines > 0) |
516 | return; | ||
517 | case XK_Down: | ||
518 | if(!sel || !sel->right) | ||
530 | return; | 519 | return; |
520 | sel = sel->right; | ||
521 | if(sel == next) { | ||
522 | curr = next; | ||
523 | calcoffsets(); | ||
524 | } | ||
531 | break; | 525 | break; |
532 | case XK_Tab: | 526 | case XK_Tab: |
533 | if(!sel) | 527 | if(!sel) |