Implement token search.

- only shows results that match all tokens
- tokens are generated by adding a space to the query
This commit is contained in:
Érico Rolim 2021-01-07 18:17:20 -03:00
parent ab99ea260b
commit ef21f16b54
4 changed files with 70 additions and 19 deletions

View File

@ -1,7 +1,7 @@
SRC = browser.c string-array.c util.c
OBJ = $(SRC:%.c=%.o)
EXE = browser
CFLAGS = -Wall -Wextra
CFLAGS = -Wall -Wextra -g
LDLIBS = -lcurses
all: $(EXE)

View File

@ -89,13 +89,25 @@ int main()
mvwaddstr(prompt, 0, 0, "> ");
wrefresh(prompt);
/* limited name size
* TODO: use dynamic string and str_array so we can search on a group of tokens */
char name[1024] = { 0 };
size_t n = 0;
struct str_array toks = { 0 };
size_t n;
char *name = NULL;
/* listx isn't changed anywhere */
int listx = 0, listy = 0;
while (n < sizeof name - 1) {
for (;;) {
if (!name) {
/* TODO: find way to track allocation size and update it when needed */
name = malloc(1024);
if (!name) {
perror("malloc");
exit(1);
}
n = 0;
name[n] = 0;
add_entry(&toks, name);
}
bool name_changed = false;
int c = wgetch(prompt);
switch (c) {
@ -133,11 +145,26 @@ int main()
case KEY_BACKSPACE:
/* DEL */
case 127:
/* go back to previous word */
if (toks.n > 1 && n == 0) {
free(pop_entry(&toks));
name = get_entry(&toks, toks.n - 1);
n = strlen(name);
name_changed = true;
break;
}
if (n) n--;
name[n] = 0;
name_changed = true;
break;
case ' ':
if (*name) {
name = NULL;
}
name_changed = true;
break;
default:
name[n] = c;
n++;
@ -152,10 +179,19 @@ int main()
}
werase(prompt);
mvwaddstr(prompt, 0, 0, "> ");
waddstr(prompt, name);
mvwaddstr(prompt, 0, 0, ">");
for (size_t i = 0; i < toks.n; i++) {
const char *e = get_entry(&toks, i);
waddch(prompt, ' ');
waddstr(prompt, e);
}
/* show space if string is empty */
if (!name) waddch(prompt, ' ');
wrefresh(prompt);
filter_entries(&entries, name);
if (!name) continue;
filter_entries(&entries, &toks);
werase(list);
int line = 0;

View File

@ -4,7 +4,7 @@
#include "string-array.h"
void add_entry(struct str_array *a, const char *s)
void add_entry(struct str_array *a, char *s)
{
if (a->n == a->c) {
if (a->c == 0) a->c = 32;
@ -21,16 +21,30 @@ void add_entry(struct str_array *a, const char *s)
a->n++;
}
void filter_entries(struct str_array *a, const char *s)
char *pop_entry(struct str_array *a)
{
if (!s) {
a->n--;
return get_entry(a, a->n);
}
void filter_entries(struct str_array *a, const struct str_array *m)
{
if (!m) {
a->ms = a->n;
return;
}
a->ms = 0;
for (size_t i = 0; i < a->n; i++) {
if ((a->m[i] = strstr(a->v[i], s))) a->ms++;
for (size_t i = 0; i < m->n; i++) {
for (size_t j = 0; j < a->n; j++) {
/* first token or was previously true */
if (i == 0 || a->m[j]) {
/* only count matches in the last round */
if ((a->m[j] = strstr(a->v[j], m->v[i])) && (i == m->n - 1)) {
a->ms++;
}
}
}
}
}

View File

@ -5,7 +5,7 @@
struct str_array {
/* strings in the array */
const char **v;
char **v;
/* flag to say if they fit a certain condition or not */
bool *m;
/* total number of true in m */
@ -15,7 +15,7 @@ struct str_array {
};
static inline const char *get_entry(const struct str_array *a, size_t i)
static inline char *get_entry(const struct str_array *a, size_t i)
{
return a->v[i];
}
@ -25,13 +25,14 @@ static inline bool get_entry_match(const struct str_array *a, size_t i)
return a->m[i];
}
static inline const char *get_entry_if_match(const struct str_array *a, size_t i)
static inline char *get_entry_if_match(const struct str_array *a, size_t i)
{
return get_entry_match(a, i) ? a->v[i] : NULL;
}
void add_entry(struct str_array *, const char *);
void filter_entries(struct str_array *, const char *);
void add_entry(struct str_array *, char *);
char *pop_entry(struct str_array *);
void filter_entries(struct str_array *, const struct str_array *);
void print_entries(const struct str_array *);
#endif