diff --git a/LICENSE b/LICENSE index 3afd28e..2a64b28 100644 --- a/LICENSE +++ b/LICENSE @@ -8,7 +8,7 @@ MIT/X Consortium License © 2009 Markus Schnalke © 2009 Evan Gates © 2010-2012 Connor Lane Smith -© 2014-2020 Hiltjo Posthuma +© 2014-2022 Hiltjo Posthuma © 2015-2019 Quentin Rameau Permission is hereby granted, free of charge, to any person obtaining a diff --git a/config.def.h b/config.def.h index 298e91a..1edb647 100644 --- a/config.def.h +++ b/config.def.h @@ -2,25 +2,16 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ - /* -fn option overrides fonts[0]; default X11 font or font set */ -static char font[] = "monospace:size=10"; static const char *fonts[] = { - font, - "monospace:size=10", + "monospace:size=10" }; - -static char *prompt = NULL; /* -p option; prompt to the left of input field */ - -static char normfgcolor[] = "#bbbbbb"; -static char normbgcolor[] = "#222222"; -static char selfgcolor[] = "#eeeeee"; -static char selbgcolor[] = "#005577"; -static char *colors[SchemeLast][2] = { +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +static const char *colors[SchemeLast][2] = { /* fg bg */ - [SchemeNorm] = { normfgcolor, normbgcolor }, - [SchemeSel] = { selfgcolor, selbgcolor }, - [SchemeOut] = { "#000000", "#00ffff" }, + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, }; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; @@ -30,15 +21,3 @@ static unsigned int lines = 0; * for example: " /?\"&[]" */ static const char worddelimiters[] = " "; - -/* - * Xresources preferences to load at startup - */ -ResourcePref resources[] = { - { "font", STRING, &font }, - { "normfgcolor", STRING, &normfgcolor }, - { "normbgcolor", STRING, &normbgcolor }, - { "selfgcolor", STRING, &selfgcolor }, - { "selbgcolor", STRING, &selbgcolor }, - { "prompt", STRING, &prompt }, -}; diff --git a/config.h b/config.h index 31bb652..d781fc5 100644 --- a/config.h +++ b/config.h @@ -1,27 +1,19 @@ /* See LICENSE file for copyright and license details. */ /* Default settings; can be overriden by command line. */ -static int topbar = 0; /* -b option; if 0, dmenu appears at bottom */ - +static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ /* -fn option overrides fonts[0]; default X11 font or font set */ -static char font[] = "Iosevka:pixelsize=14:antialias=true:autohint=true"; static const char *fonts[] = { - font, - "Iosevka:pixelsize=14:antialias=true:autohint=true", + "Iosevka:pixelsize=14:antialias=true:autohint=true" }; - -static char *prompt = NULL; /* -p option; prompt to the left of input field */ - -static char normfgcolor[] = "#D6DEEB"; -static char normbgcolor[] = "#121317"; -static char selfgcolor[] = "#D6DEEB"; -static char selbgcolor[] = "#313439"; -static char *colors[SchemeLast][2] = { +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +#include "/home/spy/cols/dmenu.h" +//static const char *colors[SchemeLast][2] = { /* fg bg */ - [SchemeNorm] = { normfgcolor, normbgcolor }, - [SchemeSel] = { selfgcolor, selbgcolor }, - [SchemeOut] = { "#000000", "#00ffff" }, -}; +// [SchemeNorm] = { "#bbbbbb", "#222222" }, +// [SchemeSel] = { "#eeeeee", "#005577" }, +// [SchemeOut] = { "#000000", "#00ffff" }, +//}; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; @@ -30,15 +22,3 @@ static unsigned int lines = 0; * for example: " /?\"&[]" */ static const char worddelimiters[] = " "; - -/* - * Xresources preferences to load at startup - */ -ResourcePref resources[] = { - { "font", STRING, &font }, - { "normfgcolor", STRING, &normfgcolor }, - { "normbgcolor", STRING, &normbgcolor }, - { "selfgcolor", STRING, &selfgcolor }, - { "selbgcolor", STRING, &selbgcolor }, - { "prompt", STRING, &prompt }, -}; diff --git a/config.mk b/config.mk index 05d5a3e..0df3fc8 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 5.0 +VERSION = 5.1 # paths PREFIX = /usr/local diff --git a/dmenu.1 b/dmenu.1 new file mode 100644 index 0000000..323f93c --- /dev/null +++ b/dmenu.1 @@ -0,0 +1,194 @@ +.TH DMENU 1 dmenu\-VERSION +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-bfiv ] +.RB [ \-l +.IR lines ] +.RB [ \-m +.IR monitor ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] +.RB [ \-w +.IR windowid ] +.P +.BR dmenu_run " ..." +.SH DESCRIPTION +.B dmenu +is a dynamic menu for X, which reads a list of newline\-separated items from +stdin. When the user selects an item and presses Return, their choice is printed +to stdout and dmenu terminates. Entering text will narrow the items to those +matching the tokens in the input. +.P +.B dmenu_run +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and runs the result in their $SHELL. +.SH OPTIONS +.TP +.B \-b +dmenu appears at the bottom of the screen. +.TP +.B \-f +dmenu grabs the keyboard before reading stdin if not reading from a tty. This +is faster, but will lock up X until stdin reaches end\-of\-file. +.TP +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-l " lines" +dmenu lists items vertically, with the given number of lines. +.TP +.BI \-m " monitor" +dmenu is displayed on the monitor number supplied. Monitor numbers are starting +from 0. +.TP +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input field. +.TP +.BI \-fn " font" +defines the font or font set used. +.TP +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and X color names are supported. +.TP +.BI \-nf " color" +defines the normal foreground color. +.TP +.BI \-sb " color" +defines the selected background color. +.TP +.BI \-sf " color" +defines the selected foreground color. +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-w " windowid" +embed into windowid. +.SH USAGE +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. +.TP +.B Tab +Copy the selected item to the input field. +.TP +.B Return +Confirm selection. Prints the selected item to stdout and exits, returning +success. +.TP +.B Ctrl-Return +Confirm selection. Prints the selected item to stdout and continues. +.TP +.B Shift\-Return +Confirm input. Prints the input text to stdout and exits, returning success. +.TP +.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 +.B C\-a +Home +.TP +.B C\-b +Left +.TP +.B C\-c +Escape +.TP +.B C\-d +Delete +.TP +.B C\-e +End +.TP +.B C\-f +Right +.TP +.B C\-g +Escape +.TP +.B C\-h +Backspace +.TP +.B C\-i +Tab +.TP +.B C\-j +Return +.TP +.B C\-J +Shift-Return +.TP +.B C\-k +Delete line right +.TP +.B C\-m +Return +.TP +.B C\-M +Shift-Return +.TP +.B C\-n +Down +.TP +.B C\-p +Up +.TP +.B C\-u +Delete line left +.TP +.B C\-w +Delete word left +.TP +.B C\-y +Paste from primary X selection +.TP +.B C\-Y +Paste from X clipboard +.TP +.B M\-b +Move cursor to the start of the current word +.TP +.B M\-f +Move cursor to the end of the current word +.TP +.B M\-g +Home +.TP +.B M\-G +End +.TP +.B M\-h +Up +.TP +.B M\-j +Page down +.TP +.B M\-k +Page up +.TP +.B M\-l +Down +.SH SEE ALSO +.IR dwm (1), +.IR stest (1) diff --git a/dmenu.c b/dmenu.c index 3c0aa35..bd77994 100644 --- a/dmenu.c +++ b/dmenu.c @@ -11,7 +11,6 @@ #include #include #include -#include #ifdef XINERAMA #include #endif @@ -25,6 +24,8 @@ * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) #define LENGTH(X) (sizeof X / sizeof X[0]) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +#define NUMBERSMAXDIGITS 100 +#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ @@ -35,6 +36,7 @@ struct item { int out; }; +static char numbers[NUMBERSBUFSIZE] = ""; static char text[BUFSIZ] = ""; static char *embed; static int bh, mw, mh; @@ -54,21 +56,6 @@ static XIC xic; static Drw *drw; static Clr *scheme[SchemeLast]; -/* Xresources preferences */ -enum resource_type { - STRING = 0, - INTEGER = 1, - FLOAT = 2 -}; -typedef struct { - char *name; - enum resource_type type; - void *dst; -} ResourcePref; - -static void load_xresources(void); -static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst); - #include "config.h" static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; @@ -119,13 +106,20 @@ cleanup(void) } static char * -cistrstr(const char *s, const char *sub) +cistrstr(const char *h, const char *n) { - size_t len; + size_t i; - for (len = strlen(sub); *s; s++) - if (!strncasecmp(s, sub, len)) - return (char *)s; + if (!n[0]) + return (char *)h; + + for (; *h; ++h) { + for (i = 0; n[i] && tolower((unsigned char)n[i]) == + tolower((unsigned char)h[i]); ++i) + ; + if (n[i] == '\0') + return (char *)h; + } return NULL; } @@ -142,6 +136,21 @@ drawitem(struct item *item, int x, int y, int w) return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); } +static void +recalculatenumbers() +{ + unsigned int numer = 0, denom = 0; + struct item *item; + if (matchend) { + numer++; + for (item = matchend; item && item->left; item = item->left) + numer++; + } + for (item = items; item && item->text; item++) + denom++; + snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom); +} + static void drawmenu(void) { @@ -167,6 +176,7 @@ drawmenu(void) drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); } + recalculatenumbers(); if (lines > 0) { /* draw vertical list */ for (item = curr; item != next; item = item->right) @@ -181,13 +191,15 @@ drawmenu(void) } x += w; for (item = curr; item != next; item = item->right) - x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">"))); + x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">") - TEXTW(numbers))); if (next) { w = TEXTW(">"); drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); + drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, ">", 0); } } + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - TEXTW(numbers), 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0); drw_map(drw, win, 0, 0, mw, mh); } @@ -413,7 +425,7 @@ keypress(XKeyEvent *ev) switch(ksym) { default: - insert: +insert: if (!iscntrl(*buf)) insert(buf, len); break; @@ -687,54 +699,6 @@ readstdin(void) lines = MIN(lines, i); } -void -resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) -{ - char *sdst = NULL; - int *idst = NULL; - float *fdst = NULL; - sdst = dst; - idst = dst; - fdst = dst; - char fullname[256]; - char *type; - XrmValue ret; - snprintf(fullname, sizeof(fullname), "%s.%s", "dmenu", name); - fullname[sizeof(fullname) - 1] = '\0'; - XrmGetResource(db, fullname, "*", &type, &ret); - if (!(ret.addr == NULL || strncmp("String", type, 64))) - { - switch (rtype) { - case STRING: - strcpy(sdst, ret.addr); - break; - case INTEGER: - *idst = strtoul(ret.addr, NULL, 10); - break; - case FLOAT: - *fdst = strtof(ret.addr, NULL); - break; - } - } -} - -void -load_xresources(void) -{ - Display *display; - char *resm; - XrmDatabase db; - ResourcePref *p; - display = XOpenDisplay(NULL); - resm = XResourceManagerString(display); - if (!resm) - return; - db = XrmGetStringDatabase(resm); - for (p = resources; p < resources + LENGTH(resources); p++) - resource_load(db, p->name, p->type, p->dst); - XCloseDisplay(display); -} - static void run(void) { @@ -892,9 +856,6 @@ main(int argc, char *argv[]) XWindowAttributes wa; int i, fast = 0; - XrmInitialize(); - load_xresources(); - for (i = 1; i < argc; i++) /* these options take no arguments */ if (!strcmp(argv[i], "-v")) { /* prints version information */ diff --git a/drw.c b/drw.c index 8f1059e..4cdbcbe 100644 --- a/drw.c +++ b/drw.c @@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname) /* Wrapper to create color schemes. The caller has to call free(3) on the * returned color scheme when done using it. */ Clr * -drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount) +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) { size_t i; Clr *ret; diff --git a/drw.h b/drw.h index 9c2c8ea..4c67419 100644 --- a/drw.h +++ b/drw.h @@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in /* Colorscheme abstraction */ void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); -Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); /* Cursor abstraction */ Cur *drw_cur_create(Drw *drw, int shape); diff --git a/stest.1 b/stest.1 new file mode 100644 index 0000000..2667d8a --- /dev/null +++ b/stest.1 @@ -0,0 +1,90 @@ +.TH STEST 1 dmenu\-VERSION +.SH NAME +stest \- filter a list of files by properties +.SH SYNOPSIS +.B stest +.RB [ -abcdefghlpqrsuwx ] +.RB [ -n +.IR file ] +.RB [ -o +.IR file ] +.RI [ file ...] +.SH DESCRIPTION +.B stest +takes a list of files and filters by the files' properties, analogous to +.IR test (1). +Files which pass all tests are printed to stdout. If no files are given, stest +reads files from stdin. +.SH OPTIONS +.TP +.B \-a +Test hidden files. +.TP +.B \-b +Test that files are block specials. +.TP +.B \-c +Test that files are character specials. +.TP +.B \-d +Test that files are directories. +.TP +.B \-e +Test that files exist. +.TP +.B \-f +Test that files are regular files. +.TP +.B \-g +Test that files have their set-group-ID flag set. +.TP +.B \-h +Test that files are symbolic links. +.TP +.B \-l +Test the contents of a directory given as an argument. +.TP +.BI \-n " file" +Test that files are newer than +.IR file . +.TP +.BI \-o " file" +Test that files are older than +.IR file . +.TP +.B \-p +Test that files are named pipes. +.TP +.B \-q +No files are printed, only the exit status is returned. +.TP +.B \-r +Test that files are readable. +.TP +.B \-s +Test that files are not empty. +.TP +.B \-u +Test that files have their set-user-ID flag set. +.TP +.B \-v +Invert the sense of tests, only failing files pass. +.TP +.B \-w +Test that files are writable. +.TP +.B \-x +Test that files are executable. +.SH EXIT STATUS +.TP +.B 0 +At least one file passed all tests. +.TP +.B 1 +No files passed all tests. +.TP +.B 2 +An error occurred. +.SH SEE ALSO +.IR dmenu (1), +.IR test (1)