diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 299675f..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,8 +0,0 @@
-BasedOnStyle: Google
-IndentWidth: 4
-InsertBraces: true
-ColumnLimit: 79
-AlignConsecutiveMacros: Consecutive
-AllowShortFunctionsOnASingleLine: None
-AllowShortLoopsOnASingleLine: false
-AllowShortIfStatementsOnASingleLine: Never
diff --git a/.clang-tidy b/.clang-tidy
deleted file mode 100644
index 17ce268..0000000
--- a/.clang-tidy
+++ /dev/null
@@ -1,30 +0,0 @@
-Checks: |
-  -*,
-  abseil-*,
-  bugprone-*,
-  clang-analyzer-*,
-  misc-*,
-  modernize-*,
-  performance-*,
-  portability-*,
-  readability-*,
-  llvm-*,
-  -bugprone-easily-swappable-parameters,
-  -readability-avoid-const-params-in-decls,
-  -readability-identifier-length
-
-CheckOptions:
-  - key: readability-inconsistent-declaration-parameter-name.Strict
-    value: true
-  - key: readability-identifier-naming.StructCase
-    value: lower_case
-  - key: readability-identifier-naming.FunctionCase
-    value: lower_case
-  - key: readability-identifier-naming.VariableCase
-    value: lower_case
-  - key: readability-identifier-naming.EnumConstantCase
-    value: UPPER_CASE
-  - key: readability-identifier-naming.MacroDefinitionCase
-    value: UPPER_CASE
-  - key: readability-function-cognitive-complexity.Threshold
-    value: 15
diff --git a/.clangd b/.clangd
deleted file mode 100644
index f8cd025..0000000
--- a/.clangd
+++ /dev/null
@@ -1,3 +0,0 @@
-Diagnostics:
-  UnusedIncludes: Strict
-  MissingIncludes: Strict
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 93046f4..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-util.o
-stest.o
-stest
-drw.o
-dmenu.o
-dmenu
-compile_commands.json
diff --git a/.woodpecker.yml b/.woodpecker.yml
deleted file mode 100644
index 56c2414..0000000
--- a/.woodpecker.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-when:
-  - event: tag
-  - event: manual
-
-steps:
-  build:
-    image: gcc
-    environment:
-      - BUILD_DEPS=libx11-dev libxinerama-dev libxft-dev libfreetype6-dev libfontconfig1-dev
-    commands: |
-      apt-get update
-      apt-get install -y $${BUILD_DEPS}
-      make install DESTDIR="$${CI_WORKSPACE}/pkg" PREFIX="/usr"
-
-  package-xbps:
-    image: ghcr.io/void-linux/void-musl-busybox
-    environment:
-      - LICENSE=GPL-2.0
-      - SHORT_DESCRIPTION=Customized dwm
-    commands: |
-      xbps-create -A x86_64 \
-                  -H "$${CI_REPO_URL}" \
-                  -l "$${LICENSE}" \
-                  -n "$${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1" \
-                  -m "$${CI_COMMIT_AUTHOR} <$${CI_COMMIT_AUTHOR_EMAIL}>" \
-                  -s "$${SHORT_DESCRIPTION}" \
-                  -c "$${CI_COMMIT_MESSAGE}" \
-                  "$${CI_WORKSPACE}/pkg"
-
-  package-targz:
-    image: alpine
-    commands: |
-      tar czf $${CI_REPO_NAME}-$${CI_COMMIT_TAG}.tar.gz --directory=$${CI_WORKSPACE}/pkg .
-
-  publish:
-    image: woodpeckerci/plugin-gitea-release
-    settings:
-      base_url: https://git.snaile.de
-      files:
-        - "${CI_REPO_NAME}-${CI_COMMIT_TAG}.tar.gz"
-      api_key:
-        from_secret: gitea_release
-      target: main
-
-  publish-xbps:
-    image: ghcr.io/void-linux/void-musl-busybox
-    environment:
-      - XBPS_TARGET_ARCH=x86_64
-    secrets: 
-      - source: xbps_pem_passphrase
-        target: XBPS_PASSPHRASE
-    volumes:
-      - /var/www/xbps:/target
-      - /etc/woodpecker/:/etc/woodpecker:ro
-    commands: |
-      export XBPS_TARGET_ARCH
-      mv $${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1.x86_64.xbps /target
-      xbps-rindex -a /target/$${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1.x86_64.xbps
-      xbps-rindex -S --signedby "$${CI_COMMIT_AUTHOR} <$${CI_COMMIT_AUTHOR_EMAIL}>" --privkey /etc/woodpecker/privkey.pem /target/$${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1.x86_64.xbps
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 2a64b28..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-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-2022 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/Makefile b/Makefile
deleted file mode 100644
index a03a95c..0000000
--- a/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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/arg.h b/arg.h
deleted file mode 100644
index e94e02b..0000000
--- a/arg.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.h b/config.h
deleted file mode 100644
index b917680..0000000
--- a/config.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-/* Default settings; can be overriden by command line. */
-
-static int topbar = 1; /*-b*/
-static int fuzzy = 1; /*-F*/
-static const unsigned int fgalpha = 0xffU;
-static const unsigned int bgalpha = 0xffU;
-/* -fn option overrides fonts[0]; default X11 font or font set */
-static const char *fonts[] = {
-    "FiraCode Nerd Font Mono:pixelsize=14",
-    "Noto Color Emoji:pixelsize=14",
-    "FontAwesome:pixelsize=14"
-};
-static const char *prompt      = NULL;      /* -p  option; prompt to the left of input field */
-static const char *colors[SchemeLast][2] = {
-	/*     fg         bg       */
-	[SchemeNorm] = { "#7aa2f7", "#15161E" },
-	[SchemeSel] = { "#15161E", "#7aa2f7" },
-	[SchemeOut] = { "#15161E", "#7dcfff" },
-};
-
-static const unsigned int alphas[SchemeLast][2] = {
-	[SchemeNorm] = { fgalpha, bgalpha },
-	[SchemeSel] = { fgalpha, bgalpha },
-	[SchemeOut] = { fgalpha, bgalpha },
-};
-
-/* -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.mk b/config.mk
deleted file mode 100644
index 8cea37a..0000000
--- a/config.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# dmenu version
-VERSION = 5.2
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = $(PREFIX)/share/man
-
-X11INC = /usr/include/X11
-X11LIB = /usr/lib/X11
-
-# 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
-#MANPREFIX = ${PREFIX}/man
-
-# includes and libs
-INCS = -I$(X11INC) -I$(FREETYPEINC)
-LIBS = -L$(X11LIB) -lXrender -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm
-
-# 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/dmenu.1 b/dmenu.1
deleted file mode 100644
index 8189e15..0000000
--- a/dmenu.1
+++ /dev/null
@@ -1,200 +0,0 @@
-.TH DMENU 1 dmenu\-VERSION
-.SH NAME
-dmenu \- dynamic menu
-.SH SYNOPSIS
-.B dmenu
-.RB [ \-bfirvP ]
-.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
-.B \-r
-dmenu will reject any input which would result in no matching option left.
-.TP
-.B \-P
-dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
-.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
deleted file mode 100644
index 944be4e..0000000
--- a/dmenu.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <ctype.h>
-#include <locale.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-/* macros */
-#define INTERSECT(x,y,w,h,r)  (MAX(0, MIN((x)+(w),(r).x_org+(r).width)  - MAX((x),(r).x_org)) \
-                             * 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)
-
-/* enums */
-enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
-
-struct item {
-	char *text;
-	struct item *left, *right;
-	int out;
-	double distance;
-};
-
-static char text[BUFSIZ] = "";
-static char *embed;
-static int bh, mw, mh;
-static int inputw = 0, promptw, passwd = 0;
-static int lrpad; /* sum of left and right padding */
-static int reject_no_match = 0;
-static size_t cursor;
-static struct item *items = NULL;
-static struct item *matches, *matchend;
-static struct item *prev, *curr, *next, *sel;
-static int mon = -1, screen;
-
-static Atom clip, utf8;
-static Display *dpy;
-static Window root, parentwin, win;
-static XIC xic;
-
-static Drw *drw;
-static Clr *scheme[SchemeLast];
-
-static int useargb = 0;
-static Visual *visual;
-static int depth;
-static Colormap cmap;
-
-#include "config.h"
-
-static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
-static char *(*fstrstr)(const char *, const char *) = strstr;
-static void xinitvisual();
-
-static unsigned int
-textw_clamp(const char *str, unsigned int n)
-{
-	unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad;
-	return MIN(w, n);
-}
-
-static void
-appenditem(struct item *item, struct item **list, struct item **last)
-{
-	if (*last)
-		(*last)->right = item;
-	else
-		*list = item;
-
-	item->left = *last;
-	item->right = NULL;
-	*last = item;
-}
-
-static void
-calcoffsets(void)
-{
-	int i, n;
-
-	if (lines > 0)
-		n = lines * bh;
-	else
-		n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
-	/* calculate which items will begin the next page and previous page */
-	for (i = 0, next = curr; next; next = next->right)
-		if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n)
-			break;
-	for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
-		if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n)
-			break;
-}
-
-static void
-cleanup(void)
-{
-	size_t i;
-
-	XUngrabKey(dpy, AnyKey, AnyModifier, root);
-	for (i = 0; i < SchemeLast; i++)
-		free(scheme[i]);
-	for (i = 0; items && items[i].text; ++i)
-		free(items[i].text);
-	free(items);
-	drw_free(drw);
-	XSync(dpy, False);
-	XCloseDisplay(dpy);
-}
-
-static char *
-cistrstr(const char *h, const char *n)
-{
-	size_t i;
-
-	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;
-}
-
-static int
-drawitem(struct item *item, int x, int y, int w)
-{
-	if (item == sel)
-		drw_setscheme(drw, scheme[SchemeSel]);
-	else if (item->out)
-		drw_setscheme(drw, scheme[SchemeOut]);
-	else
-		drw_setscheme(drw, scheme[SchemeNorm]);
-
-	return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
-}
-
-static void
-drawmenu(void)
-{
-	unsigned int curpos;
-	struct item *item;
-	int x = 0, y = 0, w;
-	char *censort;
-
-	drw_setscheme(drw, scheme[SchemeNorm]);
-	drw_rect(drw, 0, 0, mw, mh, 1, 1);
-
-	if (prompt && *prompt) {
-		drw_setscheme(drw, scheme[SchemeSel]);
-		x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0);
-	}
-	/* draw input field */
-	w = (lines > 0 || !matches) ? mw - x : inputw;
-	drw_setscheme(drw, scheme[SchemeNorm]);
-	if (passwd) {
-	        censort = ecalloc(1, sizeof(text));
-		memset(censort, '.', strlen(text));
-		drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0);
-		free(censort);
-	} else drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
-
-	curpos = TEXTW(text) - TEXTW(&text[cursor]);
-	if ((curpos += lrpad / 2 - 1) < w) {
-		drw_setscheme(drw, scheme[SchemeNorm]);
-		drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
-	}
-
-	if (lines > 0) {
-		/* draw vertical list */
-		for (item = curr; item != next; item = item->right)
-			drawitem(item, x, y += bh, mw - x);
-	} else if (matches) {
-		/* draw horizontal list */
-		x += inputw;
-		w = TEXTW("<");
-		if (curr->left) {
-			drw_setscheme(drw, scheme[SchemeNorm]);
-			drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0);
-		}
-		x += w;
-		for (item = curr; item != next; item = item->right)
-			x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">")));
-		if (next) {
-			w = TEXTW(">");
-			drw_setscheme(drw, scheme[SchemeNorm]);
-			drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
-		}
-	}
-	drw_map(drw, win, 0, 0, mw, mh);
-}
-
-static void
-grabfocus(void)
-{
-	struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000  };
-	Window focuswin;
-	int i, revertwin;
-
-	for (i = 0; i < 100; ++i) {
-		XGetInputFocus(dpy, &focuswin, &revertwin);
-		if (focuswin == win)
-			return;
-		XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
-		nanosleep(&ts, NULL);
-	}
-	die("cannot grab focus");
-}
-
-static void
-grabkeyboard(void)
-{
-	struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000  };
-	int i;
-
-	if (embed)
-		return;
-	/* try to grab keyboard, we may have to wait for another process to ungrab */
-	for (i = 0; i < 1000; i++) {
-		if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
-		                  GrabModeAsync, CurrentTime) == GrabSuccess)
-			return;
-		nanosleep(&ts, NULL);
-	}
-	die("cannot grab keyboard");
-}
-
-int
-compare_distance(const void *a, const void *b)
-{
-	struct item *da = *(struct item **) a;
-	struct item *db = *(struct item **) b;
-
-	if (!db)
-		return 1;
-	if (!da)
-		return -1;
-
-	return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1;
-}
-
-void
-fuzzymatch(void)
-{
-	/* bang - we have so much memory */
-	struct item *it;
-	struct item **fuzzymatches = NULL;
-	char c;
-	int number_of_matches = 0, i, pidx, sidx, eidx;
-	int text_len = strlen(text), itext_len;
-
-	matches = matchend = NULL;
-
-	/* walk through all items */
-	for (it = items; it && it->text; it++) {
-		if (text_len) {
-			itext_len = strlen(it->text);
-			pidx = 0; /* pointer */
-			sidx = eidx = -1; /* start of match, end of match */
-			/* walk through item text */
-			for (i = 0; i < itext_len && (c = it->text[i]); i++) {
-				/* fuzzy match pattern */
-				if (!fstrncmp(&text[pidx], &c, 1)) {
-					if(sidx == -1)
-						sidx = i;
-					pidx++;
-					if (pidx == text_len) {
-						eidx = i;
-						break;
-					}
-				}
-			}
-			/* build list of matches */
-			if (eidx != -1) {
-				/* compute distance */
-				/* add penalty if match starts late (log(sidx+2))
-				 * add penalty for long a match without many matching characters */
-				it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len);
-				/* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */
-				appenditem(it, &matches, &matchend);
-				number_of_matches++;
-			}
-		} else {
-			appenditem(it, &matches, &matchend);
-		}
-	}
-
-	if (number_of_matches) {
-		/* initialize array with matches */
-		if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*))))
-			die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*));
-		for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) {
-			fuzzymatches[i] = it;
-		}
-		/* sort matches according to distance */
-		qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
-		/* rebuild list of matches */
-		matches = matchend = NULL;
-		for (i = 0, it = fuzzymatches[i];  i < number_of_matches && it && \
-				it->text; i++, it = fuzzymatches[i]) {
-			appenditem(it, &matches, &matchend);
-		}
-		free(fuzzymatches);
-	}
-	curr = sel = matches;
-	calcoffsets();
-}
-
-static void
-match(void)
-{
-	if (fuzzy) {
-		fuzzymatch();
-		return;
-	}
-	static char **tokv = NULL;
-	static int tokn = 0;
-
-	char buf[sizeof text], *s;
-	int i, tokc = 0;
-	size_t len, textsize;
-	struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
-
-	strcpy(buf, text);
-	/* separate input text into tokens to be matched individually */
-	for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
-		if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
-			die("cannot realloc %zu bytes:", tokn * sizeof *tokv);
-	len = tokc ? strlen(tokv[0]) : 0;
-
-	matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
-	textsize = strlen(text) + 1;
-	for (item = items; item && item->text; item++) {
-		for (i = 0; i < tokc; i++)
-			if (!fstrstr(item->text, tokv[i]))
-				break;
-		if (i != tokc) /* not all tokens match */
-			continue;
-		/* exact matches go first, then prefixes, then substrings */
-		if (!tokc || !fstrncmp(text, item->text, textsize))
-			appenditem(item, &matches, &matchend);
-		else if (!fstrncmp(tokv[0], item->text, len))
-			appenditem(item, &lprefix, &prefixend);
-		else
-			appenditem(item, &lsubstr, &substrend);
-	}
-	if (lprefix) {
-		if (matches) {
-			matchend->right = lprefix;
-			lprefix->left = matchend;
-		} else
-			matches = lprefix;
-		matchend = prefixend;
-	}
-	if (lsubstr) {
-		if (matches) {
-			matchend->right = lsubstr;
-			lsubstr->left = matchend;
-		} else
-			matches = lsubstr;
-		matchend = substrend;
-	}
-	curr = sel = matches;
-	calcoffsets();
-}
-
-static void
-insert(const char *str, ssize_t n)
-{
-	if (strlen(text) + n > sizeof text - 1)
-		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 */
-	memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
-	if (n > 0)
-		memcpy(&text[cursor], str, n);
-	cursor += n;
-	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
-nextrune(int inc)
-{
-	ssize_t n;
-
-	/* return location of next utf8 rune in the given direction (+1 or -1) */
-	for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc)
-		;
-	return n;
-}
-
-static void
-movewordedge(int dir)
-{
-	if (dir < 0) { /* move cursor to the start of the word*/
-		while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
-			cursor = nextrune(-1);
-		while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
-			cursor = nextrune(-1);
-	} else { /* move cursor to the end of the word */
-		while (text[cursor] && strchr(worddelimiters, text[cursor]))
-			cursor = nextrune(+1);
-		while (text[cursor] && !strchr(worddelimiters, text[cursor]))
-			cursor = nextrune(+1);
-	}
-}
-
-static void
-keypress(XKeyEvent *ev)
-{
-	char buf[64];
-	int len;
-	KeySym ksym = NoSymbol;
-	Status status;
-
-	len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
-	switch (status) {
-	default: /* XLookupNone, XBufferOverflow */
-		return;
-	case XLookupChars: /* composed string from input method */
-		goto insert;
-	case XLookupKeySym:
-	case XLookupBoth: /* a KeySym and a string are returned: use keysym */
-		break;
-	}
-
-	if (ev->state & ControlMask) {
-		switch(ksym) {
-		case XK_a: ksym = XK_Home;      break;
-		case XK_b: ksym = XK_Left;      break;
-		case XK_c: ksym = XK_Escape;    break;
-		case XK_d: ksym = XK_Delete;    break;
-		case XK_e: ksym = XK_End;       break;
-		case XK_f: ksym = XK_Right;     break;
-		case XK_g: ksym = XK_Escape;    break;
-		case XK_h: ksym = XK_BackSpace; break;
-		case XK_i: ksym = XK_Tab;       break;
-		case XK_j: /* fallthrough */
-		case XK_J: /* fallthrough */
-		case XK_m: /* fallthrough */
-		case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
-		case XK_n: ksym = XK_Down;      break;
-		case XK_p: ksym = XK_Up;        break;
-
-		case XK_k: /* delete right */
-			text[cursor] = '\0';
-			match();
-			break;
-		case XK_u: /* delete left */
-			insert(NULL, 0 - cursor);
-			break;
-		case XK_w: /* delete word */
-			while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
-				insert(NULL, nextrune(-1) - cursor);
-			while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
-				insert(NULL, nextrune(-1) - cursor);
-			break;
-		case XK_y: /* paste selection */
-		case XK_Y:
-			XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
-			                  utf8, utf8, win, CurrentTime);
-			return;
-		case XK_Left:
-		case XK_KP_Left:
-			movewordedge(-1);
-			goto draw;
-		case XK_Right:
-		case XK_KP_Right:
-			movewordedge(+1);
-			goto draw;
-		case XK_Return:
-		case XK_KP_Enter:
-			break;
-		case XK_bracketleft:
-			cleanup();
-			exit(1);
-		default:
-			return;
-		}
-	} else if (ev->state & Mod1Mask) {
-		switch(ksym) {
-		case XK_b:
-			movewordedge(-1);
-			goto draw;
-		case XK_f:
-			movewordedge(+1);
-			goto draw;
-		case XK_g: ksym = XK_Home;  break;
-		case XK_G: ksym = XK_End;   break;
-		case XK_h: ksym = XK_Up;    break;
-		case XK_j: ksym = XK_Next;  break;
-		case XK_k: ksym = XK_Prior; break;
-		case XK_l: ksym = XK_Down;  break;
-		default:
-			return;
-		}
-	}
-
-	switch(ksym) {
-	default:
-insert:
-		if (!iscntrl((unsigned char)*buf))
-			insert(buf, len);
-		break;
-	case XK_Delete:
-	case XK_KP_Delete:
-		if (text[cursor] == '\0')
-			return;
-		cursor = nextrune(+1);
-		/* fallthrough */
-	case XK_BackSpace:
-		if (cursor == 0)
-			return;
-		insert(NULL, nextrune(-1) - cursor);
-		break;
-	case XK_End:
-	case XK_KP_End:
-		if (text[cursor] != '\0') {
-			cursor = strlen(text);
-			break;
-		}
-		if (next) {
-			/* jump to end of list and position items in reverse */
-			curr = matchend;
-			calcoffsets();
-			curr = prev;
-			calcoffsets();
-			while (next && (curr = curr->right))
-				calcoffsets();
-		}
-		sel = matchend;
-		break;
-	case XK_Escape:
-		cleanup();
-		exit(1);
-	case XK_Home:
-	case XK_KP_Home:
-		if (sel == matches) {
-			cursor = 0;
-			break;
-		}
-		sel = curr = matches;
-		calcoffsets();
-		break;
-	case XK_Left:
-	case XK_KP_Left:
-		if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
-			cursor = nextrune(-1);
-			break;
-		}
-		if (lines > 0)
-			return;
-		/* fallthrough */
-	case XK_Up:
-	case XK_KP_Up:
-		if (sel && sel->left && (sel = sel->left)->right == curr) {
-			curr = prev;
-			calcoffsets();
-		}
-		break;
-	case XK_Next:
-	case XK_KP_Next:
-		if (!next)
-			return;
-		sel = curr = next;
-		calcoffsets();
-		break;
-	case XK_Prior:
-	case XK_KP_Prior:
-		if (!prev)
-			return;
-		sel = curr = prev;
-		calcoffsets();
-		break;
-	case XK_Return:
-	case XK_KP_Enter:
-		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
-		if (!(ev->state & ControlMask)) {
-			cleanup();
-			exit(0);
-		}
-		if (sel)
-			sel->out = 1;
-		break;
-	case XK_Right:
-	case XK_KP_Right:
-		if (text[cursor] != '\0') {
-			cursor = nextrune(+1);
-			break;
-		}
-		if (lines > 0)
-			return;
-		/* fallthrough */
-	case XK_Down:
-	case XK_KP_Down:
-		if (sel && sel->right && (sel = sel->right) == next) {
-			curr = next;
-			calcoffsets();
-		}
-		break;
-	case XK_Tab:
-		if (!sel)
-			return;
-		cursor = strnlen(sel->text, sizeof text - 1);
-		memcpy(text, sel->text, cursor);
-		text[cursor] = '\0';
-		match();
-		break;
-	}
-
-draw:
-	drawmenu();
-}
-
-static void
-paste(void)
-{
-	char *p, *q;
-	int di;
-	unsigned long dl;
-	Atom da;
-
-	/* we have been given the current selection, now insert it into input */
-	if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
-	                   utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
-	    == Success && p) {
-		insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
-		XFree(p);
-	}
-	drawmenu();
-}
-
-static void
-readstdin(void)
-{
-	char *line = NULL;
-	size_t i, junk, itemsiz = 0;
-	ssize_t len;
-	if(passwd){
-    	inputw = lines = 0;
-    	return;
-  	}
-
-
-	/* read each line from stdin and add it to the item list */
-	for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) {
-		if (i + 1 >= itemsiz) {
-			itemsiz += 256;
-			if (!(items = realloc(items, itemsiz * sizeof(*items))))
-				die("cannot realloc %zu bytes:", itemsiz * sizeof(*items));
-		}
-		if (line[len - 1] == '\n')
-			line[len - 1] = '\0';
-		items[i].text = line;
-		items[i].out = 0;
-		line = NULL; /* next call of getline() allocates a new line */
-	}
-	free(line);
-	if (items)
-		items[i].text = NULL;
-	lines = MIN(lines, i);
-}
-
-static void
-run(void)
-{
-	XEvent ev;
-
-	while (!XNextEvent(dpy, &ev)) {
-		if (XFilterEvent(&ev, win))
-			continue;
-		switch(ev.type) {
-		case DestroyNotify:
-			if (ev.xdestroywindow.window != win)
-				break;
-			cleanup();
-			exit(1);
-		case Expose:
-			if (ev.xexpose.count == 0)
-				drw_map(drw, win, 0, 0, mw, mh);
-			break;
-		case FocusIn:
-			/* regrab focus from parent window */
-			if (ev.xfocus.window != win)
-				grabfocus();
-			break;
-		case KeyPress:
-			keypress(&ev.xkey);
-			break;
-		case SelectionNotify:
-			if (ev.xselection.property == utf8)
-				paste();
-			break;
-		case VisibilityNotify:
-			if (ev.xvisibility.state != VisibilityUnobscured)
-				XRaiseWindow(dpy, win);
-			break;
-		}
-	}
-}
-
-static void
-setup(void)
-{
-	int x, y, i, j;
-	unsigned int du;
-	XSetWindowAttributes swa;
-	XIM xim;
-	Window w, dw, *dws;
-	XWindowAttributes wa;
-	XClassHint ch = {"dmenu", "dmenu"};
-#ifdef XINERAMA
-	XineramaScreenInfo *info;
-	Window pw;
-	int a, di, n, area = 0;
-#endif
-	/* init appearance */
-	for (j = 0; j < SchemeLast; j++)
-		scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2);
-
-	clip = XInternAtom(dpy, "CLIPBOARD",   False);
-	utf8 = XInternAtom(dpy, "UTF8_STRING", False);
-
-	/* calculate menu geometry */
-	bh = drw->fonts->h + 2;
-	lines = MAX(lines, 0);
-	mh = (lines + 1) * bh;
-#ifdef XINERAMA
-	i = 0;
-	if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
-		XGetInputFocus(dpy, &w, &di);
-		if (mon >= 0 && mon < n)
-			i = mon;
-		else if (w != root && w != PointerRoot && w != None) {
-			/* find top-level window containing current input focus */
-			do {
-				if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
-					XFree(dws);
-			} while (w != root && w != pw);
-			/* find xinerama screen with which the window intersects most */
-			if (XGetWindowAttributes(dpy, pw, &wa))
-				for (j = 0; j < n; j++)
-					if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
-						area = a;
-						i = j;
-					}
-		}
-		/* no focused window is on screen, so use pointer location instead */
-		if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
-			for (i = 0; i < n; i++)
-				if (INTERSECT(x, y, 1, 1, info[i]) != 0)
-					break;
-
-		x = info[i].x_org;
-		y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
-		mw = info[i].width;
-
-		XFree(info);
-	} else
-#endif
-	{
-		if (!XGetWindowAttributes(dpy, parentwin, &wa))
-			die("could not get embedding window attributes: 0x%lx",
-			    parentwin);
-		x = 0;
-		y = topbar ? 0 : wa.height - mh;
-		mw = wa.width;
-	}
-	promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
-	inputw = mw / 3; /* input width: ~33% of monitor width */
-	match();
-
-	/* create menu window */
-	swa.override_redirect = True;
-	swa.background_pixel = 0;
-	swa.border_pixel = 0;
-	swa.colormap = cmap;
-	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
-	win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
-	                    depth, CopyFromParent, visual,
-	                    CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
-	XSetClassHint(dpy, win, &ch);
-
-
-	/* input methods */
-	if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
-		die("XOpenIM failed: could not open input device");
-
-	xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
-	                XNClientWindow, win, XNFocusWindow, win, NULL);
-
-	XMapRaised(dpy, win);
-	if (embed) {
-		XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
-		if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
-			for (i = 0; i < du && dws[i] != win; ++i)
-				XSelectInput(dpy, dws[i], FocusChangeMask);
-			XFree(dws);
-		}
-		grabfocus();
-	}
-	drw_resize(drw, mw, mh);
-	drawmenu();
-}
-
-static void
-usage(void)
-{
-	die("usage: dmenu [-bfirvP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-	    "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]");
-}
-
-int
-main(int argc, char *argv[])
-{
-	XWindowAttributes wa;
-	int i, fast = 0;
-
-	for (i = 1; i < argc; i++)
-		/* these options take no arguments */
-		if (!strcmp(argv[i], "-v")) {      /* prints version information */
-			puts("dmenu-"VERSION);
-			exit(0);
-		} else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
-			topbar = 0;
-		else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
-			fast = 1;
-		else if (!strcmp(argv[i], "-F"))   /* grabs keyboard before reading stdin */
-			fuzzy = 0;
-		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
-			fstrncmp = strncasecmp;
-			fstrstr = cistrstr;
-		} else if (!strcmp(argv[i], "-P"))   /* is the input a password */
-			passwd = 1;
-		else if (!strcmp(argv[i], "-r")) /* reject input which results in no match */
-			reject_no_match = 1;
-		else if (i + 1 == argc)
-			usage();
-		/* these options take one argument */
-		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
-			lines = atoi(argv[++i]);
-		else if (!strcmp(argv[i], "-m"))
-			mon = atoi(argv[++i]);
-		else if (!strcmp(argv[i], "-p"))   /* adds prompt to left of input field */
-			prompt = argv[++i];
-		else if (!strcmp(argv[i], "-fn"))  /* font or font set */
-			fonts[0] = argv[++i];
-		else if (!strcmp(argv[i], "-nb"))  /* normal background color */
-			colors[SchemeNorm][ColBg] = argv[++i];
-		else if (!strcmp(argv[i], "-nf"))  /* normal foreground color */
-			colors[SchemeNorm][ColFg] = argv[++i];
-		else if (!strcmp(argv[i], "-sb"))  /* selected background color */
-			colors[SchemeSel][ColBg] = argv[++i];
-		else if (!strcmp(argv[i], "-sf"))  /* selected foreground color */
-			colors[SchemeSel][ColFg] = argv[++i];
-		else if (!strcmp(argv[i], "-w"))   /* embedding window id */
-			embed = argv[++i];
-		else
-			usage();
-
-	if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
-		fputs("warning: no locale support\n", stderr);
-	if (!(dpy = XOpenDisplay(NULL)))
-		die("cannot open display");
-	screen = DefaultScreen(dpy);
-	root = RootWindow(dpy, screen);
-	if (!embed || !(parentwin = strtol(embed, NULL, 0)))
-		parentwin = root;
-	if (!XGetWindowAttributes(dpy, parentwin, &wa))
-		die("could not get embedding window attributes: 0x%lx",
-		    parentwin);
-	xinitvisual();
-	drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
-	if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
-		die("no fonts could be loaded.");
-	lrpad = drw->fonts->h;
-
-#ifdef __OpenBSD__
-	if (pledge("stdio rpath", NULL) == -1)
-		die("pledge");
-#endif
-
-	if (fast && !isatty(0)) {
-		grabkeyboard();
-		readstdin();
-	} else {
-		readstdin();
-		grabkeyboard();
-	}
-	setup();
-	run();
-
-	return 1; /* unreachable */
-}
-
- void
-xinitvisual()
-{
-	XVisualInfo *infos;
-	XRenderPictFormat *fmt;
-	int nitems;
-	int i;
-
-	XVisualInfo tpl = {
-		.screen = screen,
-		.depth = 32,
-		.class = TrueColor
-	};
-	long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
-
-	infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
-	visual = NULL;
-	for(i = 0; i < nitems; i ++) {
-		fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
-		if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
-			visual = infos[i].visual;
-			depth = infos[i].depth;
-			cmap = XCreateColormap(dpy, root, visual, AllocNone);
-			useargb = 1;
-			break;
-		}
-	}
-
-	XFree(infos);
-
-	if (! visual) {
-		visual = DefaultVisual(dpy, screen);
-		depth = DefaultDepth(dpy, screen);
-		cmap = DefaultColormap(dpy, screen);
-	}
-}
diff --git a/dmenu_path b/dmenu_path
deleted file mode 100755
index 3a7cda7..0000000
--- a/dmenu_path
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/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/dmenu_run b/dmenu_run
deleted file mode 100755
index 834ede5..0000000
--- a/dmenu_run
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
diff --git a/drw.c b/drw.c
deleted file mode 100644
index 42700e5..0000000
--- a/drw.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/* 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, Visual *visual, unsigned int depth, Colormap cmap)
-{
-	Drw *drw = ecalloc(1, sizeof(Drw));
-
-	drw->dpy = dpy;
-	drw->screen = screen;
-	drw->root = root;
-	drw->w = w;
-	drw->h = h;
-	drw->visual = visual;
-	drw->depth = depth;
-	drw->cmap = cmap;
-	drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
-	drw->gc = XCreateGC(dpy, drw->drawable, 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, drw->depth);
-}
-
-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, unsigned int alpha)
-{
-	if (!drw || !dest || !clrname)
-		return;
-
-	if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
-	                       clrname, dest))
-		die("error, cannot allocate color '%s'", clrname);
-
-	dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
-}
-
-/* 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[], const unsigned int alphas[], 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], alphas[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)
-{
-	int i, ty, ellipsis_x = 0;
-	unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
-	XftDraw *d = NULL;
-	Fnt *usedfont, *curfont, *nextfont;
-	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, overflow = 0;
-	/* keep track of a couple codepoints for which we have no match. */
-	enum { nomatches_len = 64 };
-	static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
-	static unsigned int ellipsis_width = 0;
-
-	if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
-		return 0;
-
-	if (!render) {
-		w = invert ? invert : ~invert;
-	} 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, drw->visual, drw->cmap);
-		x += lpad;
-		w -= lpad;
-	}
-
-	usedfont = drw->fonts;
-	if (!ellipsis_width && render)
-		ellipsis_width = drw_fontset_getwidth(drw, "...");
-	while (1) {
-		ew = ellipsis_len = 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) {
-					drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
-					if (ew + ellipsis_width <= w) {
-						/* keep track where the ellipsis still fits */
-						ellipsis_x = x + ew;
-						ellipsis_w = w - ew;
-						ellipsis_len = utf8strlen;
-					}
-
-					if (ew + tmpw > w) {
-						overflow = 1;
-						/* called from drw_fontset_getwidth_clamp():
-						 * it wants the width AFTER the overflow
-						 */
-						if (!render)
-							x += tmpw;
-						else
-							utf8strlen = ellipsis_len;
-					} else if (curfont == usedfont) {
-						utf8strlen += utf8charlen;
-						text += utf8charlen;
-						ew += tmpw;
-					} else {
-						nextfont = curfont;
-					}
-					break;
-				}
-			}
-
-			if (overflow || !charexists || nextfont)
-				break;
-			else
-				charexists = 0;
-		}
-
-		if (utf8strlen) {
-			if (render) {
-				ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
-				XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
-				                  usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
-			}
-			x += ew;
-			w -= ew;
-		}
-		if (render && overflow)
-			drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
-
-		if (!*text || overflow) {
-			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;
-
-			for (i = 0; i < nomatches_len; ++i) {
-				/* avoid calling XftFontMatch if we know we won't find a match */
-				if (utf8codepoint == nomatches.codepoint[i])
-					goto no_match;
-			}
-
-			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);
-
-			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);
-					nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
-no_match:
-					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);
-}
-
-unsigned int
-drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
-{
-	unsigned int tmp = 0;
-	if (drw && drw->fonts && text && n)
-		tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
-	return MIN(n, tmp);
-}
-
-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/drw.h b/drw.h
deleted file mode 100644
index 48f2f93..0000000
--- a/drw.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* 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;
-	Visual *visual;
-	unsigned int depth;
-	Colormap cmap;
-	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, Visual*, unsigned int, Colormap);
-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);
-unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
-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, unsigned int alpha);
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], 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/patches/dmenu-alpha-20210605-1a13d04.diff b/patches/dmenu-alpha-20210605-1a13d04.diff
deleted file mode 100644
index 51679f7..0000000
--- a/patches/dmenu-alpha-20210605-1a13d04.diff
+++ /dev/null
@@ -1,267 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 1edb647..697d511 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -2,6 +2,7 @@
- /* Default settings; can be overriden by command line. */
- 
- static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
-+static const unsigned int alpha = 0xf0;
- /* -fn option overrides fonts[0]; default X11 font or font set */
- static const char *fonts[] = {
- 	"monospace:size=10"
-@@ -13,6 +14,13 @@ static const char *colors[SchemeLast][2] = {
- 	[SchemeSel] = { "#eeeeee", "#005577" },
- 	[SchemeOut] = { "#000000", "#00ffff" },
- };
-+
-+static const unsigned int alphas[SchemeLast][2] = {
-+	[SchemeNorm] = { OPAQUE, alpha },
-+	[SchemeSel] = { OPAQUE, alpha },
-+	[SchemeOut] = { OPAQUE, alpha },
-+};
-+
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
- static unsigned int lines      = 0;
- 
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..3e56e1a 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -10,6 +10,7 @@
- 
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
-+#include <X11/Xproto.h>
- #include <X11/Xutil.h>
- #ifdef XINERAMA
- #include <X11/extensions/Xinerama.h>
-@@ -25,6 +26,8 @@
- #define LENGTH(X)             (sizeof X / sizeof X[0])
- #define TEXTW(X)              (drw_fontset_getwidth(drw, (X)) + lrpad)
- 
-+#define OPAQUE                0xffU
-+
- /* enums */
- enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
- 
-@@ -53,10 +56,16 @@ static XIC xic;
- static Drw *drw;
- static Clr *scheme[SchemeLast];
- 
-+static int useargb = 0;
-+static Visual *visual;
-+static int depth;
-+static Colormap cmap;
-+
- #include "config.h"
- 
- static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
- static char *(*fstrstr)(const char *, const char *) = strstr;
-+static void xinitvisual();
- 
- static void
- appenditem(struct item *item, struct item **list, struct item **last)
-@@ -602,7 +611,7 @@ setup(void)
- #endif
- 	/* init appearance */
- 	for (j = 0; j < SchemeLast; j++)
--		scheme[j] = drw_scm_create(drw, colors[j], 2);
-+		scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2);
- 
- 	clip = XInternAtom(dpy, "CLIPBOARD",   False);
- 	utf8 = XInternAtom(dpy, "UTF8_STRING", False);
-@@ -640,6 +649,7 @@ setup(void)
- 		x = info[i].x_org;
- 		y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
- 		mw = info[i].width;
-+
- 		XFree(info);
- 	} else
- #endif
-@@ -657,11 +667,13 @@ setup(void)
- 
- 	/* create menu window */
- 	swa.override_redirect = True;
--	swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+	swa.background_pixel = 0;
-+	swa.border_pixel = 0;
-+	swa.colormap = cmap;
- 	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
--	win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
--	                    CopyFromParent, CopyFromParent, CopyFromParent,
--	                    CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
-+	win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
-+	                    depth, CopyFromParent, visual,
-+	                    CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
- 	XSetClassHint(dpy, win, &ch);
- 
- 
-@@ -747,7 +759,8 @@ main(int argc, char *argv[])
- 	if (!XGetWindowAttributes(dpy, parentwin, &wa))
- 		die("could not get embedding window attributes: 0x%lx",
- 		    parentwin);
--	drw = drw_create(dpy, screen, root, wa.width, wa.height);
-+	xinitvisual();
-+	drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
- 	if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
- 		die("no fonts could be loaded.");
- 	lrpad = drw->fonts->h;
-@@ -769,3 +782,40 @@ main(int argc, char *argv[])
- 
- 	return 1; /* unreachable */
- }
-+
-+ void
-+xinitvisual()
-+{
-+	XVisualInfo *infos;
-+	XRenderPictFormat *fmt;
-+	int nitems;
-+	int i;
-+
-+	XVisualInfo tpl = {
-+		.screen = screen,
-+		.depth = 32,
-+		.class = TrueColor
-+	};
-+	long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
-+
-+	infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
-+	visual = NULL;
-+	for(i = 0; i < nitems; i ++) {
-+		fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
-+		if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
-+			visual = infos[i].visual;
-+			depth = infos[i].depth;
-+			cmap = XCreateColormap(dpy, root, visual, AllocNone);
-+			useargb = 1;
-+			break;
-+		}
-+	}
-+
-+	XFree(infos);
-+
-+	if (! visual) {
-+		visual = DefaultVisual(dpy, screen);
-+		depth = DefaultDepth(dpy, screen);
-+		cmap = DefaultColormap(dpy, screen);
-+	}
-+}
-diff --git a/drw.c b/drw.c
-index 4cdbcbe..fe3aadd 100644
---- a/drw.c
-+++ b/drw.c
-@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
- }
- 
- Drw *
--drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
-+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
- {
- 	Drw *drw = ecalloc(1, sizeof(Drw));
- 
-@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
- 	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);
-+	drw->visual = visual;
-+	drw->depth = depth;
-+	drw->cmap = cmap;
-+	drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
-+	drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
- 	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
- 
- 	return drw;
-@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
- 	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));
-+	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
- }
- 
- void
-@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font)
- }
- 
- void
--drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
-+drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
- {
- 	if (!drw || !dest || !clrname)
- 		return;
- 
--	if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
--	                       DefaultColormap(drw->dpy, drw->screen),
-+	if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
- 	                       clrname, dest))
- 		die("error, cannot allocate color '%s'", clrname);
-+
-+	dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
- }
- 
- /* 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)
-+drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
- {
- 	size_t i;
- 	Clr *ret;
-@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
- 		return NULL;
- 
- 	for (i = 0; i < clrcount; i++)
--		drw_clr_create(drw, &ret[i], clrnames[i]);
-+		drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
- 	return ret;
- }
- 
-@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
- 	} 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));
-+		d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
- 		x += lpad;
- 		w -= lpad;
- 	}
-diff --git a/drw.h b/drw.h
-index 4c67419..f6fa5cd 100644
---- a/drw.h
-+++ b/drw.h
-@@ -20,6 +20,9 @@ typedef struct {
- 	Display *dpy;
- 	int screen;
- 	Window root;
-+	Visual *visual;
-+	unsigned int depth;
-+	Colormap cmap;
- 	Drawable drawable;
- 	GC gc;
- 	Clr *scheme;
-@@ -27,7 +30,7 @@ typedef struct {
- } Drw;
- 
- /* Drawable abstraction */
--Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
-+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap);
- void drw_resize(Drw *drw, unsigned int w, unsigned int h);
- void drw_free(Drw *drw);
- 
-@@ -38,8 +41,8 @@ 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);
-+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
-+Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
- 
- /* Cursor abstraction */
- Cur *drw_cur_create(Drw *drw, int shape);
diff --git a/patches/dmenu-fuzzymatch-4.9.diff b/patches/dmenu-fuzzymatch-4.9.diff
deleted file mode 100644
index 9fd206d..0000000
--- a/patches/dmenu-fuzzymatch-4.9.diff
+++ /dev/null
@@ -1,163 +0,0 @@
-From 94353eb52055927d9079f3d9e33da1c954abf386 Mon Sep 17 00:00:00 2001
-From: aleks <aleks.stier@icloud.com>
-Date: Wed, 26 Jun 2019 13:25:10 +0200
-Subject: [PATCH] Add support for fuzzy-matching
-
----
- config.def.h |  1 +
- config.mk    |  2 +-
- dmenu.c      | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 91 insertions(+), 1 deletion(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1edb647..51612b9 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -2,6 +2,7 @@
- /* Default settings; can be overriden by command line. */
- 
- static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
-+static int fuzzy = 1;                      /* -F  option; if 0, dmenu doesn't use fuzzy matching     */
- /* -fn option overrides fonts[0]; default X11 font or font set */
- static const char *fonts[] = {
- 	"monospace:size=10"
-diff --git a/config.mk b/config.mk
-index 0929b4a..d14309a 100644
---- a/config.mk
-+++ b/config.mk
-@@ -20,7 +20,7 @@ FREETYPEINC = /usr/include/freetype2
- 
- # includes and libs
- INCS = -I$(X11INC) -I$(FREETYPEINC)
--LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
-+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm
- 
- # flags
- CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
-diff --git a/dmenu.c b/dmenu.c
-index 6b8f51b..96ddc98 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -1,6 +1,7 @@
- /* See LICENSE file for copyright and license details. */
- #include <ctype.h>
- #include <locale.h>
-+#include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -32,6 +33,7 @@ struct item {
- 	char *text;
- 	struct item *left, *right;
- 	int out;
-+	double distance;
- };
- 
- static char text[BUFSIZ] = "";
-@@ -210,9 +212,94 @@ grabkeyboard(void)
- 	die("cannot grab keyboard");
- }
- 
-+int
-+compare_distance(const void *a, const void *b)
-+{
-+	struct item *da = *(struct item **) a;
-+	struct item *db = *(struct item **) b;
-+
-+	if (!db)
-+		return 1;
-+	if (!da)
-+		return -1;
-+
-+	return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1;
-+}
-+
-+void
-+fuzzymatch(void)
-+{
-+	/* bang - we have so much memory */
-+	struct item *it;
-+	struct item **fuzzymatches = NULL;
-+	char c;
-+	int number_of_matches = 0, i, pidx, sidx, eidx;
-+	int text_len = strlen(text), itext_len;
-+
-+	matches = matchend = NULL;
-+
-+	/* walk through all items */
-+	for (it = items; it && it->text; it++) {
-+		if (text_len) {
-+			itext_len = strlen(it->text);
-+			pidx = 0; /* pointer */
-+			sidx = eidx = -1; /* start of match, end of match */
-+			/* walk through item text */
-+			for (i = 0; i < itext_len && (c = it->text[i]); i++) {
-+				/* fuzzy match pattern */
-+				if (!fstrncmp(&text[pidx], &c, 1)) {
-+					if(sidx == -1)
-+						sidx = i;
-+					pidx++;
-+					if (pidx == text_len) {
-+						eidx = i;
-+						break;
-+					}
-+				}
-+			}
-+			/* build list of matches */
-+			if (eidx != -1) {
-+				/* compute distance */
-+				/* add penalty if match starts late (log(sidx+2))
-+				 * add penalty for long a match without many matching characters */
-+				it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len);
-+				/* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */
-+				appenditem(it, &matches, &matchend);
-+				number_of_matches++;
-+			}
-+		} else {
-+			appenditem(it, &matches, &matchend);
-+		}
-+	}
-+
-+	if (number_of_matches) {
-+		/* initialize array with matches */
-+		if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*))))
-+			die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*));
-+		for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) {
-+			fuzzymatches[i] = it;
-+		}
-+		/* sort matches according to distance */
-+		qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
-+		/* rebuild list of matches */
-+		matches = matchend = NULL;
-+		for (i = 0, it = fuzzymatches[i];  i < number_of_matches && it && \
-+				it->text; i++, it = fuzzymatches[i]) {
-+			appenditem(it, &matches, &matchend);
-+		}
-+		free(fuzzymatches);
-+	}
-+	curr = sel = matches;
-+	calcoffsets();
-+}
-+
- static void
- match(void)
- {
-+	if (fuzzy) {
-+		fuzzymatch();
-+		return;
-+	}
- 	static char **tokv = NULL;
- 	static int tokn = 0;
- 
-@@ -702,6 +789,8 @@ main(int argc, char *argv[])
- 			topbar = 0;
- 		else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
- 			fast = 1;
-+		else if (!strcmp(argv[i], "-F"))   /* grabs keyboard before reading stdin */
-+			fuzzy = 0;
- 		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
- 			fstrncmp = strncasecmp;
- 			fstrstr = cistrstr;
--- 
-2.22.0
-
diff --git a/patches/dmenu-password-5.0.diff b/patches/dmenu-password-5.0.diff
deleted file mode 100644
index 7a187b9..0000000
--- a/patches/dmenu-password-5.0.diff
+++ /dev/null
@@ -1,103 +0,0 @@
-From c4de1032bd4c247bc20b6ab92a10a8d778966679 Mon Sep 17 00:00:00 2001
-From: Mehrad Mahmoudian <m.mahmoudian@gmail.com>
-Date: Tue, 4 May 2021 12:05:09 +0300
-Subject: [PATCH] patched with password patch
-
----
- dmenu.1 |  5 ++++-
- dmenu.c | 21 +++++++++++++++++----
- 2 files changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/dmenu.1 b/dmenu.1
-index 323f93c..762f707 100644
---- a/dmenu.1
-+++ b/dmenu.1
-@@ -3,7 +3,7 @@
- dmenu \- dynamic menu
- .SH SYNOPSIS
- .B dmenu
--.RB [ \-bfiv ]
-+.RB [ \-bfivP ]
- .RB [ \-l
- .IR lines ]
- .RB [ \-m
-@@ -47,6 +47,9 @@ is faster, but will lock up X until stdin reaches end\-of\-file.
- .B \-i
- dmenu matches menu items case insensitively.
- .TP
-+.B \-P
-+dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
-+.TP
- .BI \-l " lines"
- dmenu lists items vertically, with the given number of lines.
- .TP
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..ad8f63b 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -37,7 +37,7 @@ struct item {
- static char text[BUFSIZ] = "";
- static char *embed;
- static int bh, mw, mh;
--static int inputw = 0, promptw;
-+static int inputw = 0, promptw, passwd = 0;
- static int lrpad; /* sum of left and right padding */
- static size_t cursor;
- static struct item *items = NULL;
-@@ -132,6 +132,7 @@ drawmenu(void)
- 	unsigned int curpos;
- 	struct item *item;
- 	int x = 0, y = 0, w;
-+	char *censort;
- 
- 	drw_setscheme(drw, scheme[SchemeNorm]);
- 	drw_rect(drw, 0, 0, mw, mh, 1, 1);
-@@ -143,7 +144,12 @@ drawmenu(void)
- 	/* draw input field */
- 	w = (lines > 0 || !matches) ? mw - x : inputw;
- 	drw_setscheme(drw, scheme[SchemeNorm]);
--	drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
-+	if (passwd) {
-+	        censort = ecalloc(1, sizeof(text));
-+		memset(censort, '.', strlen(text));
-+		drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0);
-+		free(censort);
-+	} else drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
- 
- 	curpos = TEXTW(text) - TEXTW(&text[cursor]);
- 	if ((curpos += lrpad / 2 - 1) < w) {
-@@ -524,6 +530,11 @@ readstdin(void)
- 	char buf[sizeof text], *p;
- 	size_t i, imax = 0, size = 0;
- 	unsigned int tmpmax = 0;
-+	if(passwd){
-+    	inputw = lines = 0;
-+    	return;
-+  	}
-+
- 
- 	/* read each line from stdin and add it to the item list */
- 	for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
-@@ -689,7 +700,7 @@ setup(void)
- static void
- usage(void)
- {
--	fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-+	fputs("usage: dmenu [-bfivP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
- 	      "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
- 	exit(1);
- }
-@@ -712,7 +723,9 @@ main(int argc, char *argv[])
- 		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
- 			fstrncmp = strncasecmp;
- 			fstrstr = cistrstr;
--		} else if (i + 1 == argc)
-+		} else if (!strcmp(argv[i], "-P"))   /* is the input a password */
-+			passwd = 1;
-+		else if (i + 1 == argc)
- 			usage();
- 		/* these options take one argument */
- 		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
--- 
-2.31.1
-
diff --git a/patches/dmenu-rejectnomatch-4.7.diff b/patches/dmenu-rejectnomatch-4.7.diff
deleted file mode 100644
index 329ab1d..0000000
--- a/patches/dmenu-rejectnomatch-4.7.diff
+++ /dev/null
@@ -1,82 +0,0 @@
-diff --git a/dmenu.1 b/dmenu.1
-index 9eab758..61084ab 100644
---- a/dmenu.1
-+++ b/dmenu.1
-@@ -3,7 +3,7 @@
- dmenu \- dynamic menu
- .SH SYNOPSIS
- .B dmenu
--.RB [ \-bfiv ]
-+.RB [ \-bfirv ]
- .RB [ \-l
- .IR lines ]
- .RB [ \-m
-@@ -47,6 +47,9 @@ X until stdin reaches end\-of\-file.
- .B \-i
- dmenu matches menu items case insensitively.
- .TP
-+.B \-r
-+dmenu will reject any input which would result in no matching option left.
-+.TP
- .BI \-l " lines"
- dmenu lists items vertically, with the given number of lines.
- .TP
-diff --git a/dmenu.c b/dmenu.c
-index d605ab4..7505278 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -38,6 +38,7 @@ static char *embed;
- static int bh, mw, mh;
- static int inputw = 0, promptw;
- static int lrpad; /* sum of left and right padding */
-+static int reject_no_match = 0;
- static size_t cursor;
- static struct item *items = NULL;
- static struct item *matches, *matchend;
-@@ -268,12 +269,26 @@ insert(const char *str, ssize_t n)
- {
- 	if (strlen(text) + n > sizeof text - 1)
- 		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 */
- 	memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
- 	if (n > 0)
- 		memcpy(&text[cursor], str, n);
- 	cursor += n;
- 	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
-@@ -636,7 +651,7 @@ setup(void)
- static void
- usage(void)
- {
--	fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-+	fputs("usage: dmenu [-bfirv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
- 	      "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
- 	exit(1);
- }
-@@ -659,7 +674,9 @@ main(int argc, char *argv[])
- 		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
- 			fstrncmp = strncasecmp;
- 			fstrstr = cistrstr;
--		} else if (i + 1 == argc)
-+		} else if (!strcmp(argv[i], "-r")) /* reject input which results in no match */
-+			reject_no_match = 1;
-+		else if (i + 1 == argc)
- 			usage();
- 		/* these options take one argument */
- 		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
diff --git a/stest.1 b/stest.1
deleted file mode 100644
index 2667d8a..0000000
--- a/stest.1
+++ /dev/null
@@ -1,90 +0,0 @@
-.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/stest.c b/stest.c
deleted file mode 100644
index e27d3a5..0000000
--- a/stest.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* 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/util.c b/util.c
deleted file mode 100644
index 96b82c9..0000000
--- a/util.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-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);
-}
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
-	void *p;
-
-	if (!(p = calloc(nmemb, size)))
-		die("calloc:");
-	return p;
-}
diff --git a/util.h b/util.h
deleted file mode 100644
index f633b51..0000000
--- a/util.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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);