some changes to the general codebase. also add spmenu:about which
displays information about the compiled spmenu build
This commit is contained in:
parent
1f2a37c1d2
commit
b8e7fd27db
3
Makefile
3
Makefile
|
@ -45,6 +45,9 @@ install: all
|
|||
mkdir -p $(DESTDIR)$(PREFIX)/share/spmenu
|
||||
cp -r docs/* $(DESTDIR)$(PREFIX)/share/spmenu/
|
||||
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
|
||||
[ -f spmenu.1 ] && mkdir -p ${DESTDIR}${MANPREFIX}/man1 || :
|
||||
[ -f spmenu.1 ] && cp spmenu.1 ${DESTDIR}${MANPREFIX}/man1/spmenu.1 || :
|
||||
|
|
24
libs/arg.c
24
libs/arg.c
|
@ -77,9 +77,6 @@ void
|
|||
movedown(const Arg *arg)
|
||||
{
|
||||
|
||||
struct item *tmpsel;
|
||||
int i, offscreen = 0;
|
||||
|
||||
int argu = arg->i ? arg->i : 1;
|
||||
|
||||
for (int j = 0; j < argu; j++) {
|
||||
|
@ -95,9 +92,6 @@ movedown(const Arg *arg)
|
|||
void
|
||||
moveup(const Arg *arg)
|
||||
{
|
||||
struct item *tmpsel;
|
||||
int i, offscreen = 0;
|
||||
|
||||
int argu = arg->i ? arg->i : 1;
|
||||
|
||||
for (int j = 0; j < argu; j++) {
|
||||
|
@ -228,13 +222,13 @@ viewhist(const Arg *arg)
|
|||
void
|
||||
deleteword(const Arg *arg)
|
||||
{
|
||||
if (cursor == 0)
|
||||
return;
|
||||
if (cursor == 0) return;
|
||||
|
||||
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
|
||||
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) {
|
||||
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);
|
||||
}
|
||||
|
||||
drawmenu();
|
||||
}
|
||||
|
@ -243,15 +237,17 @@ void
|
|||
moveword(const Arg *arg)
|
||||
{
|
||||
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);
|
||||
while (cursor > 0 && !strchr(worddelimiters, text[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]))
|
||||
while (text[cursor] && strchr(worddelimiters, text[cursor])) {
|
||||
cursor = nextrune(+1);
|
||||
while (text[cursor] && !strchr(worddelimiters, text[cursor]))
|
||||
} while (text[cursor] && !strchr(worddelimiters, text[cursor])) {
|
||||
cursor = nextrune(+1);
|
||||
}
|
||||
}
|
||||
|
||||
drawmenu();
|
||||
|
|
10
libs/draw.c
10
libs/draw.c
|
@ -5,13 +5,11 @@ drawhighlights(struct item *item, int x, int y, int w)
|
|||
char *highlight;
|
||||
char c;
|
||||
|
||||
if (columns > 5)
|
||||
return;
|
||||
if (columns > 5 && lines > 1) return;
|
||||
|
||||
char *itemtext = item->text;
|
||||
|
||||
if (!(strlen(itemtext) && strlen(text)))
|
||||
return;
|
||||
if (!(strlen(itemtext) && strlen(text))) return;
|
||||
|
||||
drw_setscheme(drw, scheme[item == sel
|
||||
? SchemeSelHighlight
|
||||
|
@ -160,7 +158,6 @@ drawmenu(void)
|
|||
#endif
|
||||
char *censort; // censor text (password)
|
||||
plw = hidepowerline ? 0 : drw->font->h / 2 + 1; // powerline size
|
||||
Clr *prevscheme, *nextscheme;
|
||||
|
||||
// draw menu first using menu scheme
|
||||
drw_setscheme(drw, scheme[SchemeMenu]);
|
||||
|
@ -177,7 +174,6 @@ drawmenu(void)
|
|||
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
|
||||
|
||||
if (prompt && *prompt) {
|
||||
prevscheme = scheme[SchemePrompt];
|
||||
drw_setscheme(drw, scheme[SchemePrompt]);
|
||||
|
||||
#if USEIMAGE
|
||||
|
@ -283,7 +279,6 @@ drawmenu(void)
|
|||
}
|
||||
|
||||
if (!hidematchcount) { // draw match count
|
||||
prevscheme = 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);
|
||||
|
@ -298,7 +293,6 @@ drawmenu(void)
|
|||
}
|
||||
|
||||
if (!hidemode) { // draw mode indicator
|
||||
prevscheme = 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);
|
||||
|
|
108
libs/stream.c
Normal file
108
libs/stream.c
Normal 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
1
libs/stream.h
Normal file
|
@ -0,0 +1 @@
|
|||
static void readstdin(void);
|
|
@ -60,7 +60,6 @@ static unsigned int maxhist = 64; /* Max number of history entries */
|
|||
static int histnodup = 1; /* If 0, record repeated histories */
|
||||
|
||||
/* Prompt options */
|
||||
static int promptheight = 10; /* Extra prompt height */
|
||||
static int indentitems = 1; /* Indent items to prompt width? (0/1) */
|
||||
static char *prompt = NULL; /* Default prompt, set to NULL (nothing) */
|
||||
|
||||
|
|
107
spmenu.c
107
spmenu.c
|
@ -89,6 +89,7 @@
|
|||
// various headers
|
||||
#include "libs/sl/draw.h"
|
||||
#include "libs/sl/main.h"
|
||||
#include "libs/stream.h"
|
||||
#include "libs/schemes.h"
|
||||
#include "libs/arg.h"
|
||||
#include "libs/mode.h"
|
||||
|
@ -117,7 +118,6 @@ static int numlockmask = 0;
|
|||
// height of each item, menu width, menu height
|
||||
static int bh, mw, mh;
|
||||
static int reallines = 0;
|
||||
static int reqlineheight; // required menu height
|
||||
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 unsigned int dmw = 0; // make spmenu this wide
|
||||
|
@ -188,7 +188,6 @@ static size_t histsz, histpos;
|
|||
static void drawmenu(void);
|
||||
static void drawhighlights(struct item *item, int x, int y, int w);
|
||||
static void calcoffsets(void);
|
||||
static void readstdin(void);
|
||||
static void recalculatenumbers(void);
|
||||
static void usage(void);
|
||||
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.c"
|
||||
#include "libs/arg.c"
|
||||
#include "libs/stream.c"
|
||||
|
||||
void
|
||||
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
|
||||
setup(void)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue