mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-28 01:40:17 -05:00
search: don’t re-scan the scrollback unless the search string actually has changed
This commit is contained in:
parent
8df49c7f84
commit
9d51f2cb1a
1 changed files with 80 additions and 36 deletions
116
search.c
116
search.c
|
|
@ -573,8 +573,11 @@ from_clipboard_done(void *user)
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
execute_binding(struct seat *seat, struct terminal *term,
|
execute_binding(struct seat *seat, struct terminal *term,
|
||||||
enum bind_action_search action, uint32_t serial)
|
enum bind_action_search action, uint32_t serial,
|
||||||
|
bool *update_search_result, bool *redraw)
|
||||||
{
|
{
|
||||||
|
*update_search_result = *redraw = false;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case BIND_ACTION_SEARCH_NONE:
|
case BIND_ACTION_SEARCH_NONE:
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -610,7 +613,8 @@ execute_binding(struct seat *seat, struct terminal *term,
|
||||||
term->search.match.row = new_row;
|
term->search.match.row = new_row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_FIND_NEXT:
|
case BIND_ACTION_SEARCH_FIND_NEXT:
|
||||||
if (term->search.match_len > 0) {
|
if (term->search.match_len > 0) {
|
||||||
|
|
@ -626,43 +630,58 @@ execute_binding(struct seat *seat, struct terminal *term,
|
||||||
term->search.match.col = new_col;
|
term->search.match.col = new_col;
|
||||||
term->search.match.row = new_row;
|
term->search.match.row = new_row;
|
||||||
term->search.direction = SEARCH_FORWARD;
|
term->search.direction = SEARCH_FORWARD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EDIT_LEFT:
|
case BIND_ACTION_SEARCH_EDIT_LEFT:
|
||||||
if (term->search.cursor > 0)
|
if (term->search.cursor > 0) {
|
||||||
term->search.cursor--;
|
term->search.cursor--;
|
||||||
return false;
|
*redraw = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EDIT_LEFT_WORD: {
|
case BIND_ACTION_SEARCH_EDIT_LEFT_WORD: {
|
||||||
size_t diff = distance_prev_word(term);
|
size_t diff = distance_prev_word(term);
|
||||||
term->search.cursor -= diff;
|
term->search.cursor -= diff;
|
||||||
assert(term->search.cursor >= 0);
|
assert(term->search.cursor >= 0);
|
||||||
assert(term->search.cursor <= term->search.len);
|
assert(term->search.cursor <= term->search.len);
|
||||||
return false;
|
if (diff > 0)
|
||||||
|
*redraw = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EDIT_RIGHT:
|
case BIND_ACTION_SEARCH_EDIT_RIGHT:
|
||||||
if (term->search.cursor < term->search.len)
|
if (term->search.cursor < term->search.len) {
|
||||||
term->search.cursor++;
|
term->search.cursor++;
|
||||||
return false;
|
*redraw = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EDIT_RIGHT_WORD: {
|
case BIND_ACTION_SEARCH_EDIT_RIGHT_WORD: {
|
||||||
size_t diff = distance_next_word(term);
|
size_t diff = distance_next_word(term);
|
||||||
term->search.cursor += diff;
|
term->search.cursor += diff;
|
||||||
assert(term->search.cursor >= 0);
|
assert(term->search.cursor >= 0);
|
||||||
assert(term->search.cursor <= term->search.len);
|
assert(term->search.cursor <= term->search.len);
|
||||||
return false;
|
if (diff > 0)
|
||||||
|
*redraw = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EDIT_HOME:
|
case BIND_ACTION_SEARCH_EDIT_HOME:
|
||||||
term->search.cursor = 0;
|
if (term->search.cursor != 0) {
|
||||||
return false;
|
term->search.cursor = 0;
|
||||||
|
*redraw = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EDIT_END:
|
case BIND_ACTION_SEARCH_EDIT_END:
|
||||||
term->search.cursor = term->search.len;
|
if (term->search.cursor != term->search.len) {
|
||||||
return false;
|
term->search.cursor = term->search.len;
|
||||||
|
*redraw = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_DELETE_PREV:
|
case BIND_ACTION_SEARCH_DELETE_PREV:
|
||||||
if (term->search.cursor > 0) {
|
if (term->search.cursor > 0) {
|
||||||
|
|
@ -672,21 +691,25 @@ execute_binding(struct seat *seat, struct terminal *term,
|
||||||
(term->search.len - term->search.cursor) * sizeof(wchar_t));
|
(term->search.len - term->search.cursor) * sizeof(wchar_t));
|
||||||
term->search.cursor--;
|
term->search.cursor--;
|
||||||
term->search.buf[--term->search.len] = L'\0';
|
term->search.buf[--term->search.len] = L'\0';
|
||||||
|
*update_search_result = *redraw = true;
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_DELETE_PREV_WORD: {
|
case BIND_ACTION_SEARCH_DELETE_PREV_WORD: {
|
||||||
size_t diff = distance_prev_word(term);
|
size_t diff = distance_prev_word(term);
|
||||||
size_t old_cursor = term->search.cursor;
|
size_t old_cursor = term->search.cursor;
|
||||||
size_t new_cursor = old_cursor - diff;
|
size_t new_cursor = old_cursor - diff;
|
||||||
|
|
||||||
memmove(&term->search.buf[new_cursor],
|
if (diff > 0) {
|
||||||
&term->search.buf[old_cursor],
|
memmove(&term->search.buf[new_cursor],
|
||||||
(term->search.len - old_cursor) * sizeof(wchar_t));
|
&term->search.buf[old_cursor],
|
||||||
|
(term->search.len - old_cursor) * sizeof(wchar_t));
|
||||||
|
|
||||||
term->search.len -= diff;
|
term->search.len -= diff;
|
||||||
term->search.cursor = new_cursor;
|
term->search.cursor = new_cursor;
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_DELETE_NEXT:
|
case BIND_ACTION_SEARCH_DELETE_NEXT:
|
||||||
|
|
@ -696,42 +719,50 @@ execute_binding(struct seat *seat, struct terminal *term,
|
||||||
&term->search.buf[term->search.cursor + 1],
|
&term->search.buf[term->search.cursor + 1],
|
||||||
(term->search.len - term->search.cursor - 1) * sizeof(wchar_t));
|
(term->search.len - term->search.cursor - 1) * sizeof(wchar_t));
|
||||||
term->search.buf[--term->search.len] = L'\0';
|
term->search.buf[--term->search.len] = L'\0';
|
||||||
|
*update_search_result = *redraw = true;
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_DELETE_NEXT_WORD: {
|
case BIND_ACTION_SEARCH_DELETE_NEXT_WORD: {
|
||||||
size_t diff = distance_next_word(term);
|
size_t diff = distance_next_word(term);
|
||||||
size_t cursor = term->search.cursor;
|
size_t cursor = term->search.cursor;
|
||||||
|
|
||||||
memmove(&term->search.buf[cursor],
|
if (diff > 0) {
|
||||||
&term->search.buf[cursor + diff],
|
memmove(&term->search.buf[cursor],
|
||||||
(term->search.len - (cursor + diff)) * sizeof(wchar_t));
|
&term->search.buf[cursor + diff],
|
||||||
|
(term->search.len - (cursor + diff)) * sizeof(wchar_t));
|
||||||
|
|
||||||
term->search.len -= diff;
|
term->search.len -= diff;
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EXTEND_WORD:
|
case BIND_ACTION_SEARCH_EXTEND_WORD:
|
||||||
search_match_to_end_of_word(term, false);
|
search_match_to_end_of_word(term, false);
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_EXTEND_WORD_WS:
|
case BIND_ACTION_SEARCH_EXTEND_WORD_WS:
|
||||||
search_match_to_end_of_word(term, true);
|
search_match_to_end_of_word(term, true);
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_CLIPBOARD_PASTE:
|
case BIND_ACTION_SEARCH_CLIPBOARD_PASTE:
|
||||||
text_from_clipboard(
|
text_from_clipboard(
|
||||||
seat, term, &from_clipboard_cb, &from_clipboard_done, term);
|
seat, term, &from_clipboard_cb, &from_clipboard_done, term);
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_PRIMARY_PASTE:
|
case BIND_ACTION_SEARCH_PRIMARY_PASTE:
|
||||||
text_from_primary(
|
text_from_primary(
|
||||||
seat, term, &from_clipboard_cb, &from_clipboard_done, term);
|
seat, term, &from_clipboard_cb, &from_clipboard_done, term);
|
||||||
return false;
|
*update_search_result = *redraw = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SEARCH_COUNT:
|
case BIND_ACTION_SEARCH_COUNT:
|
||||||
assert(false);
|
assert(false);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -747,6 +778,9 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
||||||
enum xkb_compose_status compose_status = xkb_compose_state_get_status(
|
enum xkb_compose_status compose_status = xkb_compose_state_get_status(
|
||||||
seat->kbd.xkb_compose_state);
|
seat->kbd.xkb_compose_state);
|
||||||
|
|
||||||
|
bool update_search_result = false;
|
||||||
|
bool redraw = false;
|
||||||
|
|
||||||
/* Key bindings */
|
/* Key bindings */
|
||||||
tll_foreach(seat->kbd.bindings.search, it) {
|
tll_foreach(seat->kbd.bindings.search, it) {
|
||||||
if (it->item.bind.mods != mods)
|
if (it->item.bind.mods != mods)
|
||||||
|
|
@ -754,16 +788,22 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
||||||
|
|
||||||
/* Match symbol */
|
/* Match symbol */
|
||||||
if (it->item.bind.sym == sym) {
|
if (it->item.bind.sym == sym) {
|
||||||
if (!execute_binding(seat, term, it->item.action, serial))
|
if (execute_binding(seat, term, it->item.action, serial,
|
||||||
|
&update_search_result, &redraw))
|
||||||
|
{
|
||||||
goto update_search;
|
goto update_search;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Match raw key code */
|
/* Match raw key code */
|
||||||
tll_foreach(it->item.bind.key_codes, code) {
|
tll_foreach(it->item.bind.key_codes, code) {
|
||||||
if (code->item == key) {
|
if (code->item == key) {
|
||||||
if (!execute_binding(seat, term, it->item.action, serial))
|
if (execute_binding(seat, term, it->item.action, serial,
|
||||||
|
&update_search_result, &redraw))
|
||||||
|
{
|
||||||
goto update_search;
|
goto update_search;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -783,6 +823,8 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
||||||
seat->kbd.xkb_state, key, (char *)buf, sizeof(buf));
|
seat->kbd.xkb_state, key, (char *)buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_search_result = redraw = count > 0;
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -790,6 +832,8 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
||||||
|
|
||||||
update_search:
|
update_search:
|
||||||
LOG_DBG("search: buffer: %ls", term->search.buf);
|
LOG_DBG("search: buffer: %ls", term->search.buf);
|
||||||
search_find_next(term);
|
if (update_search_result)
|
||||||
render_refresh_search(term);
|
search_find_next(term);
|
||||||
|
if (redraw)
|
||||||
|
render_refresh_search(term);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue