mirror of https://github.com/ericonr/ef.git
Switch to using a pad for the list, add working navigation.
This commit is contained in:
parent
8f70f6e213
commit
ab99ea260b
67
browser.c
67
browser.c
|
@ -35,6 +35,7 @@ int main()
|
||||||
|
|
||||||
struct str_array entries = { 0 };
|
struct str_array entries = { 0 };
|
||||||
read_entries_from_stream(&entries, delim, stdin);
|
read_entries_from_stream(&entries, delim, stdin);
|
||||||
|
filter_entries(&entries, NULL);
|
||||||
|
|
||||||
int tmp_fd;
|
int tmp_fd;
|
||||||
/* use stderr for input instead of stdin, since we get the entries from stdin */
|
/* use stderr for input instead of stdin, since we get the entries from stdin */
|
||||||
|
@ -68,21 +69,22 @@ int main()
|
||||||
/* noop function - should use the windows from below */
|
/* noop function - should use the windows from below */
|
||||||
attrset(COLOR_PAIR(1));
|
attrset(COLOR_PAIR(1));
|
||||||
|
|
||||||
WINDOW *list = newwin(LINES - 1, 0, 0, 0);
|
/* store number of rows that can be displayed in list */
|
||||||
|
const int nrows = LINES - 1;
|
||||||
|
|
||||||
|
WINDOW *list = newpad(entries.n, COLS);
|
||||||
WINDOW *prompt = newwin(1, 0, LINES - 1, 0);
|
WINDOW *prompt = newwin(1, 0, LINES - 1, 0);
|
||||||
if (!list || !prompt) {
|
if (!list || !prompt) {
|
||||||
perror("newwin");
|
perror("newwin");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
keypad(prompt, TRUE);
|
keypad(prompt, TRUE);
|
||||||
keypad(list, TRUE);
|
|
||||||
|
|
||||||
/* inital dump of list
|
/* inital dump of list */
|
||||||
* TODO: needs scroll support */
|
|
||||||
for (size_t i = 0; i < entries.n; i++) {
|
for (size_t i = 0; i < entries.n; i++) {
|
||||||
mvwaddstr(list, i, 0, get_entry(&entries, i));
|
mvwaddstr(list, i, 0, get_entry(&entries, i));
|
||||||
}
|
}
|
||||||
wrefresh(list);
|
prefresh(list, 0, 0, 0, 0, nrows - 1, COLS);
|
||||||
|
|
||||||
mvwaddstr(prompt, 0, 0, "> ");
|
mvwaddstr(prompt, 0, 0, "> ");
|
||||||
wrefresh(prompt);
|
wrefresh(prompt);
|
||||||
|
@ -91,29 +93,64 @@ int main()
|
||||||
* TODO: use dynamic string and str_array so we can search on a group of tokens */
|
* TODO: use dynamic string and str_array so we can search on a group of tokens */
|
||||||
char name[1024] = { 0 };
|
char name[1024] = { 0 };
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while (n < sizeof name) {
|
/* listx isn't changed anywhere */
|
||||||
|
int listx = 0, listy = 0;
|
||||||
|
while (n < sizeof name - 1) {
|
||||||
|
bool name_changed = false;
|
||||||
int c = wgetch(prompt);
|
int c = wgetch(prompt);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
/* Ctrl+[ or ESC */
|
||||||
|
case 27:
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
|
||||||
case KEY_ENTER:
|
case KEY_ENTER:
|
||||||
case '\r':
|
case '\r':
|
||||||
/* since we are using nonl above, only capture '\r' itself
|
/* since we are using nonl above, only capture '\r' itself
|
||||||
* TODO: actually store the entry name */
|
* TODO: actually store the entry name */
|
||||||
final_name = name;
|
final_name = name;
|
||||||
exit(0);
|
exit(0);
|
||||||
case KEY_BACKSPACE:
|
|
||||||
case 127:
|
case KEY_DOWN:
|
||||||
name[n] = 0;
|
/* Ctrl-N */
|
||||||
if (n) n--;
|
case 14:
|
||||||
|
if ((size_t)listy < entries.n && (size_t)nrows < entries.ms ) listy++;
|
||||||
break;
|
break;
|
||||||
case KEY_DL:
|
|
||||||
name[0] = 0;
|
case KEY_UP:
|
||||||
|
/* Ctrl-P */
|
||||||
|
case 16:
|
||||||
|
if (listy) listy--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Ctrl+W */
|
||||||
|
case 23:
|
||||||
n = 0;
|
n = 0;
|
||||||
|
name[n] = 0;
|
||||||
|
name_changed = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
/* DEL */
|
||||||
|
case 127:
|
||||||
|
if (n) n--;
|
||||||
|
name[n] = 0;
|
||||||
|
name_changed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
name[n] = c;
|
name[n] = c;
|
||||||
n++;
|
n++;
|
||||||
|
/* clear chars from previous entries */
|
||||||
|
name[n] = 0;
|
||||||
|
name_changed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!name_changed) {
|
||||||
|
prefresh(list, listy, listx, 0, 0, nrows-1, COLS);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
werase(prompt);
|
werase(prompt);
|
||||||
mvwaddstr(prompt, 0, 0, "> ");
|
mvwaddstr(prompt, 0, 0, "> ");
|
||||||
waddstr(prompt, name);
|
waddstr(prompt, name);
|
||||||
|
@ -123,10 +160,12 @@ int main()
|
||||||
werase(list);
|
werase(list);
|
||||||
int line = 0;
|
int line = 0;
|
||||||
for (size_t i = 0; i < entries.n; i++) {
|
for (size_t i = 0; i < entries.n; i++) {
|
||||||
const char *e = get_entry_match(&entries, i);
|
const char *e = get_entry_if_match(&entries, i);
|
||||||
if (e) mvwaddstr(list, line++, 0, e);
|
if (e) mvwaddstr(list, line++, 0, e);
|
||||||
}
|
}
|
||||||
wrefresh(list);
|
/* reset vertical position when name changes */
|
||||||
|
listy = 0;
|
||||||
|
prefresh(list, listy, listx, 0, 0, nrows-1, COLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -18,14 +18,19 @@ void add_entry(struct str_array *a, const char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
a->v[a->n] = s;
|
a->v[a->n] = s;
|
||||||
a->m[a->n] = false;
|
|
||||||
a->n++;
|
a->n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter_entries(struct str_array *a, const char *s)
|
void filter_entries(struct str_array *a, const char *s)
|
||||||
{
|
{
|
||||||
|
if (!s) {
|
||||||
|
a->ms = a->n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a->ms = 0;
|
||||||
for (size_t i = 0; i < a->n; i++) {
|
for (size_t i = 0; i < a->n; i++) {
|
||||||
a->m[i] = strstr(a->v[i], s);
|
if ((a->m[i] = strstr(a->v[i], s))) a->ms++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,13 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct str_array {
|
struct str_array {
|
||||||
|
/* strings in the array */
|
||||||
const char **v;
|
const char **v;
|
||||||
|
/* flag to say if they fit a certain condition or not */
|
||||||
bool *m;
|
bool *m;
|
||||||
|
/* total number of true in m */
|
||||||
|
size_t ms;
|
||||||
|
/* number of elements, maximum number of elements */
|
||||||
size_t n, c;
|
size_t n, c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,9 +20,14 @@ static inline const char *get_entry(const struct str_array *a, size_t i)
|
||||||
return a->v[i];
|
return a->v[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *get_entry_match(const struct str_array *a, size_t i)
|
static inline bool get_entry_match(const struct str_array *a, size_t i)
|
||||||
{
|
{
|
||||||
return a->m[i] ? a->v[i] : NULL;
|
return a->m[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const 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 add_entry(struct str_array *, const char *);
|
||||||
|
|
Loading…
Reference in New Issue