mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-22 05:33:45 -04:00
search: wip: re-direct input while searching, and build a search buffer
This adds a new state, 'is_searching'. While active, input is re-directed, and stored in a search buffer. In the future, we'll use this buffer and search for its content in the scrollback buffer, and move the view and create a selection on matches. When rendering in 'is_searching', everything is dimmed. In the future, we'll render the current search buffer on-top of the dimmed "regular" terminal output.
This commit is contained in:
parent
2d7ca416f0
commit
61cabdac13
6 changed files with 160 additions and 10 deletions
107
search.c
Normal file
107
search.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#include "search.h"
|
||||
|
||||
#include <wchar.h>
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
|
||||
#define LOG_MODULE "search"
|
||||
#define LOG_ENABLE_DBG 1
|
||||
#include "log.h"
|
||||
#include "render.h"
|
||||
|
||||
void
|
||||
search_begin(struct terminal *term)
|
||||
{
|
||||
LOG_DBG("search: begin");
|
||||
|
||||
free(term->search.buf);
|
||||
term->search.buf = NULL;
|
||||
term->search.len = 0;
|
||||
term->search.sz = 0;
|
||||
term->is_searching = true;
|
||||
|
||||
render_refresh(term);
|
||||
}
|
||||
|
||||
void
|
||||
search_cancel(struct terminal *term)
|
||||
{
|
||||
LOG_DBG("search: cancel");
|
||||
|
||||
free(term->search.buf);
|
||||
term->search.buf = NULL;
|
||||
term->search.len = 0;
|
||||
term->search.sz = 0;
|
||||
term->is_searching = false;
|
||||
|
||||
render_refresh(term);
|
||||
}
|
||||
|
||||
void
|
||||
search_input(struct terminal *term, uint32_t key, xkb_keysym_t sym, xkb_mod_mask_t mods)
|
||||
{
|
||||
LOG_DBG("search: input: sym=%d/0x%x, mods=0x%08x", sym, sym, mods);
|
||||
|
||||
const xkb_mod_mask_t ctrl = 1 << term->kbd.mod_ctrl;
|
||||
//const xkb_mod_mask_t alt = 1 << term->kbd.mod_alt;
|
||||
//const xkb_mod_mask_t shift = 1 << term->kbd.mod_shift;
|
||||
//const xkb_mod_mask_t meta = 1 << term->kbd.mod_meta;
|
||||
|
||||
enum xkb_compose_status compose_status = xkb_compose_state_get_status(
|
||||
term->kbd.xkb_compose_state);
|
||||
|
||||
if ((mods == 0 && sym == XKB_KEY_Escape) || (mods == ctrl && sym == XKB_KEY_g))
|
||||
search_cancel(term);
|
||||
|
||||
else if (mods == 0 && sym == XKB_KEY_BackSpace) {
|
||||
if (term->search.len > 0)
|
||||
term->search.buf[--term->search.len] = L'\0';
|
||||
}
|
||||
|
||||
else {
|
||||
uint8_t buf[64] = {0};
|
||||
int count = 0;
|
||||
|
||||
if (compose_status == XKB_COMPOSE_COMPOSED) {
|
||||
count = xkb_compose_state_get_utf8(
|
||||
term->kbd.xkb_compose_state, (char *)buf, sizeof(buf));
|
||||
xkb_compose_state_reset(term->kbd.xkb_compose_state);
|
||||
} else {
|
||||
count = xkb_state_key_get_utf8(
|
||||
term->kbd.xkb_state, key, (char *)buf, sizeof(buf));
|
||||
}
|
||||
|
||||
const char *src = (const char *)buf;
|
||||
mbstate_t ps = {0};
|
||||
size_t wchars = mbsnrtowcs(NULL, &src, count, 0, &ps);
|
||||
|
||||
if (wchars == -1) {
|
||||
LOG_ERRNO("failed to convert %.*s to wchars", count, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
while (term->search.len + wchars >= term->search.sz) {
|
||||
size_t new_sz = term->search.sz == 0 ? 64 : term->search.sz * 2;
|
||||
wchar_t *new_buf = realloc(term->search.buf, new_sz * sizeof(term->search.buf[0]));
|
||||
|
||||
if (new_buf == NULL) {
|
||||
LOG_ERRNO("failed to resize search buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
term->search.buf = new_buf;
|
||||
term->search.sz = new_sz;
|
||||
}
|
||||
|
||||
assert(term->search.len + wchars < term->search.sz);
|
||||
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
mbsnrtowcs(&term->search.buf[term->search.len], &src, count,
|
||||
term->search.sz - term->search.len - 1, &ps);
|
||||
|
||||
term->search.len += wchars;
|
||||
term->search.buf[term->search.len] = L'\0';
|
||||
}
|
||||
|
||||
LOG_DBG("search: buffer: %S", term->search.buf);
|
||||
render_refresh(term);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue