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) | 
