From 10495b48bfbf7c4e21b8938b4f8637ba9f433d87 Mon Sep 17 00:00:00 2001
From: speedie
Date: Tue, 4 Apr 2023 21:39:38 +0200
Subject: [PATCH] add experimental configuration file profiles still need to be
rewritten
---
Makefile | 2 +-
PKGBUILD | 2 +-
README.html | 14 +-
README.md | 16 +-
build.sh | 11 ++
buildconf | 1 +
docs/docs.md | 24 ++-
docs/example.Xresources | 2 +-
docs/spmenu.conf | 112 ++++++++++-
host.mk | 5 +-
libs/arg.c | 2 +-
libs/argv.c | 4 +-
libs/conf/config.c | 286 ++++++++++++++++++++++++++-
libs/draw.c | 4 +-
libs/xresources.h | 2 +-
options.h | 8 +-
spmenu.1 | 21 +-
spmenu.c | 13 +-
themes/README.md | 14 +-
themes/install.sh | 7 +-
themes/{ => legacy}/Catppuccin | 0
themes/{ => legacy}/Cyberpunk-Neon | 0
themes/{ => legacy}/Doom-One | 0
themes/{ => legacy}/Dracula | 0
themes/{ => legacy}/Gruvbox-Dark | 0
themes/{ => legacy}/No-Global-Colors | 0
themes/{ => legacy}/Nord | 0
themes/{ => legacy}/Solarized-Dark | 0
themes/{ => legacy}/Tokyo-Night | 0
themes/sample.theme | 9 +
toggle.mk | 27 +--
31 files changed, 535 insertions(+), 51 deletions(-)
rename themes/{ => legacy}/Catppuccin (100%)
rename themes/{ => legacy}/Cyberpunk-Neon (100%)
rename themes/{ => legacy}/Doom-One (100%)
rename themes/{ => legacy}/Dracula (100%)
rename themes/{ => legacy}/Gruvbox-Dark (100%)
rename themes/{ => legacy}/No-Global-Colors (100%)
rename themes/{ => legacy}/Nord (100%)
rename themes/{ => legacy}/Solarized-Dark (100%)
rename themes/{ => legacy}/Tokyo-Night (100%)
create mode 100644 themes/sample.theme
diff --git a/Makefile b/Makefile
index d0dfd32..75c42f6 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ include toggle.mk
# spmenu version
VERSION = 0.3.3
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMATOGGLE) $(BDTOGGLE) $(PANGOTOGGLE) $(IMLIB2TOGGLE)
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMATOGGLE) $(BDTOGGLE) $(PANGOTOGGLE) $(IMLIB2TOGGLE) $(LIBCONFIGTOGGLE)
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations $(OPT) $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
INCS = -I$(X11INC) -I$(FREETYPEINC) -I$(BDINC) `pkg-config --cflags $(XFTCONF) $(PANGOCONF) $(PANGOXFTCONF) $(OPENSSLCONF) $(LIBCONFIGCONF)`
diff --git a/PKGBUILD b/PKGBUILD
index 8286f78..91374e9 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -7,7 +7,7 @@ pkgdesc="Fancy dynamic menu, compatible with dmenu!"
url="https://git.speedie/gq/spmenu"
arch=(i686 x86_64)
license=(MIT)
-depends=(sh libxinerama libxft pango libx11 imlib2 fribidi gcc)
+depends=(sh libxinerama libxft pango libx11 imlib2 fribidi libconfig gcc)
makedepends=(git)
provides=($pkgname)
conflicts=($pkgname)
diff --git a/README.html b/README.html
index adf1149..9474f78 100644
--- a/README.html
+++ b/README.html
@@ -20,6 +20,7 @@ href="https://git.speedie.gq/speedwm">speedwm.
course if you want, this is free software so you can use it in your own
build.
+- Proper configuration file support
- dwm-like key/mouse bind array (See keybinds.h and mouse.h)
- Vim-like modes, including indicator.
- The ability to move around items with keybinds.
@@ -118,6 +119,16 @@ lines.
lines.
+libconfig
+
+- Can be disabled if you don’t want/need config file support by:
+
+- build.sh: Setting
libconfig=false
in
+buildconf
.
+- Makefile: Editing
toggle.mk
and commenting out a few
+lines.
+
+
Installation
(GNU/Linux, *BSD, macOS/OS X/Mac OS X)
@@ -166,8 +177,7 @@ but maybe at some point in the distant future
Wayland: Wayland support, but only if it doesn’t require writing any
extra code which as of now seems unlikely.
-- Before this can even be done, we need to add a configuration file
-using anything but .Xresources, replace Xft with cairo, deal with
+
- Before this can even be done, replace Xft with cairo, deal with
keybinds in some Wayland compatible way, and figure out a way to
preserve X11 compatibility as I do not want to use Wayland anyway.
- You can just use XWayland anyway if you happen to use Wayland, so
diff --git a/README.md b/README.md
index 757b7d7..c550e70 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ It is designed to integrate well with my [dwm](https://dwm.suckless.org) fork, [
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.
+- Proper configuration file support
- dwm-like key/mouse bind array (See keybinds.h and mouse.h)
- Vim-like modes, including indicator.
- The ability to move around items with keybinds.
@@ -84,6 +85,10 @@ disabled if you don't want this by:
- Can be disabled if you don't want/need Pango markup by:
- build.sh: Setting `pango=false` and `pangoxft=false` in `buildconf`.
- Makefile: Editing `toggle.mk` and commenting out a few lines.
+- libconfig
+ - Can be disabled if you don't want/need config file support by:
+ - build.sh: Setting `libconfig=false` in `buildconf`.
+ - Makefile: Editing `toggle.mk` and commenting out a few lines.
## Installation (GNU/Linux, \*BSD, macOS/OS X/Mac OS X)
@@ -122,8 +127,7 @@ Pull requests would be greatly appreciated for any of these issues!
### General
-- Config file: Add configuration file using (probably) libconfig, allowing
-keybinds to be configured without recompiling spmenu.
+- Config file: Add mouse/keybind configuration
- Image support: Stop using OpenSSL for caching images, mostly because MD5()
is deprecated as of OpenSSL 3.0, but this would also make it very easy to
have LibreSSL compatibility.
@@ -136,10 +140,10 @@ have LibreSSL compatibility.
- Wayland: Wayland support, but only if it doesn't require writing any extra
code which as of now seems unlikely.
- - Before this can even be done, we need to add a configuration file using
-anything but .Xresources, replace Xft with cairo, deal with keybinds in some
-Wayland compatible way, and figure out a way to preserve X11 compatibility
-as I do not want to use Wayland anyway.
+ - Before this can even be done, replace Xft with cairo,
+ deal with keybinds in some Wayland compatible way, and
+ figure out a way to preserve X11 compatibility as I do
+ not want to use Wayland anyway.
- You can just use XWayland anyway if you happen to use Wayland, so it's not
like you will be unable to use spmenu in its current state.
diff --git a/build.sh b/build.sh
index 274e586..daf75a2 100755
--- a/build.sh
+++ b/build.sh
@@ -25,6 +25,7 @@ check() {
[ -n "$(ldconfig -p | grep libgnutls-openssl)" ] && printf "openssl found\n" && openssl=true || openssl=false
[ -n "$(ldconfig -p | grep fribidi)" ] && printf "fribidi found\n" && fribidi=true || fribidi=false
[ -n "$(ldconfig -p | grep freetype)" ] && printf "freetype found\n" && freetype=true || freetype=false
+ [ -n "$(ldconfig -p | grep libconfig)" ] && printf "libconfig found\n" && libconfig=true || libconfig=false
}
loadconf() {
@@ -83,6 +84,12 @@ build() {
pangotoggle="-DPANGO"
fi
+ # libconfig
+ if [ "$libconfig" = "true" ]; then
+ libconfigtoggle="-DCONFIG"
+ libconfigconf="libconfig"
+ fi
+
# fribidi
if [ "$fribidi" = "true" ]; then
bdlibs="-lfribidi"
@@ -114,6 +121,8 @@ build() {
BDTOGGLE="$bdtoggle" \
FREETYPEINC="$FREETYPEINC" \
OPENSSLCONF="$opensslconf" \
+ LIBCONFIGTOGGLE="$libconfigtoggle" \
+ LIBCONFIGCONF="$libconfigconf" \
X11LIB="$X11LIB" \
X11INC="$X11INC"
}
@@ -135,6 +144,8 @@ install() {
BDTOGGLE="$bdtoggle" \
FREETYPEINC="$FREETYPEINC" \
OPENSSLCONF="$opensslconf" \
+ LIBCONFIGTOGGLE="$libconfigtoggle" \
+ LIBCONFIGCONF="$libconfigconf" \
X11LIB="$X11LIB" \
X11INC="$X11INC"
}
diff --git a/buildconf b/buildconf
index 2a2ff7a..b822327 100755
--- a/buildconf
+++ b/buildconf
@@ -7,5 +7,6 @@ pangoxft=true
xinerama=true
openssl=true
fribidi=true
+libconfig=true
CC=gcc
OPT="-O2"
diff --git a/docs/docs.md b/docs/docs.md
index c600b20..ec2d461 100644
--- a/docs/docs.md
+++ b/docs/docs.md
@@ -572,12 +572,28 @@ See [this page](https://docs.gtk.org/Pango/pango_markup.html) for more informati
Configuration
=============
-spmenu has .Xresources (xrdb) support built in. It reads the xrdb (.Xresources database)
-on runtime. You may disable it by passing -nxrdb, or enable it by padding -xrdb.
+Unlike dmenu, spmenu has a configuration file which can be edited by hand. It
+is located in ~/.config/spmenu/spmenu.conf, but you can override this by
+exporting `$XDG_CONFIG_HOME`.
+
+When spmenu is installed, it copies a sample configuration
+to /usr/share/spmenu/spmenu.conf. You can copy this to your `.config/spmenu` directory.
+This configuration file is loaded on startup.
+
+You can also include other configuration files in the configuration file using
+`@include "path/to/config"`.
+
+.Xresources
+=============
+
+spmenu also has .Xresources (xrdb) support built in. It reads the xrdb
+(.Xresources database) on runtime. You may disable it by passing -nxrdb,
+or enable it by padding -xrdb. You can also set this in the regular config file.
spmenu loads `~/.config/spmenu/spmenurc` or alternatively if you're
-old fashioned, `~/.spmenurc`. This requires that `xrdb` is available on your
-operating system.
+old fashioned, `~/.spmenurc` on startup. This requires that `xrdb` is
+available on your operating system. Of course, you don't NEED to use them,
+as you can just `xrdb -override` any .Xresources file you want.
You can also use wildcards (such as `*`) to achieve a global colorscheme.
Programs like `pywal` do this to apply universal colorschemes.
diff --git a/docs/example.Xresources b/docs/example.Xresources
index 86254d7..d1ed5f6 100644
--- a/docs/example.Xresources
+++ b/docs/example.Xresources
@@ -69,7 +69,7 @@ spmenu.indentitems: 1
!! History
spmenu.maxhist: 64
-spmenu.histnodup: 1
+spmenu.histdup: 0
!! Matches
spmenu.type: 1
diff --git a/docs/spmenu.conf b/docs/spmenu.conf
index c17cad4..2ce6854 100644
--- a/docs/spmenu.conf
+++ b/docs/spmenu.conf
@@ -1,4 +1,10 @@
-// spmenu default configuration file
+/* spmenu default configuration file
+ *
+ * Copy to ~/.config/spmenu/spmenu.conf to use.
+ * Note that you can @include other config files if you want
+ *
+ * Example: @include "config.conf"
+ */
spmenu =
{
// General window options
@@ -16,6 +22,97 @@ spmenu =
dock = 1;
} );
+ // Text
+ text = ( { font = "Noto Sans Mono 8";
+ padding = 0;
+ leftarrow = "<";
+ rightarrow = ">";
+ password = "*";
+ prompt = "";
+ input = "";
+ } );
+
+ // Color
+ color = ( { itemnormfg = "#bbbbbb";
+ itemnormbg = "#222222";
+ itemselfg = "#eeeeee";
+ itemselbg = "#35638A";
+ itemnormprifg = "#bbbbbb";
+ itemnormpribg = "#222222";
+ itemselprifg = "#eeeeee";
+ itemselpribg = "#35638A";
+ inputfg = "#eeeeee";
+ inputbg = "#222222";
+ menubg = "#222222";
+ promptfg = "#eeeeee";
+ promptbg = "#35526b";
+ larrowfg = "#bbbbbb";
+ larrowbg = "#222222";
+ rarrowfg = "#bbbbbb";
+ rarrowbg = "#222222";
+ hlnormfg = "#ffffff";
+ hlnormbg = "#000000";
+ hlselfg = "#ffffff";
+ hlselbg = "#000000";
+ numfg = "#ffffff";
+ numbg = "#2d3856";
+ modefg = "#ffffff";
+ modebg = "#35638A";
+ borderbg = "#35638A";
+ caretfg = "#ffffff";
+ sgrcolor0 = "#000000";
+ sgrcolor1 = "#7f0000";
+ sgrcolor2 = "#007f00";
+ sgrcolor3 = "#7f7f00";
+ sgrcolor4 = "#00007f";
+ sgrcolor5 = "#7f007f";
+ sgrcolor6 = "#007f7f";
+ sgrcolor7 = "#cccccc";
+ sgrcolor8 = "#333333";
+ sgrcolor9 = "#ff0000";
+ sgrcolor10 = "#00ff00";
+ sgrcolor11 = "#ffff00";
+ sgrcolor12 = "#0000ff";
+ sgrcolor13 = "#ff00ff";
+ sgrcolor14 = "#00ffff";
+ sgrcolor15 = "#ffffff";
+ coloritems = 1;
+ } );
+
+ // Hide options
+ hide = ( { input = 0;
+ larrow = 0;
+ rarrow = 0;
+ prompt = 0;
+ powerline = 0;
+ cursor = 0;
+ highlight = 0;
+ matchcount = 0;
+ mode = 0;
+ image = 0;
+ } );
+
+ // Match options
+ match = ( { sort = 1;
+ casesensitive = 0;
+ fuzzy = 1;
+ preselected = 0;
+ accuratewidth = 1;
+ delimiters = " ";
+ } );
+
+ // Line options
+ line = ( { height = 1;
+ lines = 0;
+ columns = 10;
+ indentitems = 1;
+ } );
+
+ // History options
+ history = ( { max = 64;
+ duplicate = 0;
+ } );
+
// Centered menu
center = ( { width = 1000;
} );
@@ -36,6 +133,7 @@ spmenu =
// Input
input = ( { fast = 1;
+ type = 1;
} );
// Mode
@@ -43,4 +141,16 @@ spmenu =
normal_text = "Normal";
insert_text = "Insert";
} );
+
+ // Pango
+ pango = ( { item = 1;
+ highlight = 1;
+ prompt = 1;
+ input = 1;
+ leftarrow = 0;
+ rightarrow = 0;
+ numbers = 0;
+ mode = 0;
+ password = 0;
+ } );
};
diff --git a/host.mk b/host.mk
index 15487fd..4633e0d 100644
--- a/host.mk
+++ b/host.mk
@@ -12,7 +12,7 @@ PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man
INCDIR = /usr/include
-# library pat hs
+# library paths
#
# libx11
X11LIBS = -lX11
@@ -29,9 +29,6 @@ XFTCONF = xft
# xrender
XRENDERLIBS = -lXrender
-# libconfig
-LIBCONFIGCONF = libconfig
-
# OpenBSD (uncomment)
#INCDIR = $(X11INC)
#FREETYPEINC = $(INCDIR)/freetype2
diff --git a/libs/arg.c b/libs/arg.c
index b39bf58..88fd2ff 100644
--- a/libs/arg.c
+++ b/libs/arg.c
@@ -369,7 +369,7 @@ savehistory(char *input)
die("failed to write to %s", histfile);
}
}
- if (histsz == 0 || !histnodup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) {
+ if (histsz == 0 || histdup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) {
if (0 >= fputs(input, fp)) {
die("failed to write to %s", histfile);
}
diff --git a/libs/argv.c b/libs/argv.c
index 4e77bcc..a740106 100644
--- a/libs/argv.c
+++ b/libs/argv.c
@@ -7,7 +7,7 @@ readargs(int argc, char *argv[])
int cxrdb = 0;
// check if we should load the xrdb/config, because it needs to be loaded before arguments are checked
- // priority: internal -> xresources -> arguments
+ // priority: internal -> config -> xresources -> arguments
for (j = 1; j < argc; j++) {
if (!strcmp(argv[j], "-xrdb") || (!strcmp(argv[j], "--xrdb"))) {
xresources = 1;
@@ -24,7 +24,9 @@ readargs(int argc, char *argv[])
}
}
+ #if USECONFIG
conf_init();
+ #endif
// init/read xrdb
if (xresources) {
diff --git a/libs/conf/config.c b/libs/conf/config.c
index 5729cb8..33135d3 100644
--- a/libs/conf/config.c
+++ b/libs/conf/config.c
@@ -46,9 +46,8 @@ conf_init(void)
// attempt to read config file to cfg
if (!config_read_file(&cfg, cfgfile)) {
- fprintf(stderr, "spmenu: '%s' is not a valid configuration file.\n", cfgfile);
- config_destroy(&cfg);
- return;
+ // invalid configuration, but let's try to read it anyway
+ ;
}
// load options spmenu.window
@@ -105,6 +104,180 @@ conf_init(void)
}
}
+ // load options spmenu.text
+ setting = config_lookup(&cfg, "spmenu.text");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // look up
+ config_setting_lookup_string(conf, "font", &dest); // spmenu.text.font
+ fonts[0] = strdup(dest);
+
+ config_setting_lookup_int(conf, "padding", &textpadding); // spmenu.text.padding
+
+ config_setting_lookup_string(conf, "leftarrow", &dest); // spmenu.text.leftarrow
+ leftarrow = strdup(dest);
+
+ config_setting_lookup_string(conf, "rightarrow", &dest); // spmenu.text.rightarrow
+ rightarrow = strdup(dest);
+
+ config_setting_lookup_string(conf, "password", &dest);
+ password = strdup(dest);
+
+ config_setting_lookup_string(conf, "prompt", &dest);
+ prompt = strdup(dest);
+
+ config_setting_lookup_string(conf, "input", &dest);
+ input = strdup(dest);
+ }
+ }
+
+ // load options spmenu.color
+ setting = config_lookup(&cfg, "spmenu.color");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // items
+ config_setting_lookup_string(conf, "itemnormfg", &dest);
+ colors[SchemeItemNorm][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "itemnormbg", &dest);
+ colors[SchemeItemNorm][ColBg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "itemselfg", &dest);
+ colors[SchemeItemSel][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "itemselbg", &dest);
+ colors[SchemeItemSel][ColBg] = strdup(dest);
+
+ // items with priority
+ config_setting_lookup_string(conf, "itemnormprifg", &dest);
+ colors[SchemeItemNormPri][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "itemnormpribg", &dest);
+ colors[SchemeItemNormPri][ColBg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "itemselprifg", &dest);
+ colors[SchemeItemSelPri][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "itemselpribg", &dest);
+ colors[SchemeItemSelPri][ColBg] = strdup(dest);
+
+ // input
+ config_setting_lookup_string(conf, "inputfg", &dest);
+ colors[SchemeInput][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "inputbg", &dest);
+ colors[SchemeInput][ColBg] = strdup(dest);
+
+ // menu
+ config_setting_lookup_string(conf, "menubg", &dest);
+ colors[SchemeMenu][ColBg] = strdup(dest);
+
+ // prompt
+ config_setting_lookup_string(conf, "promptfg", &dest);
+ colors[SchemePrompt][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "promptbg", &dest);
+ colors[SchemePrompt][ColBg] = strdup(dest);
+
+ // arrows
+ config_setting_lookup_string(conf, "larrowfg", &dest);
+ colors[SchemeLArrow][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "larrowbg", &dest);
+ colors[SchemeLArrow][ColBg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "rarrowfg", &dest);
+ colors[SchemeRArrow][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "rarrowbg", &dest);
+ colors[SchemeRArrow][ColBg] = strdup(dest);
+
+ // highlight
+ config_setting_lookup_string(conf, "hlnormfg", &dest);
+ colors[SchemeNormHighlight][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "hlnormbg", &dest);
+ colors[SchemeNormHighlight][ColBg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "hlselfg", &dest);
+ colors[SchemeSelHighlight][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "hlselbg", &dest);
+ colors[SchemeSelHighlight][ColBg] = strdup(dest);
+
+ // number
+ config_setting_lookup_string(conf, "numfg", &dest);
+ colors[SchemeNumber][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "numbg", &dest);
+ colors[SchemeNumber][ColBg] = strdup(dest);
+
+ // mode
+ config_setting_lookup_string(conf, "modefg", &dest);
+ colors[SchemeMode][ColFg] = strdup(dest);
+
+ config_setting_lookup_string(conf, "modebg", &dest);
+ colors[SchemeMode][ColBg] = strdup(dest);
+
+ // border
+ config_setting_lookup_string(conf, "borderbg", &dest);
+ colors[SchemeBorder][ColBg] = strdup(dest);
+
+ // caret
+ config_setting_lookup_string(conf, "caretfg", &dest);
+ colors[SchemeCaret][ColFg] = strdup(dest);
+
+ // sgr colors
+ config_setting_lookup_string(conf, "sgrcolor0", &dest);
+ textcolors[0] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor1", &dest);
+ textcolors[1] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor2", &dest);
+ textcolors[2] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor3", &dest);
+ textcolors[3] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor4", &dest);
+ textcolors[4] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor5", &dest);
+ textcolors[5] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor6", &dest);
+ textcolors[6] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor7", &dest);
+ textcolors[7] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor8", &dest);
+ textcolors[8] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor9", &dest);
+ textcolors[9] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor10", &dest);
+ textcolors[10] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor11", &dest);
+ textcolors[11] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor12", &dest);
+ textcolors[12] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor13", &dest);
+ textcolors[13] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor14", &dest);
+ textcolors[14] = strdup(dest);
+ config_setting_lookup_string(conf, "sgrcolor15", &dest);
+ textcolors[15] = strdup(dest);
+
+ // coloritems int
+ config_setting_lookup_int(conf, "coloritems", &coloritems);
+ }
+ }
+
// load options spmenu.image
setting = config_lookup(&cfg, "spmenu.image");
if (setting != NULL) {
@@ -153,6 +326,7 @@ conf_init(void)
// look up
config_setting_lookup_int(conf, "fast", &fast); // spmenu.input.fast
+ config_setting_lookup_int(conf, "type", &type); // spmenu.input.type
}
}
@@ -176,4 +350,110 @@ conf_init(void)
instext = strdup(dest);
}
}
+
+ // load options spmenu.match
+ setting = config_lookup(&cfg, "spmenu.match");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // look up
+ config_setting_lookup_int(conf, "sort", &sortmatches); // spmenu.match.sort
+ config_setting_lookup_int(conf, "casesensitive", &casesensitive); // spmenu.match.casesensitive
+ config_setting_lookup_int(conf, "fuzzy", &fuzzy); // spmenu.match.fuzzy
+ config_setting_lookup_int(conf, "preselected", &preselected); // spmenu.match.preselected
+ config_setting_lookup_int(conf, "accuratewidth", &accuratewidth); // spmenu.match.accuratewidth
+ config_setting_lookup_string(conf, "delimiters", &dest); // spmenu.match.delimiters
+ worddelimiters = strdup(dest);
+ }
+ }
+
+ // load options spmenu.line
+ setting = config_lookup(&cfg, "spmenu.line");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // look up
+ config_setting_lookup_int(conf, "height", &lineheight); // spmenu.line.height
+ config_setting_lookup_int(conf, "lines", &lines); // spmenu.line.lines
+ config_setting_lookup_int(conf, "columns", &columns); // spmenu.line.columns
+ config_setting_lookup_int(conf, "indentitems", &indentitems); // spmenu.line.indentitems
+ }
+ }
+
+ // load options spmenu.history
+ setting = config_lookup(&cfg, "spmenu.history");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // look up
+ config_setting_lookup_int(conf, "max", &maxhist); // spmenu.history.max
+ config_setting_lookup_int(conf, "duplicate", &histdup); // spmenu.history.duplicate
+ }
+ }
+
+ // load options spmenu.hide
+ setting = config_lookup(&cfg, "spmenu.hide");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // look up
+ config_setting_lookup_int(conf, "input", &hideinput); // spmenu.hide.input
+ config_setting_lookup_int(conf, "larrow", &hidelarrow); // spmenu.hide.larrow
+ config_setting_lookup_int(conf, "rarrow", &hiderarrow); // spmenu.hide.rarrow
+ config_setting_lookup_int(conf, "prompt", &hideprompt); // spmenu.hide.prompt
+ config_setting_lookup_int(conf, "powerline", &hidepowerline); // spmenu.hide.powerline
+ config_setting_lookup_int(conf, "cursor", &hidecursor); // spmenu.hide.cursor
+ config_setting_lookup_int(conf, "highlight", &hidehighlight); // spmenu.hide.highlight
+ config_setting_lookup_int(conf, "matchcount", &hidematchcount); // spmenu.hide.matchcount
+ config_setting_lookup_int(conf, "mode", &hidemode); // spmenu.hide.mode
+ config_setting_lookup_int(conf, "hideimage", &hideimage); // spmenu.hide.image
+ }
+ }
+
+ // load options spmenu.pango
+ setting = config_lookup(&cfg, "spmenu.pango");
+ if (setting != NULL) {
+ unsigned int i = 0;
+
+ conflength = config_setting_length(setting);
+
+ for (i = 0; i < conflength; ++i) {
+ config_setting_t *conf = config_setting_get_elem(setting, i);
+
+ // look up
+ config_setting_lookup_int(conf, "item", &pango_item); // spmenu.pango.input
+ config_setting_lookup_int(conf, "highlight", &pango_highlight); // spmenu.pango.highlight
+ config_setting_lookup_int(conf, "prompt", &pango_prompt); // spmenu.pango.rarrow
+ config_setting_lookup_int(conf, "input", &pango_input); // spmenu.pango.input
+ config_setting_lookup_int(conf, "leftarrow", &pango_leftarrow); // spmenu.pango.leftarrow
+ config_setting_lookup_int(conf, "rightarrow", &pango_rightarrow); // spmenu.pango.rightarrow
+ config_setting_lookup_int(conf, "numbers", &pango_numbers); // spmenu.pango.numbers
+ config_setting_lookup_int(conf, "mode", &pango_mode); // spmenu.pango.mode
+ config_setting_lookup_int(conf, "password", &pango_password); // spmenu.pango.mode
+ }
+ }
+
+ // we're done here
+ config_destroy(&cfg);
+ return;
}
diff --git a/libs/draw.c b/libs/draw.c
index 964361a..5e817df 100644
--- a/libs/draw.c
+++ b/libs/draw.c
@@ -269,7 +269,9 @@ drawinput(int x, int y, int w)
drw_setscheme(drw, scheme[SchemeInput]);
if (passwd && !hideprompt) {
censort = ecalloc(1, sizeof(text));
- memset(censort, (int)password, strlen(text));
+
+ for (int i = 0; i < strlen(text); i++)
+ memcpy(&censort[i], password, strlen(text));
apply_fribidi(censort);
drw_text(drw, x, 0, w, bh, lrpad / 2, isrtl ? fribidi_text : censort, 0, pango_password ? True : False);
diff --git a/libs/xresources.h b/libs/xresources.h
index 7f526a5..dc24706 100644
--- a/libs/xresources.h
+++ b/libs/xresources.h
@@ -80,7 +80,7 @@ ResourcePref resources[] = {
{ "hideinput", INTEGER, &hideinput },
{ "hidepowerline", INTEGER, &hidepowerline },
{ "hidecursor", INTEGER, &hidecursor },
- { "histnodup", INTEGER, &histnodup },
+ { "histdup", INTEGER, &histdup },
{ "casesensitive", INTEGER, &casesensitive },
{ "imagewidth", INTEGER, &imagewidth },
{ "imageheight", INTEGER, &imageheight },
diff --git a/options.h b/options.h
index c5ec8bf..9e220be 100644
--- a/options.h
+++ b/options.h
@@ -46,7 +46,7 @@ static int textpadding = 0; /* Text padding (lrpad) */
/* Text 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 */
-static char password = '*'; /* Password character, when the -P argument is active this will replace all characters typed */
+static char *password = "*"; /* Password character, when the -P argument is active this will replace all characters typed */
static char *prompt = NULL; /* Default prompt */
static char *input = NULL; /* Default input text */
@@ -64,8 +64,8 @@ static int lines = 0; /* Default number of lines */
static int columns = 10; /* Default number of columns */
/* History options */
-static unsigned int maxhist = 64; /* Max number of history entries */
-static int histnodup = 1; /* If 0, record repeated histories */
+static int maxhist = 64; /* Max number of history entries */
+static int histdup = 0; /* If 1, record repeated histories */
/* Prompt options */
static int indentitems = 1; /* Indent items to prompt width? (0/1) */
@@ -169,4 +169,4 @@ static int pango_password = 0; /* Enable support for pango markup f
/* Misc */
static int coloritems = 1; /* Color items or not */
-static char worddelimiters[] = " "; /* Word delimiters used for keybinds that change words, " " is default. */
+static char *worddelimiters = " "; /* Word delimiters used for keybinds that change words, " " is default. */
diff --git a/spmenu.1 b/spmenu.1
index bf1a300..a3ca129 100644
--- a/spmenu.1
+++ b/spmenu.1
@@ -601,13 +601,30 @@ See this page (https://docs.gtk.org/Pango/pango_markup.html) for more
information.
.SH Configuration
.PP
-spmenu has .Xresources (xrdb) support built in.
+Unlike dmenu, spmenu has a configuration file which can be edited by
+hand.
+It is located in \[ti]/.config/spmenu/spmenu.conf, but you can override
+this by exporting \f[V]$XDG_CONFIG_HOME\f[R].
+.PP
+When spmenu is installed, it copies a sample configuration to
+/usr/share/spmenu/spmenu.conf.
+You can copy this to your \f[V].config/spmenu\f[R] directory.
+This configuration file is loaded on startup.
+.PP
+You can also include other configuration files in the configuration file
+using \f[V]\[at]include \[dq]path/to/config\[dq]\f[R].
+.SH .Xresources
+.PP
+spmenu also has .Xresources (xrdb) support built in.
It reads the xrdb (.Xresources database) on runtime.
You may disable it by passing -nxrdb, or enable it by padding -xrdb.
+You can also set this in the regular config file.
.PP
spmenu loads \f[V]\[ti]/.config/spmenu/spmenurc\f[R] or alternatively if
-you\[cq]re old fashioned, \f[V]\[ti]/.spmenurc\f[R].
+you\[cq]re old fashioned, \f[V]\[ti]/.spmenurc\f[R] on startup.
This requires that \f[V]xrdb\f[R] is available on your operating system.
+Of course, you don\[cq]t NEED to use them, as you can just
+\f[V]xrdb -override\f[R] any .Xresources file you want.
.PP
You can also use wildcards (such as \f[V]*\f[R]) to achieve a global
colorscheme.
diff --git a/spmenu.c b/spmenu.c
index b042cf4..7a43438 100644
--- a/spmenu.c
+++ b/spmenu.c
@@ -50,6 +50,13 @@
#define USEXINERAMA 1
#endif
+// check if we should enable config file support using libconfig
+#ifndef CONFIG
+#define USECONFIG 0
+#else
+#define USECONFIG 1
+#endif
+
// include fribidi used for right to left language support
#if USERTL
#include
@@ -205,11 +212,13 @@ static size_t nextrune(int inc);
#include "libs/xresources.h"
#include "libs/colors.h"
+static char *fonts[] = { font };
+
// config file
+#if USECONFIG
#include "libs/conf/config.h"
#include "libs/conf/config.c"
-
-static char *fonts[] = { font };
+#endif
// matching
static char * cistrstr(const char *s, const char *sub);
diff --git a/themes/README.md b/themes/README.md
index 01a823b..f661f16 100644
--- a/themes/README.md
+++ b/themes/README.md
@@ -3,9 +3,15 @@
spmenu has a profile feature, which allows you to quickly switch between
configuration files. For this reason, it is possible to quickly switch between colorschemes.
-Feel free to contribute your own colorschemes here.
+legacy/ contains themes applied through .Xresources, while the current directory contains
+themes included from spmenu.conf.
-## Usage
+Feel free to contribute your own colorschemes here in either form.
+
+## Usage (.Xresources)
+
+**NOTE: These is nothing wrong with using the .Xresources themes, despite them
+having the 'legacy' name.**
To switch between profiles in spmenu, you use Ctrl+Shift+p. It will spawn a
list of installed profiles, but also allows you to add/remove profiles.
@@ -17,3 +23,7 @@ it to start using it!
To switch back remove the profile or switch back to the default profile using 'Default'.
Alternatively, run `install.sh` to install all the themes instantly.
+
+## Usage (spmenurc)
+
+Install it, and `@include` it in your spmenu.conf.
diff --git a/themes/install.sh b/themes/install.sh
index 8b3b275..f4bd4e4 100755
--- a/themes/install.sh
+++ b/themes/install.sh
@@ -1,6 +1,7 @@
#!/bin/sh
# install.sh
# This script installs all the profiles, allowing spmenu to see and choose them.
-mkdir -p "$HOME/.config/spmenu/profiles/"
-cp ./* "$HOME/.config/spmenu/profiles/"
-rm -f "$HOME/.config/spmenu/profiles/install.sh" "$HOME/.config/spmenu/profiles/README.md"
+CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}"
+mkdir -p "$CONFDIR/spmenu/profiles/"
+cp ./* legacy/* "$CONFDIR/spmenu/profiles/"
+rm -f "$CONFDIR/spmenu/profiles/install.sh" "$CONFDIR/spmenu/profiles/README.md" "$CONFDIR/spmenu/profiles/sample.theme"
diff --git a/themes/Catppuccin b/themes/legacy/Catppuccin
similarity index 100%
rename from themes/Catppuccin
rename to themes/legacy/Catppuccin
diff --git a/themes/Cyberpunk-Neon b/themes/legacy/Cyberpunk-Neon
similarity index 100%
rename from themes/Cyberpunk-Neon
rename to themes/legacy/Cyberpunk-Neon
diff --git a/themes/Doom-One b/themes/legacy/Doom-One
similarity index 100%
rename from themes/Doom-One
rename to themes/legacy/Doom-One
diff --git a/themes/Dracula b/themes/legacy/Dracula
similarity index 100%
rename from themes/Dracula
rename to themes/legacy/Dracula
diff --git a/themes/Gruvbox-Dark b/themes/legacy/Gruvbox-Dark
similarity index 100%
rename from themes/Gruvbox-Dark
rename to themes/legacy/Gruvbox-Dark
diff --git a/themes/No-Global-Colors b/themes/legacy/No-Global-Colors
similarity index 100%
rename from themes/No-Global-Colors
rename to themes/legacy/No-Global-Colors
diff --git a/themes/Nord b/themes/legacy/Nord
similarity index 100%
rename from themes/Nord
rename to themes/legacy/Nord
diff --git a/themes/Solarized-Dark b/themes/legacy/Solarized-Dark
similarity index 100%
rename from themes/Solarized-Dark
rename to themes/legacy/Solarized-Dark
diff --git a/themes/Tokyo-Night b/themes/legacy/Tokyo-Night
similarity index 100%
rename from themes/Tokyo-Night
rename to themes/legacy/Tokyo-Night
diff --git a/themes/sample.theme b/themes/sample.theme
new file mode 100644
index 0000000..be5717f
--- /dev/null
+++ b/themes/sample.theme
@@ -0,0 +1,9 @@
+/* This is a sample theme.
+ * It simply sets the font to Terminus.
+ *
+ * You can include this from your spmenu.conf using `@include "path/to/sample.theme`
+ */
+
+spmenu = {
+ text = ( { font = "Terminus 8"; } );
+};
diff --git a/toggle.mk b/toggle.mk
index 2322333..5842101 100644
--- a/toggle.mk
+++ b/toggle.mk
@@ -4,23 +4,28 @@
# Multi-monitor support.
# Requires libXinerama
# Comment these lines if you don't need it.
-XINERAMALIBS = -lXinerama
-XINERAMATOGGLE = -DXINERAMA
+XINERAMALIBS = -lXinerama
+XINERAMATOGGLE = -DXINERAMA
# Right to left language support
# Comment these lines if you don't need it.
-BDLIBS = -lfribidi
-BDINC = $(INCDIR)/fribidi
-BDTOGGLE = -DRTL
+BDLIBS = -lfribidi
+BDINC = $(INCDIR)/fribidi
+BDTOGGLE = -DRTL
# Pango
# Comment these lines if you don't need it.
-PANGOCONF = pango
-PANGOXFTCONF = pangoxft
-PANGOTOGGLE = -DPANGO
+PANGOCONF = pango
+PANGOXFTCONF = pangoxft
+PANGOTOGGLE = -DPANGO
# Image support
# Comment these lines if you don't need it.
-IMLIB2LIBS = -lImlib2
-IMLIB2TOGGLE = -DIMAGE
-OPENSSLCONF = openssl
+IMLIB2LIBS = -lImlib2
+IMLIB2TOGGLE = -DIMAGE
+OPENSSLCONF = openssl
+
+# Config file support
+# Comment these lines if you don't need it.
+LIBCONFIGTOGGLE = -DCONFIG
+LIBCONFIGCONF = libconfig