Add initial build of spmenu

This commit is contained in:
speedie 2023-01-20 23:17:30 +01:00
commit c73c22aa56
17 changed files with 2865 additions and 0 deletions

31
LICENSE Normal file
View file

@ -0,0 +1,31 @@
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>
© 2021-2023 speedie <speedie@duck.com>
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.

54
Makefile Normal file
View file

@ -0,0 +1,54 @@
# spmenu
# See LICENSE file for copyright and license details.
include options.mk
include host.mk
include toggle.mk
SRC = draw.c spmenu.c main.c
OBJ = $(SRC:.c=.o)
all: options spmenu
options:
@echo spmenu build options:
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
.c.o:
$(CC) -c $(CFLAGS) -g $<
$(OBJ): arg.h options.h options.mk draw.h
spmenu: spmenu.o draw.o main.o
$(CC) -o $@ spmenu.o draw.o main.o $(LDFLAGS)
clean:
rm -f spmenu $(OBJ) spmenu-$(VERSION).tar.gz
dist: clean
mkdir -p spmenu-$(VERSION)
cp LICENSE Makefile *.h *.mk *.c scripts/ spmenu-$(VERSION)
tar -cf spmenu-$(VERSION).tar spmenu-$(VERSION)
gzip spmenu-$(VERSION).tar
rm -rf spmenu-$(VERSION)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f spmenu scripts/* $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/spmenu*
rm -f *.o
rm -f spmenu
uninstall:
$(DESTDIR)$(PREFIX)/bin/spmenu*\
help:
@echo install: Installs spmenu. You may need to run this as root.
@echo uninstall: Uninstalls spmenu. You may need to run this as root.
@echo help: Displays this help sheet.
.PHONY: all options clean dist install uninstall help

85
README.md Normal file
View file

@ -0,0 +1,85 @@
# spmenu
Simply my build of suckless's dmenu
### What is spmenu?
spmenu is an X11 menu application based on
[dmenu](https://tools.suckless.org/dmenu) which takes standard input, parses
it, and lets the user choose an option and sends the
selected option to standard output.
It is designed to integrate well with my [dwm](https://dwm.suckless.org) fork, [speedwm](https://codeberg.org/speedie/speedwm).
### Special features
This build of spmenu has some features written for this build.
Of course if you want, this is free software so you can use it in your own build.
- 256 color support through SGR codes.
- Option to block typing.
- Rewritten arguments, old arguments still work though.
- Border only when centered option
- Hiding each part of the menu
### Other features
Note: This is an incomplete list, it's just here to give you an idea of what this build has to offer.
- Pango markup support.
- Alpha transparency
- Pywal/.Xresources support
- Grid
- Colored Emoji/Font support
- Highlighting
- Case-insensitive by default
- Padding; useful with patched dwm with barpadding or speedwm.
- Fuzzy-finding
- Preselect support
- Line-height
- History support
### Dependencies
- libX11
- libXrender
- freetype
- libXinerama
- Can be disabled if you don't want/need multi-monitor support.
- tcc compiler (you can swap it out for GCC by passing CC="gcc" to the `make` command if you want)
- Pango (for drawing fonts)
- If you do not want to use pango, consider my [older spmenu build](https://github.com/speedie-de/dmenu)
### Installation (most GNU/Linux distributions)
`emerge dev-vcs/git # Install dev-vcs/git using your favorite package manager`
`git clone https://codeberg.org/speedie/spmenu`
`cd spmenu/`
`make clean install # Run as root.`
### Installation (Gentoo)
If you are on Gentoo GNU/Linux, you can add
[my overlay](https://codeberg.org/speedie/speedie-overlay) which includes
`x11-misc/spmenu` as well as other useful packages.
### .Xresources values
This build allows you to define .Xresources values to load on startup. See docs/example.Xresources for a list of default values.
### Scripts
This build of spmenu should work with all spmenu scripts. [Here](https://codeberg.org/speedie/speedwm-extras) are a few I've written/use:
### Notes for users of Arch
This fork of spmenu is compiled using tcc for speed however tcc from the Arch repositories seems to be broken. I'm sure there's a better way to fix this but I just fix it by installing [this package](https://aur.archlinux.org/packages/tcc-ziyao) from the AUR.
### Notes for GCC users
If you're compiling with GCC, chances are you're seeing a lot of warnings.
This is because we're compiling with -Ofast. I can't seem to find any issues
with using -Ofast but if it bothers you, you can compile
with -Os or -O2 which don't spit out these warnings.

49
arg.h Normal file
View file

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

45
colors.h Normal file
View file

@ -0,0 +1,45 @@
/* Color options */
/* Alpha */
static const unsigned int alphas[][3] = {
/* fg bg border */
[SchemeNorm] = { opaque, baralpha, borderalpha },
[SchemeSel] = { opaque, baralpha, borderalpha },
[SchemePrompt] = { opaque, baralpha, borderalpha },
[SchemeNormHighlight] = { opaque, baralpha, borderalpha },
[SchemeSelHighlight] = { opaque, baralpha, borderalpha },
[SchemeCaret] = { opaque, baralpha, borderalpha },
[SchemeNumber] = { opaque, baralpha, borderalpha },
};
/* Colors */
static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { normfgcolor, normbgcolor },
[SchemeSel] = { selfgcolor, selbgcolor },
[SchemePrompt] = { selfgcolor, selbgcolor },
[SchemeNormHighlight] = { normhlfgcolor, normhlbgcolor },
[SchemeSelHighlight] = { selhlfgcolor, selhlbgcolor },
[SchemeCaret] = { caretfgcolor, NULL },
[SchemeNumber] = { numfgcolor, numbgcolor },
};
/* sgr colors */
static char *textcolors[] = {
sgrcolor0,
sgrcolor1,
sgrcolor2,
sgrcolor3,
sgrcolor4,
sgrcolor5,
sgrcolor6,
sgrcolor7,
sgrcolor8,
sgrcolor9,
sgrcolor10,
sgrcolor11,
sgrcolor12,
sgrcolor13,
sgrcolor14,
sgrcolor15,
};

