add the ability to read from file, been wanting this for a very long

time
This commit is contained in:
speedie 2023-05-07 01:41:30 +02:00
parent 442c40b732
commit 63e5be2884
13 changed files with 128 additions and 12 deletions

View file

@ -188,6 +188,7 @@ href="https://git.speedie.site/speedwm">speedwm</a>.</p>
<li>Vim-like modes, including indicator.</li>
<li>The ability to move around items with keybinds.</li>
<li>Customizable/dynamic line/column size.</li>
<li>Ability to update entries dynamically by reading from file</li>
<li>IME support
<ul>
<li>Was removed from suckless dmenu years ago due to issues Ive
@ -330,7 +331,6 @@ easy to have LibreSSL compatibility.</li>
</ul></li>
<li>Matching: Add support for contextual completions similar to
xprompt</li>
<li>Matching: FIFO, used to dynamically refresh entries.</li>
<li>Matching: Regex matching
<ul>
<li>Probably use some minimal public domain library for this, Id like

View file

@ -22,6 +22,7 @@ It is designed to integrate well with my [dwm](https://dwm.suckless.org) fork, [
- Vim-like modes, including indicator.
- The ability to move around items with keybinds.
- Customizable/dynamic line/column size.
- Ability to update entries dynamically by reading from file
- IME support
- Was removed from suckless dmenu years ago due to issues I've resolved
- Powerlines
@ -130,7 +131,6 @@ have LibreSSL compatibility.
- Just need to `XMoveResizeWindow()` as well as `mh += bh` and `y += bh`
for each added line.
- Matching: Add support for contextual completions similar to xprompt
- Matching: FIFO, used to dynamically refresh entries.
- Matching: Regex matching
- Probably use some minimal public domain library for this, I'd
like to avoid adding more external dependencies unless it's a

View file

@ -265,7 +265,11 @@ You may use long, descriptive arguments or the shorter arguments.
: Embed spmenu inside window id
`-H, --hist-file hist file`
: Specify a path to save the history to
: Specify a file to save the history to
`-lf, --list-file list file`
: Specify a file to load entries from
`-ig, --image-gaps gaps`
: Set image gaps to gaps

View file

@ -160,6 +160,7 @@ spmenu = {
preselected = 0; // Preselect an item, 0 is the first item (number)
accuratewidth = 0; // Enable accurate width, could be noticeably slower in some cases (0/1)
delimiters = " "; // Word delimiter, used to delete words (text)
listfile = "NULL"; // File to read entries from. If set to NULL standard input is read. This is read every time a key is pressed. (text)
} );
/* Line options */

View file

@ -276,6 +276,8 @@ void readargs(int argc, char *argv[]) {
input = argv[++i];
else if (!strcmp(argv[i], "-fn") || (!strcmp(argv[i], "--font"))) // font or font set
fonts[0] = argv[++i];
else if (!strcmp(argv[i], "-lf") || (!strcmp(argv[i], "--lf"))) // list file
listfile = argv[++i];
else if (!strcmp(argv[i], "-nmt") || (!strcmp(argv[i], "--normal-mode-text"))) // normal mode text
strcpy(normtext, argv[++i]);
else if (!strcmp(argv[i], "-imt") || (!strcmp(argv[i], "--insert-mode-text"))) // insert mode text
@ -531,7 +533,8 @@ void usage(void) {
"spmenu -ngbc, --no-global-colors Don't recognize global colors (such as *.color1) on runtime\n"
"spmenu -m, --monitor <monitor> Specify a monitor to run spmenu on\n"
"spmenu -w, --embed <window id> Embed spmenu inside <window id>\n"
"spmenu -H, --hist-file <hist file> Specify a path to save the history to\n"
"spmenu -H, --hist-file <hist file> Specify a file to save the history to\n"
"spmenu -lf, --list-file <list file> Specify a file to load entries from\n"
"spmenu -ig, --image-gaps <gaps> Set image gaps to <gaps>\n"
"spmenu -txp, --text-padding <padding> Set text padding to <padding>\n"
"spmenu -lp, --vertical-padding <padding> Set the vertical padding\n"

View file

@ -443,6 +443,9 @@ void conf_init(void) {
config_setting_lookup_int(conf, "accuratewidth", &accuratewidth); // spmenu.match.accuratewidth
config_setting_lookup_string(conf, "delimiters", &dest); // spmenu.match.delimiters
worddelimiters = strdup(dest);
if (config_setting_lookup_string(conf, "listfile", &dest)) // spmenu.match.listfile
if (dest && strcmp(strdup(dest), "NULL"))
listfile = strdup(dest);
}
}

View file

@ -7,6 +7,7 @@ void eventloop(void) {
while (!XNextEvent(dpy, &ev)) {
if (XFilterEvent(&ev, None))
continue;
switch(ev.type) {
case DestroyNotify:
if (ev.xdestroywindow.window != win)
@ -31,6 +32,15 @@ void eventloop(void) {
grabfocus();
break;
case KeyPress: // read key array and call functions
if (listfile) {
readfile();
if (listchanged) {
match();
drawmenu();
}
}
if (incremental) {
puts(text);
fflush(stdout);

View file

@ -7,7 +7,7 @@ void readstdin(void) {
char *limg = NULL;
#endif
if (passwd){
if (passwd) {
inputw = lines = 0;
return;
}
@ -112,3 +112,75 @@ void readstdin(void) {
inputw = items ? TEXTWM(items[imax].text) : 0;
lines = MIN(lines, i);
}
void readfile(void) {
if (passwd){
inputw = lines = 0;
return;
}
size_t len;
static size_t cap = 0;
char *l;
FILE *ef = fopen(listfile, "r");
if (!ef) return;
items = NULL;
//list = NULL;
listsize = 0;
for (;;) {
l = NULL;
len = 0;
if (-1 == getline(&l, &len, ef)) {
if (ferror(ef)) die("spmenu: failed to read file\n");
free(l);
break;
}
if (cap == listsize) {
cap += 64 * sizeof(char*);
list = realloc(list, cap);
if (!list) die("spmenu: failed to realloc memory");
}
strtok(l, "\n");
list[listsize] = l;
listsize++;
}
if (fclose(ef)) {
die("spmenu: failed to close file %s\n", listfile);
}
if (!list_items) {
list_items = items;
items = calloc(listsize + 1, sizeof(struct item));
if (!items) die("spmenu: cannot alloc memory\n");
int i = 0;
for (i = 0; i < listsize; i++) {
items[i].text = list[i];
}
if (i == olistcount) {
listcount = i;
listchanged = 0;
} else {
olistcount = listcount;
listcount = i;
listchanged = 1;
}
} else {
free(items);
items = list_items;
list_items = NULL;
}
//match();
//drawmenu();
}

View file

@ -1 +1,2 @@
static void readstdin(void);
static void readfile(void);

View file

@ -79,6 +79,7 @@ static int casesensitive = 0; /* Case-sensitive by default? (0/1)
static int preselected = 0; /* Which line should spmenu preselect? */
static int accuratewidth = 0; /* Enable accurate width. May have a performance hit if you are matching a lot of items at once */
static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */
static char *listfile = NULL; /* File to read entries from instead of stdin. NULL means read from stdin instead. */
/* Line options */
static int lineheight = 1; /* Line height (0: Calculate automatically) */

View file

@ -286,7 +286,10 @@ Specify a monitor to run spmenu on
Embed spmenu inside window id
.TP
\f[V]-H, --hist-file hist file\f[R]
Specify a path to save the history to
Specify a file to save the history to
.TP
\f[V]-lf, --list-file list file\f[R]
Specify a file to load entries from
.TP
\f[V]-ig, --image-gaps gaps\f[R]
Set image gaps to gaps

View file

@ -149,7 +149,7 @@ static int vp; // vertical padding for bar
static int sp; // side padding for bar
static int cursorstate = 1; // cursor state
static size_t cursor;
static struct item *items = NULL, *backup_items;
static struct item *items = NULL, *backup_items, *list_items;
static struct item *matches, *matchend;
static struct item *prev, *curr, *next, *sel;
static int screen;
@ -229,6 +229,12 @@ static void setupdisplay(void);
static int max_textw(void);
static size_t nextrune(int inc);
static char **list;
static size_t listsize;
static int listcount;
static int olistcount;
static int listchanged = 0;
// user configuration
#include "options.h"
#include "keybinds.h"
@ -256,8 +262,6 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/img.c"
#include "libs/rtl.h"
#include "libs/rtl.c"
#include "libs/event.h"
#include "libs/event.c"
#include "libs/key.c"
#include "libs/mouse.c"
#include "libs/sort.c"
@ -273,6 +277,8 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/history.c"
#include "libs/arg.c"
#include "libs/stream.c"
#include "libs/event.h"
#include "libs/event.c"
void appenditem(struct item *item, struct item **list, struct item **last) {
if (*last)
@ -736,9 +742,17 @@ int main(int argc, char *argv[]) {
// fast (-f) means we grab keyboard before reading standard input
if (fast && !isatty(0)) {
grabkeyboard();
readstdin();
if (!listfile)
readstdin();
else
readfile();
} else {
readstdin();
if (listfile)
readfile();
else
readstdin();
grabkeyboard();
}

View file

@ -505,7 +505,11 @@ Embed spmenu inside window id
</dd>
<dt><code>-H, --hist-file hist file</code></dt>
<dd>
Specify a path to save the history to
Specify a file to save the history to
</dd>
<dt><code>-lf, --list-file list file</code></dt>
<dd>
Specify a file to load entries from
</dd>
<dt><code>-ig, --image-gaps gaps</code></dt>
<dd>