-r to restrict input to actual options

This commit is contained in:
Luke Smith 2020-04-18 09:59:37 -04:00
parent ef9e3d2439
commit 96608c36b5
No known key found for this signature in database
GPG key ID: 4C50B54A911F6252
3 changed files with 25 additions and 2 deletions

View file

@ -5,6 +5,9 @@ Extra stuff added to vanilla dmenu:
- reads Xresources (ergo pywal compatible) - reads Xresources (ergo pywal compatible)
- alpha patch, which importantly allows this build to be embedded in transparent st - alpha patch, which importantly allows this build to be embedded in transparent st
- can view color characters like emoji (libxft-bgra is required for this reason) - can view color characters like emoji (libxft-bgra is required for this reason)
- `-P` for password mode: hide user imput
- `-r` to reject non-matching input
- dmenu options are mouse clickable
## Installation ## Installation

View file

@ -3,7 +3,7 @@
dmenu \- dynamic menu dmenu \- dynamic menu
.SH SYNOPSIS .SH SYNOPSIS
.B dmenu .B dmenu
.RB [ \-bfivP ] .RB [ \-bfirvP ]
.RB [ \-l .RB [ \-l
.IR lines ] .IR lines ]
.RB [ \-m .RB [ \-m
@ -50,6 +50,9 @@ dmenu matches menu items case insensitively.
.B \-P .B \-P
dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored. dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
.TP .TP
.B \-r
dmenu will reject any input which would result in no matching option left.
.TP
.BI \-l " lines" .BI \-l " lines"
dmenu lists items vertically, with the given number of lines. dmenu lists items vertically, with the given number of lines.
.TP .TP

19
dmenu.c
View file

@ -43,6 +43,7 @@ static char *embed;
static int bh, mw, mh; static int bh, mw, mh;
static int inputw = 0, promptw, passwd = 0; static int inputw = 0, promptw, passwd = 0;
static int lrpad; /* sum of left and right padding */ static int lrpad; /* sum of left and right padding */
static int reject_no_match = 0;
static size_t cursor; static size_t cursor;
static struct item *items = NULL; static struct item *items = NULL;
static struct item *matches, *matchend; static struct item *matches, *matchend;
@ -323,12 +324,26 @@ insert(const char *str, ssize_t n)
{ {
if (strlen(text) + n > sizeof text - 1) if (strlen(text) + n > sizeof text - 1)
return; return;
static char last[BUFSIZ] = "";
if(reject_no_match) {
/* store last text value in case we need to revert it */
memcpy(last, text, BUFSIZ);
}
/* move existing text out of the way, insert new text, and update cursor */ /* move existing text out of the way, insert new text, and update cursor */
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
if (n > 0) if (n > 0)
memcpy(&text[cursor], str, n); memcpy(&text[cursor], str, n);
cursor += n; cursor += n;
match(); match();
if(!matches && reject_no_match) {
/* revert to last text value if theres no match */
memcpy(text, last, BUFSIZ);
cursor -= n;
match();
}
} }
static size_t static size_t
@ -860,7 +875,7 @@ setup(void)
static void static void
usage(void) usage(void)
{ {
fputs("usage: dmenu [-bfiPv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" fputs("usage: dmenu [-bfiPrv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
exit(1); exit(1);
} }
@ -910,6 +925,8 @@ main(int argc, char *argv[])
fstrstr = cistrstr; fstrstr = cistrstr;
} else if (!strcmp(argv[i], "-P")) /* is the input a password */ } else if (!strcmp(argv[i], "-P")) /* is the input a password */
passwd = 1; passwd = 1;
else if (!strcmp(argv[i], "-r")) /* reject input which results in no match */
reject_no_match = 1;
else if (i + 1 == argc) else if (i + 1 == argc)
usage(); usage();
/* these options take one argument */ /* these options take one argument */