wmenu-run: Populate items from PATH - wmenu - 🔧 fork of wmenu
(HTM) git clone git@git.drkhsh.at/wmenu.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 8f19d6a8d2f34aeb4060d4374eb204b270ffbaa8
(DIR) parent 92d3b294aeff5b36916782847bae4389c10e8f17
(HTM) Author: adnano <me@adnano.co>
Date: Fri, 3 May 2024 19:10:28 -0400
wmenu-run: Populate items from PATH
Diffstat:
M menu.c | 87 ++++++++++++++++++-------------
M menu.h | 4 ++--
M wmenu-run.c | 19 +++++++++++++------
M wmenu.c | 2 +-
4 files changed, 68 insertions(+), 44 deletions(-)
---
(DIR) diff --git a/menu.c b/menu.c
@@ -35,6 +35,36 @@ struct menu *menu_create() {
return menu;
}
+static void free_pages(struct menu *menu) {
+ struct page *next = menu->pages;
+ while (next) {
+ struct page *page = next;
+ next = page->next;
+ free(page);
+ }
+}
+
+static void free_item(struct item *item) {
+ free(item->text);
+ free(item);
+}
+
+static void free_items(struct menu *menu) {
+ struct item *next = menu->items;
+ while (next) {
+ struct item *item = next;
+ next = item->next;
+ free_item(item);
+ }
+}
+
+// Destroys the menu, freeing memory associated with it.
+void menu_destroy(struct menu *menu) {
+ free_pages(menu);
+ free_items(menu);
+ free(menu);
+}
+
static bool parse_color(const char *color, uint32_t *result) {
if (color[0] == '#') {
++color;
@@ -136,19 +166,34 @@ void menu_getopts(struct menu *menu, int argc, char *argv[]) {
}
// Add an item to the menu.
-void menu_add_item(struct menu *menu, char *text) {
- struct item *item = calloc(1, sizeof *item);
- if (!item) {
+void menu_add_item(struct menu *menu, char *text, bool sort) {
+ struct item *new = calloc(1, sizeof(struct item));
+ if (!new) {
return;
}
- item->text = text;
+ new->text = text;
+
+ if (sort) {
+ for (struct item **item = &menu->items; *item; item = &(*item)->next) {
+ int result = strcmp(new->text, (*item)->text);
+ if (result == 0) {
+ free_item(new);
+ return;
+ }
+ if (result < 0) {
+ new->next = *item;
+ *item = new;
+ return;
+ }
+ }
+ }
if (menu->lastitem) {
- menu->lastitem->next = item;
+ menu->lastitem->next = new;
} else {
- menu->items = item;
+ menu->items = new;
}
- menu->lastitem = item;
+ menu->lastitem = new;
}
static void append_page(struct page *page, struct page **first, struct page **last) {
@@ -637,31 +682,3 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
}
}
}
-
-// Frees menu pages.
-static void free_pages(struct menu *menu) {
- struct page *next = menu->pages;
- while (next) {
- struct page *page = next;
- next = page->next;
- free(page);
- }
-}
-
-// Frees menu items.
-static void free_items(struct menu *menu) {
- struct item *next = menu->items;
- while (next) {
- struct item *item = next;
- next = item->next;
- free(item->text);
- free(item);
- }
-}
-
-// Destroys the menu, freeing memory associated with it.
-void menu_destroy(struct menu *menu) {
- free_pages(menu);
- free_items(menu);
- free(menu);
-}
(DIR) diff --git a/menu.h b/menu.h
@@ -74,12 +74,12 @@ struct menu {
};
struct menu *menu_create();
+void menu_destroy(struct menu *menu);
void menu_getopts(struct menu *menu, int argc, char *argv[]);
-void menu_add_item(struct menu *menu, char *text);
+void menu_add_item(struct menu *menu, char *text, bool sort);
void menu_render_items(struct menu *menu);
void menu_paste(struct menu *menu, const char *text, ssize_t len);
void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
xkb_keysym_t sym);
-void menu_destroy(struct menu *menu);
#endif
(DIR) diff --git a/wmenu-run.c b/wmenu-run.c
@@ -1,4 +1,5 @@
#define _POSIX_C_SOURCE 200809L
+#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -9,13 +10,19 @@
#include "xdg-activation-v1-client-protocol.h"
static void read_items(struct menu *menu) {
- char buf[sizeof menu->input];
- while (fgets(buf, sizeof buf, stdin)) {
- char *p = strchr(buf, '\n');
- if (p) {
- *p = '\0';
+ char *path = getenv("PATH");
+ for (char *p = strtok(path, ":"); p != NULL; p = strtok(NULL, ":")) {
+ DIR *dir = opendir(p);
+ if (dir == NULL) {
+ continue;
}
- menu_add_item(menu, strdup(buf));
+ for (struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
+ if (ent->d_name[0] == '.') {
+ continue;
+ }
+ menu_add_item(menu, strdup(ent->d_name), true);
+ }
+ closedir(dir);
}
}
(DIR) diff --git a/wmenu.c b/wmenu.c
@@ -12,7 +12,7 @@ static void read_items(struct menu *menu) {
if (p) {
*p = '\0';
}
- menu_add_item(menu, strdup(buf));
+ menu_add_item(menu, strdup(buf), false);
}
}