commit 57609d2ef265bc6b2ae2d5b04605d57150971ebe
parent b70423c2ece6b268a47c32950faeda344c7004a7
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 24 Jan 2022 17:50:44 +0100
Added tag search mode to select quickly
Diffstat:
6 files changed, 131 insertions(+), 34 deletions(-)
diff --git a/src/history.c b/src/history.c
@@ -9,7 +9,7 @@ void
history_init(struct history *history)
{
history->list = LIST_HEAD;
- history->input = inputln_init();
+ history->input = inputln_alloc();
history->sel = history->input;
}
@@ -27,7 +27,7 @@ history_submit(struct history *history)
history_add(history, history->sel);
/* create new input buf and add to hist */
- history->input = inputln_init();
+ history->input = inputln_alloc();
history->sel = history->input;
history_add(history, history->sel);
}
@@ -109,21 +109,25 @@ history_add(struct history *history, struct inputln *line)
list_push_front(&history->list, LINK(line));
}
+void
+inputln_init(struct inputln *ln)
+{
+ ln->buf = NULL;
+ ln->len = 0;
+ ln->cap = 0;
+ ln->cur = 0;
+ ln->link = LINK_EMPTY;
+}
+
struct inputln *
-inputln_init(void)
+inputln_alloc(void)
{
struct inputln *ln;
ln = malloc(sizeof(struct inputln));
ASSERT(ln != NULL);
- ln->cap = 128;
- ln->buf = malloc(ln->cap * sizeof(wchar_t));
- ASSERT(ln->buf != NULL);
- ln->len = 0;
- ln->buf[ln->len] = '\0';
- ln->cur = 0;
- ln->link.next = NULL;
- ln->link.prev = NULL;
+ inputln_init(ln);
+ inputln_resize(ln, 128);
return ln;
}
@@ -210,3 +214,15 @@ inputln_replace(struct inputln *line, const wchar_t *str)
line->cap = line->len + 1;
line->cur = line->len;
}
+
+void
+inputln_resize(struct inputln *ln, size_t size)
+{
+ ASSERT(size != 0);
+
+ ln->cap = size;
+ ln->buf = realloc(ln->buf, ln->cap * sizeof(wchar_t));
+ ASSERT(ln->buf != NULL);
+ ln->len = MIN(ln->len, ln->cap-1);
+ ln->buf[ln->len] = '\0';
+}
diff --git a/src/history.h b/src/history.h
@@ -29,7 +29,9 @@ void history_next(struct history *history);
void history_add(struct history *history, struct inputln *line);
-struct inputln *inputln_init(void);
+struct inputln *inputln_alloc(void);
+void inputln_init(struct inputln *ln);
+void inputln_resize(struct inputln *ln, size_t size);
void inputln_free(struct inputln *ln);
void inputln_left(struct inputln *line);
diff --git a/src/main.c b/src/main.c
@@ -52,7 +52,9 @@ enum {
enum {
IMODE_EXECUTE,
- IMODE_SEARCH
+ IMODE_TRACK_SEARCH,
+ IMODE_TAG_SEARCH,
+ IMODE_COUNT
};
typedef wchar_t *(*completion_gen)(const wchar_t *text, int fwd, int state);
@@ -92,11 +94,13 @@ static int track_show_playlist;
/* bottom 'cmd' pane for search / exec */
static struct pane *cmd_pane;
-static struct history search_history, command_history;
+static struct history command_history;
+static struct history track_search_history;
+static struct history tag_search_history;
static struct history *history;
static int cmd_show, cmd_mode;
-static struct inputln completion_query = { 0 };
-static int completion_reset = 1;
+static struct inputln completion_query;
+static int completion_reset;
static completion_gen completion;
/* left pane for tags */
@@ -138,6 +142,8 @@ static void tag_pane_vis(struct pane *pane, int sel);
static int track_pane_input(wint_t c);
static void track_pane_vis(struct pane *pane, int sel);
+static int play_track(const wchar_t *name);
+static int select_tag(const wchar_t *name);
static int cmd_pane_input(wint_t c);
static void cmd_pane_vis(struct pane *pane, int sel);
@@ -148,6 +154,12 @@ static void main_vis(void);
static int usercmd_save(const wchar_t *args);
+const char imode_prefix[IMODE_COUNT] = {
+ [IMODE_EXECUTE] = ':',
+ [IMODE_TRACK_SEARCH] = '/',
+ [IMODE_TAG_SEARCH] = '?',
+};
+
const struct cmd cmds[] = {
{ L"save", usercmd_save },
};
@@ -159,7 +171,11 @@ init(void)
srand(time(NULL));
quit = 0;
- history_init(&search_history);
+ inputln_init(&completion_query);
+ completion_reset = 1;
+
+ history_init(&track_search_history);
+ history_init(&tag_search_history);
history_init(&command_history);
history = &command_history;
@@ -197,7 +213,8 @@ cleanup(int exitcode, void* arg)
log_end();
- history_free(&search_history);
+ history_free(&track_search_history);
+ history_free(&tag_search_history);
history_free(&command_history);
}
@@ -268,7 +285,7 @@ tui_resize(void)
/* adjust tag pane width to name lengths */
leftw = 0;
for (iter = tags.next; iter; iter = iter->next)
- leftw = MAX(leftw, strlen(UPCAST(iter, struct tag)->name));
+ leftw = MAX(leftw, wcslen(UPCAST(iter, struct tag)->name));
leftw = MAX(leftw + 1, 0.2f * scrw);
pane_resize(&pane_left, 0, 0, leftw, scrh - 3);
@@ -487,6 +504,32 @@ track_name_gen(const wchar_t *text, int fwd, int reset)
return NULL;
}
+wchar_t *
+tag_name_gen(const wchar_t *text, int fwd, int reset)
+{
+ static struct link *cur;
+ struct link *iter;
+ struct tag *tag;
+
+ if (reset) {
+ cur = tags.next;
+ iter = cur;
+ } else {
+ iter = fwd ? cur->next : cur->prev;
+ }
+
+ while (iter && iter != &tags) {
+ tag = UPCAST(iter, struct tag);
+ if (wcsstr(tag->name, text)) {
+ cur = iter;
+ return wcsdup(tag->name);
+ }
+ iter = fwd ? iter->next : iter->prev;
+ }
+
+ return NULL;
+}
+
void
toggle_current_tag(void)
{
@@ -580,7 +623,7 @@ tag_pane_vis(struct pane *pane, int sel)
style_on(pane->win, STYLE_ITEM_SEL);
wmove(pane->win, 1 + index - tag_nav.wmin, 0);
- wprintw(pane->win, "%*.*s", pane->w, pane->w, tag->name);
+ wprintw(pane->win, "%-*.*ls", pane->w, pane->w, tag->name);
if (sel && index == tag_nav.sel && tsel)
style_off(pane->win, STYLE_ITEM_HOVER_SEL);
@@ -706,6 +749,25 @@ play_track(const wchar_t *query)
}
int
+select_tag(const wchar_t *query)
+{
+ struct tag *tag;
+ struct link *iter;
+ int index;
+
+ index = 0;
+ for (iter = tags.next; iter; iter = iter->next, index++) {
+ tag = UPCAST(iter, struct tag);
+ if (wcsstr(tag->name, query)) {
+ listnav_update_sel(&tag_nav, index);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
cmd_pane_input(wint_t c)
{
wchar_t *res;
@@ -713,9 +775,12 @@ cmd_pane_input(wint_t c)
if (cmd_mode == IMODE_EXECUTE) {
history = &command_history;
completion = command_name_gen;
- } else if (cmd_mode == IMODE_SEARCH) {
- history = &search_history;
+ } else if (cmd_mode == IMODE_TRACK_SEARCH) {
+ history = &track_search_history;
completion = track_name_gen;
+ } else if (cmd_mode == IMODE_TAG_SEARCH) {
+ history = &tag_search_history;
+ completion = tag_name_gen;
}
switch (c) {
@@ -748,8 +813,10 @@ cmd_pane_input(wint_t c)
if (cmd_mode == IMODE_EXECUTE) {
run_cmd(history->sel->buf);
- } else if (cmd_mode == IMODE_SEARCH) {
+ } else if (cmd_mode == IMODE_TRACK_SEARCH) {
play_track(history->sel->buf);
+ } else if (cmd_mode == IMODE_TAG_SEARCH) {
+ select_tag(history->sel->buf);
}
history_submit(history);
@@ -885,7 +952,7 @@ cmd_pane_vis(struct pane *pane, int sel)
iter ? index : -1);
} else {
line += swprintf(line, end - line, L"%c",
- cmd_mode == IMODE_SEARCH ? '/' : ':');
+ imode_prefix[cmd_mode]);
}
offset = wcslen(linebuf);
@@ -959,9 +1026,6 @@ main_input(wint_t c)
case L'c':
player_toggle_pause();
break;
- case L'P':
- track_show_playlist ^= 1;
- break;
case L'n':
case L'>':
player_next();
@@ -970,10 +1034,13 @@ main_input(wint_t c)
case L'<':
player_prev();
break;
- case L'w':
+ case L'P':
+ track_show_playlist ^= 1;
+ break;
+ case L'A':
player->autoplay ^= 1;
break;
- case L'g':
+ case L'S':
player->shuffle ^= 1;
break;
case L'b':
@@ -992,7 +1059,12 @@ main_input(wint_t c)
completion_reset = 1;
break;
case L'/':
- cmd_mode = IMODE_SEARCH;
+ cmd_mode = IMODE_TRACK_SEARCH;
+ pane_sel = &pane_bot;
+ completion_reset = 1;
+ break;
+ case L'?':
+ cmd_mode = IMODE_TAG_SEARCH;
pane_sel = &pane_bot;
completion_reset = 1;
break;
diff --git a/src/tag.c b/src/tag.c
@@ -8,6 +8,7 @@ struct tag *
tag_init(const char *path, const char *fname)
{
struct tag *tag;
+ int len;
tag = malloc(sizeof(struct tag));
ASSERT(tag != NULL);
@@ -18,8 +19,11 @@ tag_init(const char *path, const char *fname)
tag->fpath = aprintf("%s/%s", path, fname);
ASSERT(tag->fpath != NULL);
- tag->name = sanitized(tag->fname);
+ len = mbstowcs(NULL, tag->fname, 0);
+ ASSERT(len > 0);
+ tag->name = calloc(len + 1, sizeof(wchar_t));
ASSERT(tag->name != NULL);
+ mbstowcs(tag->name, tag->fname, len + 1);
tag->link = LINK_EMPTY;
diff --git a/src/tag.h b/src/tag.h
@@ -4,7 +4,7 @@
#include "util.h"
struct tag {
- char *name;
+ wchar_t *name;
char *fname, *fpath;
struct link tracks;
diff --git a/src/track.c b/src/track.c
@@ -11,6 +11,7 @@ track_init(const char *dir, const char *fname)
{
struct track *track;
struct stat info;
+ int len;
track = malloc(sizeof(struct track));
ASSERT(track != NULL);
@@ -21,9 +22,11 @@ track_init(const char *dir, const char *fname)
track->fpath = aprintf("%s/%s", dir, fname);
ASSERT(track->fpath != NULL);
- track->name = calloc(strlen(track->fname) + 1, sizeof(wchar_t));
+ len = mbstowcs(NULL, track->fname, 0);
+ ASSERT(len >= 0);
+ track->name = calloc(len + 1, sizeof(wchar_t));
ASSERT(track->name != NULL);
- mbstowcs(track->name, track->fname, strlen(track->fname) + 1);
+ mbstowcs(track->name, track->fname, len + 1);
track->fid = -1;
if (!stat(track->fpath, &info))