aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config/dunst/dunstrc2
-rwxr-xr-x.local/bin/dmenu-adwaitabin0 -> 42672 bytes
-rwxr-xr-x.local/bin/dmenu-dunstbin0 -> 42672 bytes
-rwxr-xr-x.local/share/Blista-Kanjo-Emoji/blista-emoji-picker2
-rwxr-xr-x.local/share/scripts/dym.sh4
-rw-r--r--.local/src/dmenu-adwaita/LICENSE (renamed from .config/dunst/dmenu-dunst/LICENSE)0
-rw-r--r--.local/src/dmenu-adwaita/Makefile (renamed from .config/dunst/dmenu-dunst/Makefile)0
-rw-r--r--.local/src/dmenu-adwaita/README (renamed from .config/dunst/dmenu-dunst/README)0
-rw-r--r--.local/src/dmenu-adwaita/arg.h (renamed from .config/dunst/dmenu-dunst/arg.h)0
-rw-r--r--.local/src/dmenu-adwaita/config.def.h24
-rw-r--r--.local/src/dmenu-adwaita/config.mk (renamed from .config/dunst/dmenu-dunst/config.mk)0
-rw-r--r--.local/src/dmenu-adwaita/dmenu.1 (renamed from .config/dunst/dmenu-dunst/dmenu.1)0
-rw-r--r--.local/src/dmenu-adwaita/dmenu.c (renamed from .config/dunst/dmenu-dunst/dmenu.c.orig)0
-rwxr-xr-x.local/src/dmenu-adwaita/dmenu_path (renamed from .config/dunst/dmenu-dunst/dmenu_path)0
-rwxr-xr-x.local/src/dmenu-adwaita/dmenu_run (renamed from .config/dunst/dmenu-dunst/dmenu_run)0
-rw-r--r--.local/src/dmenu-adwaita/drw.c (renamed from .config/dunst/dmenu-dunst/drw.c)0
-rw-r--r--.local/src/dmenu-adwaita/drw.h (renamed from .config/dunst/dmenu-dunst/drw.h)0
-rw-r--r--.local/src/dmenu-adwaita/stest.1 (renamed from .config/dunst/dmenu-dunst/stest.1)0
-rw-r--r--.local/src/dmenu-adwaita/stest.c (renamed from .config/dunst/dmenu-dunst/stest.c)0
-rw-r--r--.local/src/dmenu-adwaita/util.c (renamed from .config/dunst/dmenu-dunst/util.c)0
-rw-r--r--.local/src/dmenu-adwaita/util.h (renamed from .config/dunst/dmenu-dunst/util.h)0
-rw-r--r--.local/src/dmenu-dunst/LICENSE30
-rw-r--r--.local/src/dmenu-dunst/Makefile64
-rw-r--r--.local/src/dmenu-dunst/README24
-rw-r--r--.local/src/dmenu-dunst/arg.h49
-rw-r--r--.local/src/dmenu-dunst/config.def.h (renamed from .config/dunst/dmenu-dunst/config.def.h)0
-rw-r--r--.local/src/dmenu-dunst/config.mk31
-rw-r--r--.local/src/dmenu-dunst/dmenu.1194
-rw-r--r--.local/src/dmenu-dunst/dmenu.c (renamed from .config/dunst/dmenu-dunst/dmenu.c)0
-rwxr-xr-x.local/src/dmenu-dunst/dmenu_path13
-rwxr-xr-x.local/src/dmenu-dunst/dmenu_run2
-rw-r--r--.local/src/dmenu-dunst/drw.c423
-rw-r--r--.local/src/dmenu-dunst/drw.h57
-rw-r--r--.local/src/dmenu-dunst/stest.190
-rw-r--r--.local/src/dmenu-dunst/stest.c109
-rw-r--r--.local/src/dmenu-dunst/util.c35
-rw-r--r--.local/src/dmenu-dunst/util.h8
37 files changed, 1157 insertions, 4 deletions
diff --git a/.config/dunst/dunstrc b/.config/dunst/dunstrc
index 22e9e6c..0a97550 100644
--- a/.config/dunst/dunstrc
+++ b/.config/dunst/dunstrc
@@ -229,7 +229,7 @@
### Misc/Advanced ###
# dmenu path.
- dmenu = ~/.config/dunst/dmenu-dunst/dmenu -i -l 30 -p 'Select Notification Action:'
+ dmenu = ~/.local/bin/dmenu-dunst -i -l 30 -p 'Select Notification Action:'
#dmenu = /usr/bin/gdmenu -t 'Select Notification Action'
# Browser for opening urls in context menu.
diff --git a/.local/bin/dmenu-adwaita b/.local/bin/dmenu-adwaita
new file mode 100755
index 0000000..24f7121
--- /dev/null
+++ b/.local/bin/dmenu-adwaita
Binary files differ
diff --git a/.local/bin/dmenu-dunst b/.local/bin/dmenu-dunst
new file mode 100755
index 0000000..d004c42
--- /dev/null
+++ b/.local/bin/dmenu-dunst
Binary files differ
diff --git a/.local/share/Blista-Kanjo-Emoji/blista-emoji-picker b/.local/share/Blista-Kanjo-Emoji/blista-emoji-picker
index b04b524..3ceae7e 100755
--- a/.local/share/Blista-Kanjo-Emoji/blista-emoji-picker
+++ b/.local/share/Blista-Kanjo-Emoji/blista-emoji-picker
@@ -1,6 +1,6 @@
#!/bin/sh
-chosen=$(cut -d ';' -f1 ~/.local/share/Blista-Kanjo-Emoji/emoji | ~/.local/share/dmenu-custom/dmenu -i -l 30 | sed "s/ .*//")
+chosen=$(cut -d ';' -f1 ~/.local/share/Blista-Kanjo-Emoji/emoji | ~/.local/bin/dmenu-adwaita -i -l 30 | sed "s/ .*//")
[ -z "$chosen" ] && exit
diff --git a/.local/share/scripts/dym.sh b/.local/share/scripts/dym.sh
index 79374f8..aef084c 100755
--- a/.local/share/scripts/dym.sh
+++ b/.local/share/scripts/dym.sh
@@ -1,13 +1,13 @@
#!/bin/sh
-WORD=$(echo "\n" | ~/.local/share/dmenu-custom/dmenu -b -i -p "Check Spelling: ")
+WORD=$(echo "\n" | ~/.local/bin/dmenu-adwaita -b -i -p "Check Spelling: ")
[ -z "$WORD" ] && exit
if [ -n "$1" ]; then
xdotool type "$WORD"
else
- CORRECTED=$(dym -c $WORD -n 10 | ~/.local/share/dmenu-custom/dmenu -i -b -l 10 -p "Did you mean?:")
+ CORRECTED=$(dym -c $WORD -n 10 | ~/.local/bin/dmenu-adwaita -i -b -l 10 -p "Did you mean?:")
[ -z "$CORRECTED" ] && exit
if [ -n "$1" ]; then
diff --git a/.config/dunst/dmenu-dunst/LICENSE b/.local/src/dmenu-adwaita/LICENSE
index 3afd28e..3afd28e 100644
--- a/.config/dunst/dmenu-dunst/LICENSE
+++ b/.local/src/dmenu-adwaita/LICENSE
diff --git a/.config/dunst/dmenu-dunst/Makefile b/.local/src/dmenu-adwaita/Makefile
index a03a95c..a03a95c 100644
--- a/.config/dunst/dmenu-dunst/Makefile
+++ b/.local/src/dmenu-adwaita/Makefile
diff --git a/.config/dunst/dmenu-dunst/README b/.local/src/dmenu-adwaita/README
index a8fcdfe..a8fcdfe 100644
--- a/.config/dunst/dmenu-dunst/README
+++ b/.local/src/dmenu-adwaita/README
diff --git a/.config/dunst/dmenu-dunst/arg.h b/.local/src/dmenu-adwaita/arg.h
index e94e02b..e94e02b 100644
--- a/.config/dunst/dmenu-dunst/arg.h
+++ b/.local/src/dmenu-adwaita/arg.h
diff --git a/.local/src/dmenu-adwaita/config.def.h b/.local/src/dmenu-adwaita/config.def.h
new file mode 100644
index 0000000..9b74712
--- /dev/null
+++ b/.local/src/dmenu-adwaita/config.def.h
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+/* 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 const char *fonts[] = {
+ "JetBrains Mono:size=11",
+ "Noto Color Emoji:size=11"
+};
+static const char *prompt = NULL; /* -p option; prompt to the left of input field */
+static const char *colors[SchemeLast][2] = {
+ /* fg bg */
+ [SchemeNorm] = { "#bbbbbb", "#303030" },
+ [SchemeSel] = { "#eeeeee", "#11427E" },
+ [SchemeOut] = { "#000000", "#00ffff" },
+};
+/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
+static unsigned int lines = 0;
+
+/*
+ * Characters not considered part of a word while deleting words
+ * for example: " /?\"&[]"
+ */
+static const char worddelimiters[] = " ";
diff --git a/.config/dunst/dmenu-dunst/config.mk b/.local/src/dmenu-adwaita/config.mk
index 05d5a3e..05d5a3e 100644
--- a/.config/dunst/dmenu-dunst/config.mk
+++ b/.local/src/dmenu-adwaita/config.mk
diff --git a/.config/dunst/dmenu-dunst/dmenu.1 b/.local/src/dmenu-adwaita/dmenu.1
index 323f93c..323f93c 100644
--- a/.config/dunst/dmenu-dunst/dmenu.1
+++ b/.local/src/dmenu-adwaita/dmenu.1
diff --git a/.config/dunst/dmenu-dunst/dmenu.c.orig b/.local/src/dmenu-adwaita/dmenu.c
index 98507d9..98507d9 100644
--- a/.config/dunst/dmenu-dunst/dmenu.c.orig
+++ b/.local/src/dmenu-adwaita/dmenu.c
diff --git a/.config/dunst/dmenu-dunst/dmenu_path b/.local/src/dmenu-adwaita/dmenu_path
index 3a7cda7..3a7cda7 100755
--- a/.config/dunst/dmenu-dunst/dmenu_path
+++ b/.local/src/dmenu-adwaita/dmenu_path
diff --git a/.config/dunst/dmenu-dunst/dmenu_run b/.local/src/dmenu-adwaita/dmenu_run
index 834ede5..834ede5 100755
--- a/.config/dunst/dmenu-dunst/dmenu_run
+++ b/.local/src/dmenu-adwaita/dmenu_run
diff --git a/.config/dunst/dmenu-dunst/drw.c b/.local/src/dmenu-adwaita/drw.c
index c1c265c..c1c265c 100644
--- a/.config/dunst/dmenu-dunst/drw.c
+++ b/.local/src/dmenu-adwaita/drw.c
diff --git a/.config/dunst/dmenu-dunst/drw.h b/.local/src/dmenu-adwaita/drw.h
index 4c67419..4c67419 100644
--- a/.config/dunst/dmenu-dunst/drw.h
+++ b/.local/src/dmenu-adwaita/drw.h
diff --git a/.config/dunst/dmenu-dunst/stest.1 b/.local/src/dmenu-adwaita/stest.1
index 2667d8a..2667d8a 100644
--- a/.config/dunst/dmenu-dunst/stest.1
+++ b/.local/src/dmenu-adwaita/stest.1
diff --git a/.config/dunst/dmenu-dunst/stest.c b/.local/src/dmenu-adwaita/stest.c
index e27d3a5..e27d3a5 100644
--- a/.config/dunst/dmenu-dunst/stest.c
+++ b/.local/src/dmenu-adwaita/stest.c
diff --git a/.config/dunst/dmenu-dunst/util.c b/.local/src/dmenu-adwaita/util.c
index fe044fc..fe044fc 100644
--- a/.config/dunst/dmenu-dunst/util.c
+++ b/.local/src/dmenu-adwaita/util.c
diff --git a/.config/dunst/dmenu-dunst/util.h b/.local/src/dmenu-adwaita/util.h
index f633b51..f633b51 100644
--- a/.config/dunst/dmenu-dunst/util.h
+++ b/.local/src/dmenu-adwaita/util.h
diff --git a/.local/src/dmenu-dunst/LICENSE b/.local/src/dmenu-dunst/LICENSE
new file mode 100644
index 0000000..3afd28e
--- /dev/null
+++ b/.local/src/dmenu-dunst/LICENSE
@@ -0,0 +1,30 @@
+MIT/X Consortium License
+
+© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
+© 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com>
+© 2006-2007 Michał Janeczek <janeczek@gmail.com>
+© 2007 Kris Maglione <jg@suckless.org>
+© 2009 Gottox <gottox@s01.de>
+© 2009 Markus Schnalke <meillo@marmaro.de>
+© 2009 Evan Gates <evan.gates@gmail.com>
+© 2010-2012 Connor Lane Smith <cls@lubutu.com>
+© 2014-2020 Hiltjo Posthuma <hiltjo@codemadness.org>
+© 2015-2019 Quentin Rameau <quinq@fifth.space>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/.local/src/dmenu-dunst/Makefile b/.local/src/dmenu-dunst/Makefile
new file mode 100644
index 0000000..a03a95c
--- /dev/null
+++ b/.local/src/dmenu-dunst/Makefile
@@ -0,0 +1,64 @@
+# dmenu - dynamic menu
+# See LICENSE file for copyright and license details.
+
+include config.mk
+
+SRC = drw.c dmenu.c stest.c util.c
+OBJ = $(SRC:.c=.o)
+
+all: options dmenu stest
+
+options:
+ @echo dmenu build options:
+ @echo "CFLAGS = $(CFLAGS)"
+ @echo "LDFLAGS = $(LDFLAGS)"
+ @echo "CC = $(CC)"
+
+.c.o:
+ $(CC) -c $(CFLAGS) $<
+
+config.h:
+ cp config.def.h $@
+
+$(OBJ): arg.h config.h config.mk drw.h
+
+dmenu: dmenu.o drw.o util.o
+ $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
+
+stest: stest.o
+ $(CC) -o $@ stest.o $(LDFLAGS)
+
+clean:
+ rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
+
+dist: clean
+ mkdir -p dmenu-$(VERSION)
+ cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
+ drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
+ dmenu-$(VERSION)
+ tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
+ gzip dmenu-$(VERSION).tar
+ rm -rf dmenu-$(VERSION)
+
+install: all
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
+ cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
+ mkdir -p $(DESTDIR)$(MANPREFIX)/man1
+ sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
+ sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
+ chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
+ chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
+
+uninstall:
+ rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
+ $(DESTDIR)$(PREFIX)/bin/dmenu_path\
+ $(DESTDIR)$(PREFIX)/bin/dmenu_run\
+ $(DESTDIR)$(PREFIX)/bin/stest\
+ $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
+ $(DESTDIR)$(MANPREFIX)/man1/stest.1
+
+.PHONY: all options clean dist install uninstall
diff --git a/.local/src/dmenu-dunst/README b/.local/src/dmenu-dunst/README
new file mode 100644
index 0000000..a8fcdfe
--- /dev/null
+++ b/.local/src/dmenu-dunst/README
@@ -0,0 +1,24 @@
+dmenu - dynamic menu
+====================
+dmenu is an efficient dynamic menu for X.
+
+
+Requirements
+------------
+In order to build dmenu you need the Xlib header files.
+
+
+Installation
+------------
+Edit config.mk to match your local setup (dmenu is installed into
+the /usr/local namespace by default).
+
+Afterwards enter the following command to build and install dmenu
+(if necessary as root):
+
+ make clean install
+
+
+Running dmenu
+-------------
+See the man page for details.
diff --git a/.local/src/dmenu-dunst/arg.h b/.local/src/dmenu-dunst/arg.h
new file mode 100644
index 0000000..e94e02b
--- /dev/null
+++ b/.local/src/dmenu-dunst/arg.h
@@ -0,0 +1,49 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][0] == '-'\
+ && argv[0][1];\
+ argc--, argv++) {\
+ char argc_;\
+ char **argv_;\
+ int brk_;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (brk_ = 0, argv[0]++, argv_ = argv;\
+ argv[0][0] && !brk_;\
+ argv[0]++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][0];\
+ switch (argc_)
+
+#define ARGEND }\
+ }
+
+#define ARGC() argc_
+
+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#endif
diff --git a/.config/dunst/dmenu-dunst/config.def.h b/.local/src/dmenu-dunst/config.def.h
index 789fd1c..789fd1c 100644
--- a/.config/dunst/dmenu-dunst/config.def.h
+++ b/.local/src/dmenu-dunst/config.def.h
diff --git a/.local/src/dmenu-dunst/config.mk b/.local/src/dmenu-dunst/config.mk
new file mode 100644
index 0000000..05d5a3e
--- /dev/null
+++ b/.local/src/dmenu-dunst/config.mk
@@ -0,0 +1,31 @@
+# dmenu version
+VERSION = 5.0
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
+
+# Xinerama, comment if you don't want it
+XINERAMALIBS = -lXinerama
+XINERAMAFLAGS = -DXINERAMA
+
+# freetype
+FREETYPELIBS = -lfontconfig -lXft
+FREETYPEINC = /usr/include/freetype2
+# OpenBSD (uncomment)
+#FREETYPEINC = $(X11INC)/freetype2
+
+# includes and libs
+INCS = -I$(X11INC) -I$(FREETYPEINC)
+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
+
+# flags
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
+CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
+LDFLAGS = $(LIBS)
+
+# compiler and linker
+CC = cc
diff --git a/.local/src/dmenu-dunst/dmenu.1 b/.local/src/dmenu-dunst/dmenu.1
new file mode 100644
index 0000000..323f93c
--- /dev/null
+++ b/.local/src/dmenu-dunst/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/.config/dunst/dmenu-dunst/dmenu.c b/.local/src/dmenu-dunst/dmenu.c
index 5a85076..5a85076 100644
--- a/.config/dunst/dmenu-dunst/dmenu.c
+++ b/.local/src/dmenu-dunst/dmenu.c
diff --git a/.local/src/dmenu-dunst/dmenu_path b/.local/src/dmenu-dunst/dmenu_path
new file mode 100755
index 0000000..3a7cda7
--- /dev/null
+++ b/.local/src/dmenu-dunst/dmenu_path
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
+cache="$cachedir/dmenu_run"
+
+[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
+
+IFS=:
+if stest -dqr -n "$cache" $PATH; then
+ stest -flx $PATH | sort -u | tee "$cache"
+else
+ cat "$cache"
+fi
diff --git a/.local/src/dmenu-dunst/dmenu_run b/.local/src/dmenu-dunst/dmenu_run
new file mode 100755
index 0000000..834ede5
--- /dev/null
+++ b/.local/src/dmenu-dunst/dmenu_run
@@ -0,0 +1,2 @@
+#!/bin/sh
+dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
diff --git a/.local/src/dmenu-dunst/drw.c b/.local/src/dmenu-dunst/drw.c
new file mode 100644
index 0000000..c1c265c
--- /dev/null
+++ b/.local/src/dmenu-dunst/drw.c
@@ -0,0 +1,423 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xft/Xft.h>
+
+#include "drw.h"
+#include "util.h"
+
+#define UTF_INVALID 0xFFFD
+#define UTF_SIZ 4
+
+static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
+static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
+static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+
+static long
+utf8decodebyte(const char c, size_t *i)
+{
+ for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
+ if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
+ return (unsigned char)c & ~utfmask[*i];
+ return 0;
+}
+
+static size_t
+utf8validate(long *u, size_t i)
+{
+ if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
+ *u = UTF_INVALID;
+ for (i = 1; *u > utfmax[i]; ++i)
+ ;
+ return i;
+}
+
+static size_t
+utf8decode(const char *c, long *u, size_t clen)
+{
+ size_t i, j, len, type;
+ long udecoded;
+
+ *u = UTF_INVALID;
+ if (!clen)
+ return 0;
+ udecoded = utf8decodebyte(c[0], &len);
+ if (!BETWEEN(len, 1, UTF_SIZ))
+ return 1;
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+ udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
+ if (type)
+ return j;
+ }
+ if (j < len)
+ return 0;
+ *u = udecoded;
+ utf8validate(u, len);
+
+ return len;
+}
+
+Drw *
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+{
+ Drw *drw = ecalloc(1, sizeof(Drw));
+
+ drw->dpy = dpy;
+ drw->screen = screen;
+ drw->root = root;
+ drw->w = w;
+ drw->h = h;
+ drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
+ drw->gc = XCreateGC(dpy, root, 0, NULL);
+ XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+
+ return drw;
+}
+
+void
+drw_resize(Drw *drw, unsigned int w, unsigned int h)
+{
+ if (!drw)
+ return;
+
+ drw->w = w;
+ drw->h = h;
+ if (drw->drawable)
+ XFreePixmap(drw->dpy, drw->drawable);
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+}
+
+void
+drw_free(Drw *drw)
+{
+ XFreePixmap(drw->dpy, drw->drawable);
+ XFreeGC(drw->dpy, drw->gc);
+ drw_fontset_free(drw->fonts);
+ free(drw);
+}
+
+/* This function is an implementation detail. Library users should use
+ * drw_fontset_create instead.
+ */
+static Fnt *
+xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
+{
+ Fnt *font;
+ XftFont *xfont = NULL;
+ FcPattern *pattern = NULL;
+
+ if (fontname) {
+ /* Using the pattern found at font->xfont->pattern does not yield the
+ * same substitution results as using the pattern returned by
+ * FcNameParse; using the latter results in the desired fallback
+ * behaviour whereas the former just results in missing-character
+ * rectangles being drawn, at least with some fonts. */
+ if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
+ fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
+ return NULL;
+ }
+ if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
+ fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
+ XftFontClose(drw->dpy, xfont);
+ return NULL;
+ }
+ } else if (fontpattern) {
+ if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
+ fprintf(stderr, "error, cannot load font from pattern.\n");
+ return NULL;
+ }
+ } else {
+ die("no font specified.");
+ }
+
+ font = ecalloc(1, sizeof(Fnt));
+ font->xfont = xfont;
+ font->pattern = pattern;
+ font->h = xfont->ascent + xfont->descent;
+ font->dpy = drw->dpy;
+
+ return font;
+}
+
+static void
+xfont_free(Fnt *font)
+{
+ if (!font)
+ return;
+ if (font->pattern)
+ FcPatternDestroy(font->pattern);
+ XftFontClose(font->dpy, font->xfont);
+ free(font);
+}
+
+Fnt*
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
+{
+ Fnt *cur, *ret = NULL;
+ size_t i;
+
+ if (!drw || !fonts)
+ return NULL;
+
+ for (i = 1; i <= fontcount; i++) {
+ if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
+ cur->next = ret;
+ ret = cur;
+ }
+ }
+ return (drw->fonts = ret);
+}
+
+void
+drw_fontset_free(Fnt *font)
+{
+ if (font) {
+ drw_fontset_free(font->next);
+ xfont_free(font);
+ }
+}
+
+void
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+{
+ if (!drw || !dest || !clrname)
+ return;
+
+ if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
+ DefaultColormap(drw->dpy, drw->screen),
+ clrname, dest))
+ die("error, cannot allocate color '%s'", 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, const char *clrnames[], size_t clrcount)
+{
+ size_t i;
+ Clr *ret;
+
+ /* need at least two colors for a scheme */
+ if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
+ return NULL;
+
+ for (i = 0; i < clrcount; i++)
+ drw_clr_create(drw, &ret[i], clrnames[i]);
+ return ret;
+}
+
+void
+drw_setfontset(Drw *drw, Fnt *set)
+{
+ if (drw)
+ drw->fonts = set;
+}
+
+void
+drw_setscheme(Drw *drw, Clr *scm)
+{
+ if (drw)
+ drw->scheme = scm;
+}
+
+void
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
+{
+ if (!drw || !drw->scheme)
+ return;
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
+ if (filled)
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+ else
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
+}
+
+int
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
+{
+ char buf[1024];
+ int ty;
+ unsigned int ew;
+ XftDraw *d = NULL;
+ Fnt *usedfont, *curfont, *nextfont;
+ size_t i, len;
+ int utf8strlen, utf8charlen, render = x || y || w || h;
+ long utf8codepoint = 0;
+ const char *utf8str;
+ FcCharSet *fccharset;
+ FcPattern *fcpattern;
+ FcPattern *match;
+ XftResult result;
+ int charexists = 0;
+
+ if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
+ return 0;
+
+ if (!render) {
+ w = ~w;
+ } else {
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+ d = XftDrawCreate(drw->dpy, drw->drawable,
+ DefaultVisual(drw->dpy, drw->screen),
+ DefaultColormap(drw->dpy, drw->screen));
+ x += lpad;
+ w -= lpad;
+ }
+
+ usedfont = drw->fonts;
+ while (1) {
+ utf8strlen = 0;
+ utf8str = text;
+ nextfont = NULL;
+ while (*text) {
+ utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
+ for (curfont = drw->fonts; curfont; curfont = curfont->next) {
+ charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
+ if (charexists) {
+ if (curfont == usedfont) {
+ utf8strlen += utf8charlen;
+ text += utf8charlen;
+ } else {
+ nextfont = curfont;
+ }
+ break;
+ }
+ }
+
+ if (!charexists || nextfont)
+ break;
+ else
+ charexists = 0;
+ }
+
+ if (utf8strlen) {
+ drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
+ /* shorten text if necessary */
+ for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
+ drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
+
+ if (len) {
+ memcpy(buf, utf8str, len);
+ buf[len] = '\0';
+ if (len < utf8strlen)
+ for (i = len; i && i > len - 3; buf[--i] = '.')
+ ; /* NOP */
+
+ if (render) {
+ ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
+ XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
+ usedfont->xfont, x, ty, (XftChar8 *)buf, len);
+ }
+ x += ew;
+ w -= ew;
+ }
+ }
+
+ if (!*text) {
+ break;
+ } else if (nextfont) {
+ charexists = 0;
+ usedfont = nextfont;
+ } else {
+ /* Regardless of whether or not a fallback font is found, the
+ * character must be drawn. */
+ charexists = 1;
+
+ fccharset = FcCharSetCreate();
+ FcCharSetAddChar(fccharset, utf8codepoint);
+
+ if (!drw->fonts->pattern) {
+ /* Refer to the comment in xfont_create for more information. */
+ die("the first font in the cache must be loaded from a font string.");
+ }
+
+ fcpattern = FcPatternDuplicate(drw->fonts->pattern);
+ FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
+ FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
+ FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
+
+ FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
+ FcDefaultSubstitute(fcpattern);
+ match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
+
+ FcCharSetDestroy(fccharset);
+ FcPatternDestroy(fcpattern);
+
+ if (match) {
+ usedfont = xfont_create(drw, NULL, match);
+ if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
+ for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
+ ; /* NOP */
+ curfont->next = usedfont;
+ } else {
+ xfont_free(usedfont);
+ usedfont = drw->fonts;
+ }
+ }
+ }
+ }
+ if (d)
+ XftDrawDestroy(d);
+
+ return x + (render ? w : 0);
+}
+
+void
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
+{
+ if (!drw)
+ return;
+
+ XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
+ XSync(drw->dpy, False);
+}
+
+unsigned int
+drw_fontset_getwidth(Drw *drw, const char *text)
+{
+ if (!drw || !drw->fonts || !text)
+ return 0;
+ return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
+}
+
+void
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
+{
+ XGlyphInfo ext;
+
+ if (!font || !text)
+ return;
+
+ XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
+ if (w)
+ *w = ext.xOff;
+ if (h)
+ *h = font->h;
+}
+
+Cur *
+drw_cur_create(Drw *drw, int shape)
+{
+ Cur *cur;
+
+ if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
+ return NULL;
+
+ cur->cursor = XCreateFontCursor(drw->dpy, shape);
+
+ return cur;
+}
+
+void
+drw_cur_free(Drw *drw, Cur *cursor)
+{
+ if (!cursor)
+ return;
+
+ XFreeCursor(drw->dpy, cursor->cursor);
+ free(cursor);
+}
diff --git a/.local/src/dmenu-dunst/drw.h b/.local/src/dmenu-dunst/drw.h
new file mode 100644
index 0000000..4c67419
--- /dev/null
+++ b/.local/src/dmenu-dunst/drw.h
@@ -0,0 +1,57 @@
+/* See LICENSE file for copyright and license details. */
+
+typedef struct {
+ Cursor cursor;
+} Cur;
+
+typedef struct Fnt {
+ Display *dpy;
+ unsigned int h;
+ XftFont *xfont;
+ FcPattern *pattern;
+ struct Fnt *next;
+} Fnt;
+
+enum { ColFg, ColBg }; /* Clr scheme index */
+typedef XftColor Clr;
+
+typedef struct {
+ unsigned int w, h;
+ Display *dpy;
+ int screen;
+ Window root;
+ Drawable drawable;
+ GC gc;
+ Clr *scheme;
+ Fnt *fonts;
+} Drw;
+
+/* Drawable abstraction */
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+void drw_free(Drw *drw);
+
+/* Fnt abstraction */
+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
+void drw_fontset_free(Fnt* set);
+unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
+void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
+
+/* Colorscheme abstraction */
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+
+/* Cursor abstraction */
+Cur *drw_cur_create(Drw *drw, int shape);
+void drw_cur_free(Drw *drw, Cur *cursor);
+
+/* Drawing context manipulation */
+void drw_setfontset(Drw *drw, Fnt *set);
+void drw_setscheme(Drw *drw, Clr *scm);
+
+/* Drawing functions */
+void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
+int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
+
+/* Map functions */
+void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
diff --git a/.local/src/dmenu-dunst/stest.1 b/.local/src/dmenu-dunst/stest.1
new file mode 100644
index 0000000..2667d8a
--- /dev/null
+++ b/.local/src/dmenu-dunst/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)
diff --git a/.local/src/dmenu-dunst/stest.c b/.local/src/dmenu-dunst/stest.c
new file mode 100644
index 0000000..e27d3a5
--- /dev/null
+++ b/.local/src/dmenu-dunst/stest.c
@@ -0,0 +1,109 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "arg.h"
+char *argv0;
+
+#define FLAG(x) (flag[(x)-'a'])
+
+static void test(const char *, const char *);
+static void usage(void);
+
+static int match = 0;
+static int flag[26];
+static struct stat old, new;
+
+static void
+test(const char *path, const char *name)
+{
+ struct stat st, ln;
+
+ if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */
+ && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
+ && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
+ && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
+ && (!FLAG('e') || access(path, F_OK) == 0) /* exists */
+ && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
+ && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
+ && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
+ && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
+ && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
+ && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
+ && (!FLAG('r') || access(path, R_OK) == 0) /* readable */
+ && (!FLAG('s') || st.st_size > 0) /* not empty */
+ && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
+ && (!FLAG('w') || access(path, W_OK) == 0) /* writable */
+ && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */
+ if (FLAG('q'))
+ exit(0);
+ match = 1;
+ puts(name);
+ }
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
+ "[-n file] [-o file] [file...]\n", argv0);
+ exit(2); /* like test(1) return > 1 on error */
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct dirent *d;
+ char path[PATH_MAX], *line = NULL, *file;
+ size_t linesiz = 0;
+ ssize_t n;
+ DIR *dir;
+ int r;
+
+ ARGBEGIN {
+ case 'n': /* newer than file */
+ case 'o': /* older than file */
+ file = EARGF(usage());
+ if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
+ perror(file);
+ break;
+ default:
+ /* miscellaneous operators */
+ if (strchr("abcdefghlpqrsuvwx", ARGC()))
+ FLAG(ARGC()) = 1;
+ else
+ usage(); /* unknown flag */
+ } ARGEND;
+
+ if (!argc) {
+ /* read list from stdin */
+ while ((n = getline(&line, &linesiz, stdin)) > 0) {
+ if (line[n - 1] == '\n')
+ line[n - 1] = '\0';
+ test(line, line);
+ }
+ free(line);
+ } else {
+ for (; argc; argc--, argv++) {
+ if (FLAG('l') && (dir = opendir(*argv))) {
+ /* test directory contents */
+ while ((d = readdir(dir))) {
+ r = snprintf(path, sizeof path, "%s/%s",
+ *argv, d->d_name);
+ if (r >= 0 && (size_t)r < sizeof path)
+ test(path, d->d_name);
+ }
+ closedir(dir);
+ } else {
+ test(*argv, *argv);
+ }
+ }
+ }
+ return match ? 0 : 1;
+}
diff --git a/.local/src/dmenu-dunst/util.c b/.local/src/dmenu-dunst/util.c
new file mode 100644
index 0000000..fe044fc
--- /dev/null
+++ b/.local/src/dmenu-dunst/util.c
@@ -0,0 +1,35 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+void *
+ecalloc(size_t nmemb, size_t size)
+{
+ void *p;
+
+ if (!(p = calloc(nmemb, size)))
+ die("calloc:");
+ return p;
+}
+
+void
+die(const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ } else {
+ fputc('\n', stderr);
+ }
+
+ exit(1);
+}
diff --git a/.local/src/dmenu-dunst/util.h b/.local/src/dmenu-dunst/util.h
new file mode 100644
index 0000000..f633b51
--- /dev/null
+++ b/.local/src/dmenu-dunst/util.h
@@ -0,0 +1,8 @@
+/* See LICENSE file for copyright and license details. */
+
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
+
+void die(const char *fmt, ...);
+void *ecalloc(size_t nmemb, size_t size);