some changes to the general codebase. also add spmenu:about which

displays information about the compiled spmenu build
This commit is contained in:
speedie 2023-03-24 03:14:24 +01:00
parent 1f2a37c1d2
commit b8e7fd27db
7 changed files with 126 additions and 128 deletions

View file

@ -45,6 +45,9 @@ install: all
mkdir -p $(DESTDIR)$(PREFIX)/share/spmenu mkdir -p $(DESTDIR)$(PREFIX)/share/spmenu
cp -r docs/* $(DESTDIR)$(PREFIX)/share/spmenu/ cp -r docs/* $(DESTDIR)$(PREFIX)/share/spmenu/
echo "${VERSION}" > $(DESTDIR)$(PREFIX)/share/spmenu/version echo "${VERSION}" > $(DESTDIR)$(PREFIX)/share/spmenu/version
echo "${CC}" > $(DESTDIR)$(PREFIX)/share/spmenu/cc
echo "${CFLAGS}" > $(DESTDIR)$(PREFIX)/share/spmenu/cflags
echo "$$(date "+%D %T")" > $(DESTDIR)$(PREFIX)/share/spmenu/compile-date
cp -r spmenu scripts/spmenu* $(DESTDIR)$(PREFIX)/bin cp -r spmenu scripts/spmenu* $(DESTDIR)$(PREFIX)/bin
[ -f spmenu.1 ] && mkdir -p ${DESTDIR}${MANPREFIX}/man1 || : [ -f spmenu.1 ] && mkdir -p ${DESTDIR}${MANPREFIX}/man1 || :
[ -f spmenu.1 ] && cp spmenu.1 ${DESTDIR}${MANPREFIX}/man1/spmenu.1 || : [ -f spmenu.1 ] && cp spmenu.1 ${DESTDIR}${MANPREFIX}/man1/spmenu.1 || :

View file

@ -77,9 +77,6 @@ void
movedown(const Arg *arg) movedown(const Arg *arg)
{ {
struct item *tmpsel;
int i, offscreen = 0;
int argu = arg->i ? arg->i : 1; int argu = arg->i ? arg->i : 1;
for (int j = 0; j < argu; j++) { for (int j = 0; j < argu; j++) {
@ -95,9 +92,6 @@ movedown(const Arg *arg)
void void
moveup(const Arg *arg) moveup(const Arg *arg)
{ {
struct item *tmpsel;
int i, offscreen = 0;
int argu = arg->i ? arg->i : 1; int argu = arg->i ? arg->i : 1;
for (int j = 0; j < argu; j++) { for (int j = 0; j < argu; j++) {
@ -228,13 +222,13 @@ viewhist(const Arg *arg)
void void
deleteword(const Arg *arg) deleteword(const Arg *arg)
{ {
if (cursor == 0) if (cursor == 0) return;
return;
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) {
insert(NULL, nextrune(-1) - cursor); insert(NULL, nextrune(-1) - cursor);
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) } while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) {
insert(NULL, nextrune(-1) - cursor); insert(NULL, nextrune(-1) - cursor);
}
drawmenu(); drawmenu();
} }
@ -243,16 +237,18 @@ void
moveword(const Arg *arg) moveword(const Arg *arg)
{ {
if (arg->i < 0) { // move cursor to the start of the word if (arg->i < 0) { // move cursor to the start of the word
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) {
cursor = nextrune(-1); cursor = nextrune(-1);
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) } while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) {
cursor = nextrune(-1); cursor = nextrune(-1);
}
} else { // move cursor to the end of the word } else { // move cursor to the end of the word
while (text[cursor] && strchr(worddelimiters, text[cursor])) while (text[cursor] && strchr(worddelimiters, text[cursor])) {
cursor = nextrune(+1); cursor = nextrune(+1);
while (text[cursor] && !strchr(worddelimiters, text[cursor])) } while (text[cursor] && !strchr(worddelimiters, text[cursor])) {
cursor = nextrune(+1); cursor = nextrune(+1);
} }
}
drawmenu(); drawmenu();
} }

View file

@ -5,13 +5,11 @@ drawhighlights(struct item *item, int x, int y, int w)
char *highlight; char *highlight;
char c; char c;
if (columns > 5) if (columns > 5 && lines > 1) return;
return;
char *itemtext = item->text; char *itemtext = item->text;
if (!(strlen(itemtext) && strlen(text))) if (!(strlen(itemtext) && strlen(text))) return;
return;
drw_setscheme(drw, scheme[item == sel drw_setscheme(drw, scheme[item == sel
? SchemeSelHighlight ? SchemeSelHighlight
@ -160,7 +158,6 @@ drawmenu(void)
#endif #endif
char *censort; // censor text (password) char *censort; // censor text (password)
plw = hidepowerline ? 0 : drw->font->h / 2 + 1; // powerline size plw = hidepowerline ? 0 : drw->font->h / 2 + 1; // powerline size
Clr *prevscheme, *nextscheme;
// draw menu first using menu scheme // draw menu first using menu scheme
drw_setscheme(drw, scheme[SchemeMenu]); drw_setscheme(drw, scheme[SchemeMenu]);
@ -177,7 +174,6 @@ drawmenu(void)
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow); if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (prompt && *prompt) { if (prompt && *prompt) {
prevscheme = scheme[SchemePrompt];
drw_setscheme(drw, scheme[SchemePrompt]); drw_setscheme(drw, scheme[SchemePrompt]);
#if USEIMAGE #if USEIMAGE
@ -283,7 +279,6 @@ drawmenu(void)
} }
if (!hidematchcount) { // draw match count if (!hidematchcount) { // draw match count
prevscheme = scheme[SchemeNumber];
drw_setscheme(drw, scheme[SchemeNumber]); drw_setscheme(drw, scheme[SchemeNumber]);
drw_text(drw, mw - numberWidth - modeWidth, 0, numberWidth, bh, lrpad / 2 + plw / 2, numbers, 0, pango_numbers ? True : False); drw_text(drw, mw - numberWidth - modeWidth, 0, numberWidth, bh, lrpad / 2 + plw / 2, numbers, 0, pango_numbers ? True : False);
@ -298,7 +293,6 @@ drawmenu(void)
} }
if (!hidemode) { // draw mode indicator if (!hidemode) { // draw mode indicator
prevscheme = scheme[SchemeMode];
drw_setscheme(drw, scheme[SchemeMode]); drw_setscheme(drw, scheme[SchemeMode]);
drw_text(drw, mw - modeWidth, 0, modeWidth, bh, lrpad / 2 + plw / 2, modetext, 0, pango_mode ? True : False); drw_text(drw, mw - modeWidth, 0, modeWidth, bh, lrpad / 2 + plw / 2, modetext, 0, pango_mode ? True : False);

108
libs/stream.c Normal file
View file

@ -0,0 +1,108 @@
void
readstdin(void)
{
char buf[sizeof text], *p;
size_t i, imax = 0, itemsiz = 0;
unsigned int tmpmax = 0;
#if USEIMAGE
int w, h;
char *limg = NULL;
#endif
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++) {
if (i + 1 >= itemsiz) {
itemsiz += 256;
if (!(items = realloc(items, itemsiz * sizeof(*items))))
die("cannot realloc %zu bytes:", itemsiz * sizeof(*items));
}
if ((p = strchr(buf, '\n')))
*p = '\0';
if (!(items[i].text = strdup(buf)))
die("cannot strdup %u bytes:", strlen(buf) + 1);
items[i].hp = arrayhas(hpitems, hplength, items[i].text);
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True);
if (tmpmax > inputw) {
inputw = tmpmax;
imax = i;
}
// parse image markup
#if USEIMAGE
if(!strncmp("IMG:", items[i].text, strlen("IMG:"))) {
if(!(items[i].image = malloc(strlen(items[i].text)+1)))
fprintf(stderr, "spmenu: cannot malloc %lu bytes\n", strlen(items[i].text));
if(sscanf(items[i].text, "IMG:%[^\t]", items[i].image)) {
items[i].text += strlen("IMG:")+strlen(items[i].image)+1;
} else {
free(items[i].image);
items[i].image = NULL;
}
} else {
items[i].image = NULL;
}
// load image cache (or generate)
if (generatecache && longestedge <= 256 && items[i].image && strcmp(items[i].image, limg ? limg : "")) {
loadimagecache(items[i].image, &w, &h);
fprintf(stdout, "spmenu: generating thumbnail for: %s\n", items[i].image);
}
if(items[i].image) {
limg = items[i].image;
}
#endif
/* TODO: use this for something
* current usage is not very useful, however it's here to be used later.
*/
if(!(items[i].ex = malloc(strlen(items[i].text)+1)))
fprintf(stderr, "spmenu: cannot malloc %lu bytes\n", strlen(items[i].text));
if (!strncmp("spmenu:", items[i].text, strlen("spmenu:"))) {
if (sscanf(items[i].text, "spmenu:%[^\t]", items[i].ex)) {
items[i].text += strlen("spmenu:")+strlen(items[i].ex)+1;
}
// spmenu:version
if (!strncmp("version", items[i].ex, strlen("version"))) {
die("spmenu version %s", VERSION);
}
// spmenu:license
if (!strncmp("license", items[i].ex, strlen("license"))) {
die("spmenu is licensed under the MIT license. See the included LICENSE file for more information.");
}
// spmenu:about
if (!strncmp("about", items[i].ex, strlen("about"))) {
int i = system("printf \"spmenu $([ -f '/usr/share/spmenu/version' ] && cat /usr/share/spmenu/version || printf unknown)\\nBased on dmenu 5.2 from https://tools.suckless.org/dmenu\\nCompiled $([ -f '/usr/share/spmenu/compile-date' ] && cat /usr/share/spmenu/compile-date || printf unknown)\\nCFLAGS: $([ -f '/usr/share/spmenu/cflags' ] && cat /usr/share/spmenu/cflags || printf unknown)\\nCC: $([ -f '/usr/share/spmenu/cc' ] && cat /usr/share/spmenu/cc || printf unknown)\" | spmenu --columns 1 --lines 5 --hide-cursor --no-allow-typing --hide-mode --hide-match-count --hide-powerline --no-indent > /dev/null");
if (i||!i) exit(0);
}
// spmenu:test
if (!strncmp("test", items[i].ex, strlen("test"))) {
int i = system("command -v spmenu_test > /dev/null && spmenu_test");
if (i||!i) exit(0);
}
}
}
// clean
if (items) {
#if USEIMAGE
items[i].image = NULL;
#endif
items[i].text = NULL;
}
#if USEIMAGE
if (!limg) longestedge = imagegaps = 0;
#endif
inputw = items ? TEXTWM(items[imax].text) : 0;
lines = MIN(lines, i);
}

1
libs/stream.h Normal file
View file

@ -0,0 +1 @@
static void readstdin(void);

View file

@ -60,7 +60,6 @@ static unsigned int maxhist = 64; /* Max number of history entries */
static int histnodup = 1; /* If 0, record repeated histories */ static int histnodup = 1; /* If 0, record repeated histories */
/* Prompt options */ /* Prompt options */
static int promptheight = 10; /* Extra prompt height */
static int indentitems = 1; /* Indent items to prompt width? (0/1) */ static int indentitems = 1; /* Indent items to prompt width? (0/1) */
static char *prompt = NULL; /* Default prompt, set to NULL (nothing) */ static char *prompt = NULL; /* Default prompt, set to NULL (nothing) */

107
spmenu.c
View file

@ -89,6 +89,7 @@
// various headers // various headers
#include "libs/sl/draw.h" #include "libs/sl/draw.h"
#include "libs/sl/main.h" #include "libs/sl/main.h"
#include "libs/stream.h"
#include "libs/schemes.h" #include "libs/schemes.h"
#include "libs/arg.h" #include "libs/arg.h"
#include "libs/mode.h" #include "libs/mode.h"
@ -117,7 +118,6 @@ static int numlockmask = 0;
// height of each item, menu width, menu height // height of each item, menu width, menu height
static int bh, mw, mh; static int bh, mw, mh;
static int reallines = 0; static int reallines = 0;
static int reqlineheight; // required menu height
static int dmx = 0; // put spmenu at this x offset static int dmx = 0; // put spmenu at this x offset
static int dmy = 0; // put spmenu at this y offset (measured from the bottom if menuposition is 0) static int dmy = 0; // put spmenu at this y offset (measured from the bottom if menuposition is 0)
static unsigned int dmw = 0; // make spmenu this wide static unsigned int dmw = 0; // make spmenu this wide
@ -188,7 +188,6 @@ static size_t histsz, histpos;
static void drawmenu(void); static void drawmenu(void);
static void drawhighlights(struct item *item, int x, int y, int w); static void drawhighlights(struct item *item, int x, int y, int w);
static void calcoffsets(void); static void calcoffsets(void);
static void readstdin(void);
static void recalculatenumbers(void); static void recalculatenumbers(void);
static void usage(void); static void usage(void);
static void insert(const char *str, ssize_t n); static void insert(const char *str, ssize_t n);
@ -236,6 +235,7 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/match.h" #include "libs/match.h"
#include "libs/match.c" #include "libs/match.c"
#include "libs/arg.c" #include "libs/arg.c"
#include "libs/stream.c"
void void
appenditem(struct item *item, struct item **list, struct item **last) appenditem(struct item *item, struct item **list, struct item **last)
@ -540,109 +540,6 @@ xinitvisual()
} }
} }
void
readstdin(void)
{
char buf[sizeof text], *p;
size_t i, imax = 0, itemsiz = 0;
unsigned int tmpmax = 0;
#if USEIMAGE
int w, h;
char *limg = NULL;
#endif
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++) {
if (i + 1 >= itemsiz) {
itemsiz += 256;
if (!(items = realloc(items, itemsiz * sizeof(*items))))
die("cannot realloc %zu bytes:", itemsiz * sizeof(*items));
}
if ((p = strchr(buf, '\n')))
*p = '\0';
if (!(items[i].text = strdup(buf)))
die("cannot strdup %u bytes:", strlen(buf) + 1);
items[i].hp = arrayhas(hpitems, hplength, items[i].text);
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True);
if (tmpmax > inputw) {
inputw = tmpmax;
imax = i;
}
// parse image markup
#if USEIMAGE
if(!strncmp("IMG:", items[i].text, strlen("IMG:"))) {
if(!(items[i].image = malloc(strlen(items[i].text)+1)))
fprintf(stderr, "spmenu: cannot malloc %lu bytes\n", strlen(items[i].text));
if(sscanf(items[i].text, "IMG:%[^\t]", items[i].image)) {
items[i].text += strlen("IMG:")+strlen(items[i].image)+1;
} else {
free(items[i].image);
items[i].image = NULL;
}
} else {
items[i].image = NULL;
}
// load image cache (or generate)
if (generatecache && longestedge <= 256 && items[i].image && strcmp(items[i].image, limg ? limg : "")) {
loadimagecache(items[i].image, &w, &h);
fprintf(stdout, "spmenu: generating thumbnail for: %s\n", items[i].image);
}
if(items[i].image) {
limg = items[i].image;
}
#endif
/* TODO: use this for something
* current usage is not very useful, however it's here to be used later.
*/
if(!(items[i].ex = malloc(strlen(items[i].text)+1)))
fprintf(stderr, "spmenu: cannot malloc %lu bytes\n", strlen(items[i].text));
if (!strncmp("spmenu:", items[i].text, strlen("spmenu:"))) {
if (sscanf(items[i].text, "spmenu:%[^\t]", items[i].ex)) {
items[i].text += strlen("spmenu:")+strlen(items[i].ex)+1;
}
// spmenu:version
if (!strncmp("version", items[i].ex, strlen("version"))) {
die("spmenu version %s", VERSION);
}
// spmenu:license
if (!strncmp("license", items[i].ex, strlen("license"))) {
die("spmenu is licensed under the MIT license. See the included LICENSE file for more information.");
}
// spmenu:test
if (!strncmp("test", items[i].ex, strlen("test"))) {
int i = system("command -v spmenu_test > /dev/null && spmenu_test");
if (i||!i) exit(0);
}
}
}
// clean
if (items) {
#if USEIMAGE
items[i].image = NULL;
#endif
items[i].text = NULL;
}
#if USEIMAGE
if (!limg) longestedge = imagegaps = 0;
#endif
inputw = items ? TEXTWM(items[imax].text) : 0;
lines = MIN(lines, i);
}
void void
setup(void) setup(void)
{ {