search: add {clipboard,primary}-paste key bindings

These bindings copy from the clipboard or primary selection into the
search buffer.

Default bindings:

* clipboard-paste: ctrl+v, ctrl+y
* primary-paste: shift+insert
This commit is contained in:
Daniel Eklöf 2020-11-01 12:39:57 +01:00
parent 43f293f22e
commit f3e6941c9a
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 90 additions and 25 deletions

View file

@ -332,6 +332,35 @@ search_find_next(struct terminal *term)
#undef ROW_DEC
}
static void
add_chars(struct terminal *term, const char *src, size_t count)
{
mbstate_t ps = {0};
size_t wchars = mbsnrtowcs(NULL, &src, count, 0, &ps);
if (wchars == -1) {
LOG_ERRNO("failed to convert %.*s to wchars", (int)count, src);
return;
}
if (!search_ensure_size(term, term->search.len + wchars))
return;
assert(term->search.len + wchars < term->search.sz);
memmove(&term->search.buf[term->search.cursor + wchars],
&term->search.buf[term->search.cursor],
(term->search.len - term->search.cursor) * sizeof(wchar_t));
memset(&ps, 0, sizeof(ps));
mbsnrtowcs(&term->search.buf[term->search.cursor], &src, count,
wchars, &ps);
term->search.len += wchars;
term->search.cursor += wchars;
term->search.buf[term->search.len] = L'\0';
}
static void
search_match_to_end_of_word(struct terminal *term, bool spaces_only)
{
@ -461,6 +490,23 @@ distance_prev_word(const struct terminal *term)
return term->search.cursor - cursor;
}
static void
from_clipboard_cb(char *text, size_t size, void *user)
{
struct terminal *term = user;
add_chars(term, text, size);
}
static void
from_clipboard_done(void *user)
{
struct terminal *term = user;
LOG_DBG("search: buffer: %ls", term->search.buf);
search_find_next(term);
render_refresh_search(term);
}
static bool
execute_binding(struct seat *seat, struct terminal *term,
enum bind_action_search action, uint32_t serial)
@ -609,6 +655,16 @@ execute_binding(struct seat *seat, struct terminal *term,
search_match_to_end_of_word(term, true);
return false;
case BIND_ACTION_SEARCH_CLIPBOARD_PASTE:
text_from_clipboard(
seat, term, &from_clipboard_cb, &from_clipboard_done, term);
return false;
case BIND_ACTION_SEARCH_PRIMARY_PASTE:
text_from_primary(
seat, term, &from_clipboard_cb, &from_clipboard_done, term);
return false;
case BIND_ACTION_SEARCH_COUNT:
assert(false);
return false;
@ -666,31 +722,7 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
if (count == 0)
return;
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;
}
if (!search_ensure_size(term, term->search.len + wchars))
return;
assert(term->search.len + wchars < term->search.sz);
memmove(&term->search.buf[term->search.cursor + wchars],
&term->search.buf[term->search.cursor],
(term->search.len - term->search.cursor) * sizeof(wchar_t));
memset(&ps, 0, sizeof(ps));
mbsnrtowcs(&term->search.buf[term->search.cursor], &src, count,
wchars, &ps);
term->search.len += wchars;
term->search.cursor += wchars;
term->search.buf[term->search.len] = L'\0';
add_chars(term, (const char *)buf, count);
update_search:
LOG_DBG("search: buffer: %ls", term->search.buf);