search: don’t re-scan the scrollback unless the search string actually has changed

This commit is contained in:
Daniel Eklöf 2021-01-24 20:31:22 +01:00
parent 8df49c7f84
commit 9d51f2cb1a
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

116
search.c
View file

@ -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);
} }