54
docs/example.Xresources Normal file
View file

@ -0,0 +1,54 @@
!! spmenu
!!
!! colors
spmenu.font: DejaVu Sans Mono 8
spmenu.normfgcolor: #bbbbbb
spmenu.normbgcolor: #222222
spmenu.selfgcolor: #eeeeee
spmenu.selbgcolor: #005577
spmenu.normhlfgcolor: #ffffff
spmenu.normhlbgcolor: #000000
spmenu.selhlfgcolor: #ffffff
spmenu.selhlbgcolor: #000000
spmenu.outfgcolor: #000000
spmenu.outbgcolor: #5e81ac
spmenu.caretfgcolor: #222222
spmenu.sgrcolor0: #000000
spmenu.sgrcolor1: #7f0000
spmenu.sgrcolor2: #007f00
spmenu.sgrcolor3: #7f7f00
spmenu.sgrcolor4: #00007f
spmenu.sgrcolor5: #7f007f
spmenu.sgrcolor6: #007f7f
spmenu.sgrcolor7: #cccccc
spmenu.sgrcolor8: #333333
spmenu.sgrcolor9: #ff0000
spmenu.sgrcolor10: #00ff00
spmenu.sgrcolor11: #ffff00
spmenu.sgrcolor12: #0000ff
spmenu.sgrcolor13: #ff00ff
spmenu.sgrcolor14: #00ffff
spmenu.sgrcolor15: #ffffff
!! misc
spmenu.alpha: 1
spmenu.bordercentered: 1
spmenu.borderwidth: 2
spmenu.lines: 0
spmenu.columns: 10
spmenu.lineheight: 5
spmenu.minlineheight: 5
spmenu.maxhist: 64
spmenu.histnodup: 1
spmenu.casesensitive: 0
spmenu.menuposition: 1
spmenu.menupaddingv: 0
spmenu.menupaddingh: 0
spmenu.colorprompt: 1
spmenu.preselected: 0
spmenu.type: 1
spmenu.class: spmenu
spmenu.leftarrow: <
spmenu.rightarrow: >
spmenu.hidematchcount: 0

285
draw.c Normal file
View file

@ -0,0 +1,285 @@
/* 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 <pango/pango.h>
#include <pango/pangoxft.h>
#include "draw.h"
#include "main.h"
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_font_free(drw->font);
free(drw);
}
static Fnt *
xfont_create(Drw *drw, const char *fontname)
{
Fnt *font;
PangoFontMap *fontmap;
PangoContext *context;
PangoFontDescription *desc;
PangoFontMetrics *metrics;
if (!fontname) {
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->dpy = drw->dpy;
fontmap = pango_xft_get_font_map(drw->dpy, drw->screen);
context = pango_font_map_create_context(fontmap);
desc = pango_font_description_from_string(fontname);
font->layout = pango_layout_new(context);
pango_layout_set_font_description(font->layout, desc);
metrics = pango_context_get_metrics(context, desc, pango_language_from_string ("en-us"));
font->h = pango_font_metrics_get_height(metrics) / PANGO_SCALE;
pango_font_metrics_unref(metrics);
g_object_unref(context);
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->layout)
g_object_unref(font->layout);
free(font);
}
Fnt*
drw_font_create(Drw* drw, const char font[])
{
Fnt *fnt = NULL;
if (!drw || !font)
return NULL;
fnt = xfont_create(drw, font);
return (drw->font = fnt);
}
void
drw_font_free(Fnt *font)
{
if (font) {
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_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, Bool markup)
{
char buf[1024];
int ty;
unsigned int ew;
XftDraw *d = NULL;
size_t i, len;
int render = x || y || w || h;
if (!drw || (render && !drw->scheme) || !text || !drw->font)
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, drw->visual, drw->cmap);
x += lpad;
w -= lpad;
}
len = strlen(text);
if (len) {
drw_font_getexts(drw->font, text, len, &ew, NULL, markup);
/* shorten text if necessary */
for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--)
drw_font_getexts(drw->font, text, len, &ew, NULL, markup);
if (len) {
memcpy(buf, text, len);
buf[len] = '\0';
if (len < strlen(text))
for (i = len; i && i > len - 3; buf[--i] = '.')
; /* NOP */
if (render) {
ty = y + (h - drw->font->h) / 2;
if(markup)
pango_layout_set_markup(drw->font->layout, buf, len);
else
pango_layout_set_text(drw->font->layout, buf, len);
pango_xft_render_layout(d, &drw->scheme[invert ? ColBg : ColFg],
drw->font->layout, x * PANGO_SCALE, ty * PANGO_SCALE);
if(markup) /* clear markup attributes */
pango_layout_set_attributes(drw->font->layout, NULL);
}
x += ew;
w -= ew;
}
}
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_font_getwidth(Drw *drw, const char *text, Bool markup)
{
if (!drw || !drw->font || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup)
{
if (!font || !text)
return;
PangoRectangle r;
if(markup)
pango_layout_set_markup(font->layout, text, len);
else
pango_layout_set_text(font->layout, text, len);
pango_layout_get_extents(font->layout, 0, &r);
if(markup) /* clear markup attributes */
pango_layout_set_attributes(font->layout, NULL);
if (w)
*w = r.width / PANGO_SCALE;
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);
}

57
draw.h Normal file
View file

@ -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;
PangoLayout *layout;
} 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 *font;
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt *drw_font_create(Drw* drw, const char font[]);
void drw_font_free(Fnt* set);
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, const 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_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, Bool markup);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);

38
host.mk Normal file
View file

@ -0,0 +1,38 @@
# spmenu
# See LICENSE file for copyright details.
# compiler
CC = tcc
# paths
PREFIX = /usr
# library paths
#
# libx11
X11LIBS = -lX11
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# xft
XFT_CONF = xft
# pango
PANGO_CONF = pango
PANGOXFT_CONF = pangoxft
# xrender
XRENDERLIBS = -lXrender
# OpenBSD (uncomment)
#FREETYPEINC = $(X11INC)/freetype2
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
CFLAGS = -std=c99 -pedantic -Wall -Ofast $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
INCS = -I$(X11INC) -I$(FREETYPEINC) `pkg-config --cflags $(XFT_CONF) $(PANGO_CONF) $(PANGOXFT_CONF)`
LIBS = -L$(X11LIB) $(X11LIBS) $(XINERAMALIBS) $(FREETYPELIBS) $(XRENDERLIBS) -lm `pkg-config --libs $(XFT_CONF) $(PANGO_CONF) $(PANGOXFT_CONF)`

35
main.c Normal file
View file

@ -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 "main.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);
}

12
main.h Normal file
View file

@ -0,0 +1,12 @@
/* See LICENSE file for copyright and license details. */
#ifndef MAX
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#endif
#ifndef MIN
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#endif
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);

103
options.h Normal file
View file

@ -0,0 +1,103 @@
/* spmenu
* Below is a configuration file which is technically C source code.
* See the LICENSE file for license details.
*/
/* spmenu options */
static char class[] = "spmenu"; /* Class for spmenu */
static int xresources = 1; /* Enable .Xresources support */
/* Window options */
static int alpha = 1; /* Enable alpha */
static int menuposition = 1; /* Position of the menu */
static int menupaddingv = 0; /* Vertical padding of bar (in pixels) */
static int menupaddingh = 0; /* Horizontal padding of bar (in pixels) */
static int minwidth = 500; /* Minimum width */
static int centered = 0; /* Whether or not to center spmenu by default */
static int colorsupport = 0; /* Support 256 colors? Otherwise the default 16 colors will be used. */
/* Window border options */
static int borderwidth = 2; /* Width of the border */
static int bordercentered = 1; /* Draw border only when centered */
/* Font options */
static char font[] = "DejaVu Sans Mono 8"; /* Font to draw text and Pango markup with. */
/* Symbol options */
static char *leftarrow = "<"; /* Left arrow, used to indicate you can move to the left */
static char *rightarrow = ">"; /* Right arrow, used to indicate you can move to the right */
/* Match options */
static int type = 1; /* Allow typing into spmenu or only allow keybinds. */
static int casesensitive = 0; /* Case-sensitive by default? (0/1) */
static int preselected = 0; /* Which line should spmenu preselect? */
static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */
/* Line options */
static int lines = 0; /* Default number of lines */
static int columns = 10; /* Default number of columns */
static int lineheight = 20; /* Height of each line */
static int minlineheight = 5; /* Minimum line height */
/* History options */
static unsigned int maxhist = 64; /* Max number of history entries */
static int histnodup = 1; /* If 0, record repeated histories */
/* Prompt options */
static int colorprompt = 1; /* Color prompt (0/1) */
static char *prompt = NULL; /* Default prompt, set to NULL (nothing) */
/* Hide options */
static int hidematchcount = 0; /* Hide match count (0/1) */
/* Color options
*
* Normal foreground colors
*/
static char normfgcolor[] = "#bbbbbb"; /* Text color for unselected */
static char normbgcolor[] = "#222222"; /* Background color for unselected */
/* Selected foreground colors */
static char selfgcolor[] = "#eeeeee"; /* Text color for selected */
static char selbgcolor[] = "#5e81ac"; /* Background color for selected */
/* Normal highlight colors */
static char normhlfgcolor[] = "#ffffff"; /* Text highlight color for unselected */
static char normhlbgcolor[] = "#000000"; /* Background highlight color for unselected */
/* Selected highlight colors */
static char selhlfgcolor[] = "#ffffff"; /* Text highlight color for selected */
static char selhlbgcolor[] = "#000000"; /* Background highlight color for selected */
/* Match count colors */
static char numfgcolor[] = "#ffffff"; /* Match count text color */
static char numbgcolor[] = "#000000"; /* Match count background color */
/* Caret colors */
static char caretfgcolor[] = "#222222"; /* Caret color */
/* SGR colors */
static char sgrcolor0[] = "#000000"; /* SGR color #0 */
static char sgrcolor1[] = "#7f0000"; /* SGR color #1 */
static char sgrcolor2[] = "#007f00"; /* SGR color #2 */
static char sgrcolor3[] = "#7f7f00"; /* SGR color #3 */
static char sgrcolor4[] = "#00007f"; /* SGR color #4 */
static char sgrcolor5[] = "#7f007f"; /* SGR color #5 */
static char sgrcolor6[] = "#007f7f"; /* SGR color #6 */
static char sgrcolor7[] = "#cccccc"; /* SGR color #7 */
static char sgrcolor8[] = "#333333"; /* SGR color #8 */
static char sgrcolor9[] = "#ff0000"; /* SGR color #9 */
static char sgrcolor10[] = "#00ff00"; /* SGR color #10 */
static char sgrcolor11[] = "#ffff00"; /* SGR color #11 */
static char sgrcolor12[] = "#0000ff"; /* SGR color #12 */
static char sgrcolor13[] = "#ff00ff"; /* SGR color #13 */
static char sgrcolor14[] = "#00ffff"; /* SGR color #14 */
static char sgrcolor15[] = "#ffffff"; /* SGR color #15 */
/* Alpha options */
#define baralpha 200 /* Bar alpha */
#define borderalpha opaque /* Border alpha */
/* Misc */
static char worddelimiters[] = " "; /* Word delimiters, " " is default. */

9
options.mk Normal file
View file

@ -0,0 +1,9 @@
# spmenu
# See LICENSE file for copyright details.
# spmenu version
VERSION = 0.1
# includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC) `pkg-config --cflags xft pango pangoxft`
LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) ${XRENDERLIBS} -lm `pkg-config --libs xft pango pangoxft`

22
scripts/spmenu_run Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh
# get path
PATH() {
echo "$PATH" | tr ':' '\n' | uniq | sed 's#$#/#' | # List directories in $PATH
xargs ls -lu --time-style=+%s | # Add atime epoch
awk '/^(-|l)/ { print $6, $7 }' | # Only print timestamp and name
sort -rn | cut -d' ' -f 2
}
# Run spmenu and parse it
PARSE() {
DOUT="$(PATH | spmenu -H "${XDG_CACHE_HOME:-$HOME/.cache/}/spmenu_run.hist" "$@")"
[ "$(printf '%c' "$DOUT")" = "#" ] && RUN_ARG="$TERMINAL" || RUN_ARG="$SHELL"
[ "$RUN_ARG" != "$TERMINAL" ] && printf "%s" "$DOUT" | sed "s/#//g" | ${SHELL:-"/bin/sh"} &
[ "$RUN_ARG" = "$TERMINAL" ] && $TERMINAL -e "$(printf "%s" "$DOUT" | sed "s/#//g")"
}
PARSE "$@"
rm -f "$HOME/.cache/spmenu_run"

1888
spmenu.c Normal file

File diff suppressed because it is too large Load diff

8
toggle.mk Normal file
View file

@ -0,0 +1,8 @@
# spmenu
# See LICENSE file for copyright details.
# Multi-monitor support.
# Requires libXinerama
# Comment these lines if you don't need it.
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA

90
xresources.h Normal file
View file

@ -0,0 +1,90 @@
/* This header is for the .Xresources options.
* These will be set on startup by xrdb.
*/
ResourcePref resources[] = {
{ "font", STRING, &font },
{ "caretfgcolor", STRING, &caretfgcolor },
{ "normfgcolor", STRING, &normfgcolor },
{ "normbgcolor", STRING, &normbgcolor },
{ "selfgcolor", STRING, &selfgcolor },
{ "selbgcolor", STRING, &selbgcolor },
{ "numfgcolor", STRING, &numfgcolor },
{ "numbgcolor", STRING, &numbgcolor },
{ "normhlfgcolor", STRING, &normhlfgcolor },
{ "normhlbgcolor", STRING, &normhlbgcolor },
{ "selhlfgcolor", STRING, &selhlfgcolor },
{ "selhlbgcolor", STRING, &selhlbgcolor },
/* Pywal support */
{ "color0", STRING, &caretfgcolor },
{ "color10", STRING, &normfgcolor },
{ "color0", STRING, &normbgcolor },
{ "color0", STRING, &selfgcolor },
{ "color6", STRING, &selbgcolor },
{ "color0", STRING, &numfgcolor },
{ "color6", STRING, &numbgcolor },
{ "color2", STRING, &normhlbgcolor },
{ "color3", STRING, &selhlbgcolor },
{ "color3", STRING, &normhlfgcolor },
{ "color0", STRING, &selhlfgcolor },
/* sgr colors */
{ "sgrcolor0", STRING, &sgrcolor0 },
{ "sgrcolor1", STRING, &sgrcolor1 },
{ "sgrcolor2", STRING, &sgrcolor2 },
{ "sgrcolor3", STRING, &sgrcolor3 },
{ "sgrcolor4", STRING, &sgrcolor4 },
{ "sgrcolor5", STRING, &sgrcolor5 },
{ "sgrcolor6", STRING, &sgrcolor6 },
{ "sgrcolor7", STRING, &sgrcolor7 },
{ "sgrcolor8", STRING, &sgrcolor8 },
{ "sgrcolor9", STRING, &sgrcolor9 },
{ "sgrcolor10", STRING, &sgrcolor10 },
{ "sgrcolor11", STRING, &sgrcolor11 },
{ "sgrcolor12", STRING, &sgrcolor12 },
{ "sgrcolor13", STRING, &sgrcolor13 },
{ "sgrcolor14", STRING, &sgrcolor14 },
{ "sgrcolor15", STRING, &sgrcolor15 },
/* sgr colors */
{ "color0", STRING, &sgrcolor0 },
{ "color1", STRING, &sgrcolor1 },
{ "color2", STRING, &sgrcolor2 },
{ "color3", STRING, &sgrcolor3 },
{ "color4", STRING, &sgrcolor4 },
{ "color5", STRING, &sgrcolor5 },
{ "color6", STRING, &sgrcolor6 },
{ "color7", STRING, &sgrcolor7 },
{ "color8", STRING, &sgrcolor8 },
{ "color9", STRING, &sgrcolor9 },
{ "color10", STRING, &sgrcolor10 },
{ "color11", STRING, &sgrcolor11 },
{ "color12", STRING, &sgrcolor12 },
{ "color13", STRING, &sgrcolor13 },
{ "color14", STRING, &sgrcolor14 },
{ "color15", STRING, &sgrcolor15 },
{ "menuposition", INTEGER, &menuposition },
{ "menupaddingv", INTEGER, &menupaddingv },
{ "menupaddingh", INTEGER, &menupaddingh },
{ "alpha", INTEGER, &alpha },
{ "type", INTEGER, &type },
{ "preselected", INTEGER, &preselected },
{ "colorprompt", INTEGER, &colorprompt },
{ "prompt", STRING, &prompt },
{ "class", STRING, &class },
{ "leftarrow", STRING, &leftarrow },
{ "rightarrow", STRING, &rightarrow },
{ "bordercentered", INTEGER, &bordercentered },
{ "borderwidth", INTEGER, &borderwidth },
{ "lines", INTEGER, &lines },
{ "columns", INTEGER, &columns },
{ "lineheight", INTEGER, &lineheight },
{ "minlineheight", INTEGER, &minlineheight },
{ "maxhist", INTEGER, &maxhist },
{ "hidematchcount", INTEGER, &hidematchcount },
{ "histnodup", INTEGER, &histnodup },
{ "casesensitive", INTEGER, &casesensitive },
};