mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-07 04:06:07 -05:00
initial vimode implementation
This commit is contained in:
parent
be19ca2b20
commit
e2c4ea3535
17 changed files with 1579 additions and 318 deletions
213
config.c
213
config.c
|
|
@ -14,6 +14,8 @@
|
|||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
#include <xkbcommon/xkbcommon-names.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
|
|
@ -120,7 +122,8 @@ static const char *const binding_action_map[] = {
|
|||
[BIND_ACTION_CLIPBOARD_COPY] = "clipboard-copy",
|
||||
[BIND_ACTION_CLIPBOARD_PASTE] = "clipboard-paste",
|
||||
[BIND_ACTION_PRIMARY_PASTE] = "primary-paste",
|
||||
[BIND_ACTION_SEARCH_START] = "search-start",
|
||||
[BIND_ACTION_START_VIMODE] = "start-vimode",
|
||||
[BIND_ACTION_START_VIMODE_SEARCH] = "start-vimode-search",
|
||||
[BIND_ACTION_FONT_SIZE_UP] = "font-increase",
|
||||
[BIND_ACTION_FONT_SIZE_DOWN] = "font-decrease",
|
||||
[BIND_ACTION_FONT_SIZE_RESET] = "font-reset",
|
||||
|
|
@ -159,43 +162,37 @@ static const char *const binding_action_map[] = {
|
|||
[BIND_ACTION_SELECT_ROW] = "select-row",
|
||||
};
|
||||
|
||||
static const char *const search_binding_action_map[] = {
|
||||
[BIND_ACTION_SEARCH_NONE] = NULL,
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_UP_PAGE] = "scrollback-up-page",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_UP_HALF_PAGE] = "scrollback-up-half-page",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_UP_LINE] = "scrollback-up-line",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_DOWN_PAGE] = "scrollback-down-page",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_DOWN_HALF_PAGE] = "scrollback-down-half-page",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_DOWN_LINE] = "scrollback-down-line",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_HOME] = "scrollback-home",
|
||||
[BIND_ACTION_SEARCH_SCROLLBACK_END] = "scrollback-end",
|
||||
[BIND_ACTION_SEARCH_CANCEL] = "cancel",
|
||||
[BIND_ACTION_SEARCH_COMMIT] = "commit",
|
||||
[BIND_ACTION_SEARCH_FIND_PREV] = "find-prev",
|
||||
[BIND_ACTION_SEARCH_FIND_NEXT] = "find-next",
|
||||
[BIND_ACTION_SEARCH_EDIT_LEFT] = "cursor-left",
|
||||
[BIND_ACTION_SEARCH_EDIT_LEFT_WORD] = "cursor-left-word",
|
||||
[BIND_ACTION_SEARCH_EDIT_RIGHT] = "cursor-right",
|
||||
[BIND_ACTION_SEARCH_EDIT_RIGHT_WORD] = "cursor-right-word",
|
||||
[BIND_ACTION_SEARCH_EDIT_HOME] = "cursor-home",
|
||||
[BIND_ACTION_SEARCH_EDIT_END] = "cursor-end",
|
||||
[BIND_ACTION_SEARCH_DELETE_PREV] = "delete-prev",
|
||||
[BIND_ACTION_SEARCH_DELETE_PREV_WORD] = "delete-prev-word",
|
||||
[BIND_ACTION_SEARCH_DELETE_NEXT] = "delete-next",
|
||||
[BIND_ACTION_SEARCH_DELETE_NEXT_WORD] = "delete-next-word",
|
||||
[BIND_ACTION_SEARCH_DELETE_TO_START] = "delete-to-start",
|
||||
[BIND_ACTION_SEARCH_DELETE_TO_END] = "delete-to-end",
|
||||
[BIND_ACTION_SEARCH_EXTEND_CHAR] = "extend-char",
|
||||
[BIND_ACTION_SEARCH_EXTEND_WORD] = "extend-to-word-boundary",
|
||||
[BIND_ACTION_SEARCH_EXTEND_WORD_WS] = "extend-to-next-whitespace",
|
||||
[BIND_ACTION_SEARCH_EXTEND_LINE_DOWN] = "extend-line-down",
|
||||
[BIND_ACTION_SEARCH_EXTEND_BACKWARD_CHAR] = "extend-backward-char",
|
||||
[BIND_ACTION_SEARCH_EXTEND_BACKWARD_WORD] = "extend-backward-to-word-boundary",
|
||||
[BIND_ACTION_SEARCH_EXTEND_BACKWARD_WORD_WS] = "extend-backward-to-next-whitespace",
|
||||
[BIND_ACTION_SEARCH_EXTEND_LINE_UP] = "extend-line-up",
|
||||
[BIND_ACTION_SEARCH_CLIPBOARD_PASTE] = "clipboard-paste",
|
||||
[BIND_ACTION_SEARCH_PRIMARY_PASTE] = "primary-paste",
|
||||
[BIND_ACTION_SEARCH_UNICODE_INPUT] = "unicode-input",
|
||||
static const char *const vimode_binding_action_map[] = {
|
||||
[BIND_ACTION_VIMODE_NONE] = NULL,
|
||||
[BIND_ACTION_VIMODE_UP] = "vimode-up",
|
||||
[BIND_ACTION_VIMODE_DOWN] = "vimode-down",
|
||||
[BIND_ACTION_VIMODE_LEFT] = "vimode-left",
|
||||
[BIND_ACTION_VIMODE_RIGHT] = "vimode-right",
|
||||
[BIND_ACTION_VIMODE_UP_PAGE] = "vimode-up-page",
|
||||
[BIND_ACTION_VIMODE_DOWN_PAGE] = "vimode-down-page",
|
||||
[BIND_ACTION_VIMODE_UP_HALF_PAGE] = "vimode-up-half-page",
|
||||
[BIND_ACTION_VIMODE_DOWN_HALF_PAGE] = "vimode-down-half-page",
|
||||
[BIND_ACTION_VIMODE_UP_LINE] = "vimode-up-line",
|
||||
[BIND_ACTION_VIMODE_DOWN_LINE] = "vimode-down-line",
|
||||
[BIND_ACTION_VIMODE_FIRST_LINE] = "vimode-first-line",
|
||||
[BIND_ACTION_VIMODE_LAST_LINE] = "vimode-last-line",
|
||||
[BIND_ACTION_VIMODE_CANCEL] = "vimode-cancel",
|
||||
[BIND_ACTION_VIMODE_START_SEARCH] = "vimode-start-search",
|
||||
[BIND_ACTION_VIMODE_FIND_NEXT] = "vimode-find-next",
|
||||
[BIND_ACTION_VIMODE_FIND_PREV] = "vimode-find-prev",
|
||||
[BIND_ACTION_VIMODE_ENTER_VISUAL] = "vimode-enter-visual",
|
||||
[BIND_ACTION_VIMODE_ENTER_VLINE] = "vimode-enter-visual-line",
|
||||
[BIND_ACTION_VIMODE_ENTER_VBLOCK] = "vimode-enter-visual-block",
|
||||
[BIND_ACTION_VIMODE_YANK] = "vimode-yank",
|
||||
};
|
||||
|
||||
static const char *const vimode_search_binding_action_map[] = {
|
||||
[BIND_ACTION_VIMODE_NONE] = NULL,
|
||||
[BIND_ACTION_VIMODE_SEARCH_CANCEL] = "vimode-search-cancel",
|
||||
[BIND_ACTION_VIMODE_SEARCH_CONFIRM] = "vimode-search-confirm",
|
||||
[BIND_ACTION_VIMODE_SEARCH_DELETE_PREV_CHAR] = "vimode-search-delete-prev",
|
||||
[BIND_ACTION_VIMODE_SEARCH_LEFT] = "vimode-search-left",
|
||||
[BIND_ACTION_VIMODE_SEARCH_RIGHT] = "vimode-search-right",
|
||||
};
|
||||
|
||||
static const char *const url_binding_action_map[] = {
|
||||
|
|
@ -206,8 +203,10 @@ static const char *const url_binding_action_map[] = {
|
|||
|
||||
static_assert(ALEN(binding_action_map) == BIND_ACTION_COUNT,
|
||||
"binding action map size mismatch");
|
||||
static_assert(ALEN(search_binding_action_map) == BIND_ACTION_SEARCH_COUNT,
|
||||
"search binding action map size mismatch");
|
||||
static_assert(ALEN(vimode_binding_action_map) == BIND_ACTION_VIMODE_COUNT,
|
||||
"vimode binding action map size mismatch");
|
||||
static_assert(ALEN(vimode_search_binding_action_map) == BIND_ACTION_VIMODE_SEARCH_COUNT,
|
||||
"vimode-search binding action map size mismatch");
|
||||
static_assert(ALEN(url_binding_action_map) == BIND_ACTION_URL_COUNT,
|
||||
"URL binding action map size mismatch");
|
||||
|
||||
|
|
@ -2388,12 +2387,21 @@ parse_section_key_bindings(struct context *ctx)
|
|||
}
|
||||
|
||||
static bool
|
||||
parse_section_search_bindings(struct context *ctx)
|
||||
parse_section_vimode_bindings(struct context *ctx)
|
||||
{
|
||||
return parse_key_binding_section(
|
||||
ctx,
|
||||
BIND_ACTION_SEARCH_COUNT, search_binding_action_map,
|
||||
&ctx->conf->bindings.search);
|
||||
BIND_ACTION_VIMODE_COUNT, vimode_binding_action_map,
|
||||
&ctx->conf->bindings.vimode);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_section_vimode_search_bindings(struct context *ctx)
|
||||
{
|
||||
return parse_key_binding_section(
|
||||
ctx,
|
||||
BIND_ACTION_VIMODE_SEARCH_COUNT, vimode_search_binding_action_map,
|
||||
&ctx->conf->bindings.vimode_search);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2964,7 +2972,8 @@ enum section {
|
|||
SECTION_MOUSE,
|
||||
SECTION_CSD,
|
||||
SECTION_KEY_BINDINGS,
|
||||
SECTION_SEARCH_BINDINGS,
|
||||
SECTION_VIMODE_BINDINGS,
|
||||
SECTION_VIMODE_SEARCH_BINDINGS,
|
||||
SECTION_URL_BINDINGS,
|
||||
SECTION_MOUSE_BINDINGS,
|
||||
SECTION_TEXT_BINDINGS,
|
||||
|
|
@ -2995,7 +3004,8 @@ static const struct {
|
|||
[SECTION_MOUSE] = {&parse_section_mouse, "mouse"},
|
||||
[SECTION_CSD] = {&parse_section_csd, "csd"},
|
||||
[SECTION_KEY_BINDINGS] = {&parse_section_key_bindings, "key-bindings"},
|
||||
[SECTION_SEARCH_BINDINGS] = {&parse_section_search_bindings, "search-bindings"},
|
||||
[SECTION_VIMODE_BINDINGS] = {&parse_section_vimode_bindings, "vimode-bindings"},
|
||||
[SECTION_VIMODE_SEARCH_BINDINGS] = {&parse_section_vimode_search_bindings, "vimode-search-bindings"},
|
||||
[SECTION_URL_BINDINGS] = {&parse_section_url_bindings, "url-bindings"},
|
||||
[SECTION_MOUSE_BINDINGS] = {&parse_section_mouse_bindings, "mouse-bindings"},
|
||||
[SECTION_TEXT_BINDINGS] = {&parse_section_text_bindings, "text-bindings"},
|
||||
|
|
@ -3234,7 +3244,8 @@ add_default_key_bindings(struct config *conf)
|
|||
{BIND_ACTION_CLIPBOARD_PASTE, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_v}}},
|
||||
{BIND_ACTION_CLIPBOARD_PASTE, m("none"), {{XKB_KEY_XF86Paste}}},
|
||||
{BIND_ACTION_PRIMARY_PASTE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Insert}}},
|
||||
{BIND_ACTION_SEARCH_START, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_r}}},
|
||||
{BIND_ACTION_START_VIMODE, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_r}}},
|
||||
{BIND_ACTION_START_VIMODE_SEARCH, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_slash}}},
|
||||
{BIND_ACTION_FONT_SIZE_UP, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_plus}}},
|
||||
{BIND_ACTION_FONT_SIZE_UP, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_equal}}},
|
||||
{BIND_ACTION_FONT_SIZE_UP, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_KP_Add}}},
|
||||
|
|
@ -3255,57 +3266,51 @@ add_default_key_bindings(struct config *conf)
|
|||
|
||||
|
||||
static void
|
||||
add_default_search_bindings(struct config *conf)
|
||||
add_default_vimode_bindings(struct config *conf)
|
||||
{
|
||||
const struct config_key_binding bindings[] = {
|
||||
{BIND_ACTION_SEARCH_SCROLLBACK_UP_PAGE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Prior}}},
|
||||
{BIND_ACTION_SEARCH_SCROLLBACK_UP_PAGE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_KP_Prior}}},
|
||||
{BIND_ACTION_SEARCH_SCROLLBACK_DOWN_PAGE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Next}}},
|
||||
{BIND_ACTION_SEARCH_SCROLLBACK_DOWN_PAGE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_KP_Next}}},
|
||||
{BIND_ACTION_SEARCH_CANCEL, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_c}}},
|
||||
{BIND_ACTION_SEARCH_CANCEL, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_g}}},
|
||||
{BIND_ACTION_SEARCH_CANCEL, m("none"), {{XKB_KEY_Escape}}},
|
||||
{BIND_ACTION_SEARCH_COMMIT, m("none"), {{XKB_KEY_Return}}},
|
||||
{BIND_ACTION_SEARCH_COMMIT, m("none"), {{XKB_KEY_KP_Enter}}},
|
||||
{BIND_ACTION_SEARCH_FIND_PREV, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_r}}},
|
||||
{BIND_ACTION_SEARCH_FIND_NEXT, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_s}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT, m("none"), {{XKB_KEY_Left}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_b}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT_WORD, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_Left}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT_WORD, m(XKB_MOD_NAME_ALT), {{XKB_KEY_b}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT, m("none"), {{XKB_KEY_Right}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_f}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_Right}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, m(XKB_MOD_NAME_ALT), {{XKB_KEY_f}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_HOME, m("none"), {{XKB_KEY_Home}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_HOME, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_a}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_END, m("none"), {{XKB_KEY_End}}},
|
||||
{BIND_ACTION_SEARCH_EDIT_END, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_e}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_PREV, m("none"), {{XKB_KEY_BackSpace}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_PREV_WORD, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_BackSpace}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_PREV_WORD, m(XKB_MOD_NAME_ALT), {{XKB_KEY_BackSpace}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_NEXT, m("none"), {{XKB_KEY_Delete}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_NEXT_WORD, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_Delete}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_NEXT_WORD, m(XKB_MOD_NAME_ALT), {{XKB_KEY_d}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_TO_START, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_u}}},
|
||||
{BIND_ACTION_SEARCH_DELETE_TO_END, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_k}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_CHAR, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Right}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_WORD, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_Right}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_WORD, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_w}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_WORD_WS, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_w}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_LINE_DOWN, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Down}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_BACKWARD_CHAR, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Left}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_BACKWARD_WORD, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_Left}}},
|
||||
{BIND_ACTION_SEARCH_EXTEND_LINE_UP, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Up}}},
|
||||
{BIND_ACTION_SEARCH_CLIPBOARD_PASTE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_v}}},
|
||||
{BIND_ACTION_SEARCH_CLIPBOARD_PASTE, m(XKB_MOD_NAME_CTRL "+" XKB_MOD_NAME_SHIFT), {{XKB_KEY_v}}},
|
||||
{BIND_ACTION_SEARCH_CLIPBOARD_PASTE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_y}}},
|
||||
{BIND_ACTION_SEARCH_CLIPBOARD_PASTE, m("none"), {{XKB_KEY_XF86Paste}}},
|
||||
{BIND_ACTION_SEARCH_PRIMARY_PASTE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_Insert}}},
|
||||
{BIND_ACTION_VIMODE_UP, m("none"), {{XKB_KEY_k}}},
|
||||
{BIND_ACTION_VIMODE_DOWN, m("none"), {{XKB_KEY_j}}},
|
||||
{BIND_ACTION_VIMODE_LEFT, m("none"), {{XKB_KEY_h}}},
|
||||
{BIND_ACTION_VIMODE_RIGHT, m("none"), {{XKB_KEY_l}}},
|
||||
{BIND_ACTION_VIMODE_UP_PAGE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_b}}},
|
||||
{BIND_ACTION_VIMODE_DOWN_PAGE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_f}}},
|
||||
{BIND_ACTION_VIMODE_UP_HALF_PAGE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_u}}},
|
||||
{BIND_ACTION_VIMODE_DOWN_HALF_PAGE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_d}}},
|
||||
{BIND_ACTION_VIMODE_UP_LINE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_y}}},
|
||||
{BIND_ACTION_VIMODE_DOWN_LINE, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_e}}},
|
||||
{BIND_ACTION_VIMODE_FIRST_LINE, m("none"), {{XKB_KEY_g}}},
|
||||
{BIND_ACTION_VIMODE_LAST_LINE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_g}}},
|
||||
{BIND_ACTION_VIMODE_CANCEL, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_c}}},
|
||||
{BIND_ACTION_VIMODE_CANCEL, m("none"), {{XKB_KEY_Escape}}},
|
||||
{BIND_ACTION_VIMODE_START_SEARCH, m("none"), {{XKB_KEY_slash}}},
|
||||
{BIND_ACTION_VIMODE_FIND_NEXT, m("none"), {{XKB_KEY_n}}},
|
||||
{BIND_ACTION_VIMODE_FIND_PREV, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_n}}},
|
||||
{BIND_ACTION_VIMODE_ENTER_VISUAL, m("none"), {{XKB_KEY_v}}},
|
||||
{BIND_ACTION_VIMODE_ENTER_VLINE, m(XKB_MOD_NAME_SHIFT), {{XKB_KEY_v}}},
|
||||
{BIND_ACTION_VIMODE_ENTER_VBLOCK, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_v}}},
|
||||
{BIND_ACTION_VIMODE_YANK, m("none"), {{XKB_KEY_y}}},
|
||||
};
|
||||
|
||||
conf->bindings.search.count = ALEN(bindings);
|
||||
conf->bindings.search.arr = xmemdup(bindings, sizeof(bindings));
|
||||
conf->bindings.vimode.count = ALEN(bindings);
|
||||
conf->bindings.vimode.arr = xmemdup(bindings, sizeof(bindings));
|
||||
}
|
||||
|
||||
static void
|
||||
add_default_vimode_search_bindings(struct config *conf)
|
||||
{
|
||||
const struct config_key_binding bindings[] = {
|
||||
{BIND_ACTION_VIMODE_SEARCH_CONFIRM, m("none"), {{XKB_KEY_Return}}},
|
||||
{BIND_ACTION_VIMODE_SEARCH_CANCEL, m("none"), {{XKB_KEY_Escape}}},
|
||||
{BIND_ACTION_VIMODE_SEARCH_DELETE_PREV_CHAR, m("none"), {{XKB_KEY_BackSpace}}},
|
||||
{BIND_ACTION_VIMODE_SEARCH_LEFT, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_h}}},
|
||||
{BIND_ACTION_VIMODE_SEARCH_LEFT, m("none"), {{XKB_KEY_leftarrow}}},
|
||||
{BIND_ACTION_VIMODE_SEARCH_RIGHT, m(XKB_MOD_NAME_CTRL), {{XKB_KEY_l}}},
|
||||
{BIND_ACTION_VIMODE_SEARCH_RIGHT, m("none"), {{XKB_KEY_rightarrow}}},
|
||||
};
|
||||
|
||||
conf->bindings.vimode_search.count = ALEN(bindings);
|
||||
conf->bindings.vimode_search.arr = xmemdup(bindings, sizeof(bindings));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3602,7 +3607,8 @@ config_load(struct config *conf, const char *conf_path,
|
|||
}
|
||||
|
||||
add_default_key_bindings(conf);
|
||||
add_default_search_bindings(conf);
|
||||
add_default_vimode_bindings(conf);
|
||||
add_default_vimode_search_bindings(conf);
|
||||
add_default_url_bindings(conf);
|
||||
add_default_mouse_bindings(conf);
|
||||
|
||||
|
|
@ -3661,8 +3667,10 @@ config_load(struct config *conf, const char *conf_path,
|
|||
#if defined(_DEBUG)
|
||||
for (size_t i = 0; i < conf->bindings.key.count; i++)
|
||||
xassert(conf->bindings.key.arr[i].action != BIND_ACTION_NONE);
|
||||
for (size_t i = 0; i < conf->bindings.search.count; i++)
|
||||
xassert(conf->bindings.search.arr[i].action != BIND_ACTION_SEARCH_NONE);
|
||||
for (size_t i = 0; i < conf->bindings.vimode.count; i++)
|
||||
xassert(conf->bindings.vimode.arr[i].action != BIND_ACTION_VIMODE_NONE);
|
||||
for (size_t i = 0; i < conf->bindings.vimode_search.count; i++)
|
||||
xassert(conf->bindings.vimode_search.arr[i].action != BIND_ACTION_VIMODE_SEARCH_NONE);
|
||||
for (size_t i = 0; i < conf->bindings.url.count; i++)
|
||||
xassert(conf->bindings.url.arr[i].action != BIND_ACTION_URL_NONE);
|
||||
#endif
|
||||
|
|
@ -3738,8 +3746,11 @@ config_override_apply(struct config *conf, config_override_t *overrides,
|
|||
conf, section_info[SECTION_KEY_BINDINGS].name,
|
||||
binding_action_map, &conf->bindings.key, KEY_BINDING) &&
|
||||
resolve_key_binding_collisions(
|
||||
conf, section_info[SECTION_SEARCH_BINDINGS].name,
|
||||
search_binding_action_map, &conf->bindings.search, KEY_BINDING) &&
|
||||
conf, section_info[SECTION_VIMODE_BINDINGS].name,
|
||||
vimode_binding_action_map, &conf->bindings.vimode, KEY_BINDING) &&
|
||||
resolve_key_binding_collisions(
|
||||
conf, section_info[SECTION_VIMODE_SEARCH_BINDINGS].name,
|
||||
vimode_search_binding_action_map, &conf->bindings.vimode_search, KEY_BINDING) &&
|
||||
resolve_key_binding_collisions(
|
||||
conf, section_info[SECTION_URL_BINDINGS].name,
|
||||
url_binding_action_map, &conf->bindings.url, KEY_BINDING) &&
|
||||
|
|
@ -3863,7 +3874,8 @@ config_clone(const struct config *old)
|
|||
}
|
||||
|
||||
key_binding_list_clone(&conf->bindings.key, &old->bindings.key);
|
||||
key_binding_list_clone(&conf->bindings.search, &old->bindings.search);
|
||||
key_binding_list_clone(&conf->bindings.vimode, &old->bindings.vimode);
|
||||
key_binding_list_clone(&conf->bindings.vimode_search, &old->bindings.vimode_search);
|
||||
key_binding_list_clone(&conf->bindings.url, &old->bindings.url);
|
||||
key_binding_list_clone(&conf->bindings.mouse, &old->bindings.mouse);
|
||||
|
||||
|
|
@ -3955,7 +3967,8 @@ config_free(struct config *conf)
|
|||
}
|
||||
|
||||
free_key_binding_list(&conf->bindings.key);
|
||||
free_key_binding_list(&conf->bindings.search);
|
||||
free_key_binding_list(&conf->bindings.vimode);
|
||||
free_key_binding_list(&conf->bindings.vimode_search);
|
||||
free_key_binding_list(&conf->bindings.url);
|
||||
free_key_binding_list(&conf->bindings.mouse);
|
||||
tll_free_and_free(conf->mouse.selection_override_modifiers, free);
|
||||
|
|
|
|||
16
config.h
16
config.h
|
|
@ -88,6 +88,7 @@ enum key_binding_type {
|
|||
typedef tll(char *) config_modifier_list_t;
|
||||
|
||||
struct config_key_binding {
|
||||
// TODO (kociap): from wayland.h?
|
||||
int action; /* One of the various bind_action_* enums from wayland.h */
|
||||
//struct config_key_modifiers modifiers;
|
||||
config_modifier_list_t modifiers;
|
||||
|
|
@ -358,9 +359,18 @@ struct config {
|
|||
* Special modes
|
||||
*/
|
||||
|
||||
/* While searching (not - action to *start* a search is in the
|
||||
* 'key' bindings above */
|
||||
struct config_key_binding_list search;
|
||||
/*
|
||||
* Bindings for vimode.
|
||||
* Note: action to enter vimode is in the 'key' bindings
|
||||
* above.
|
||||
*/
|
||||
struct config_key_binding_list vimode;
|
||||
/*
|
||||
* Bindings for the search mode within vimode.
|
||||
* Actions to enter the search mode are in the 'key' and
|
||||
* 'vimode' bindings.
|
||||
*/
|
||||
struct config_key_binding_list vimode_search;
|
||||
|
||||
/* While showing URL jump labels */
|
||||
struct config_key_binding_list url;
|
||||
|
|
|
|||
2
grid.c
2
grid.c
|
|
@ -819,6 +819,7 @@ grid_resize_and_reflow(
|
|||
size_t tracking_points_count,
|
||||
struct coord *const _tracking_points[static tracking_points_count])
|
||||
{
|
||||
printf("GRID REFLOW\n");
|
||||
#if defined(TIME_REFLOW) && TIME_REFLOW
|
||||
struct timespec start;
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
|
@ -859,6 +860,7 @@ grid_resize_and_reflow(
|
|||
saved_cursor.row += grid->offset;
|
||||
saved_cursor.row &= old_rows - 1;
|
||||
|
||||
// TODO (kociap): add the vimode cursor and selection start.
|
||||
size_t tp_count =
|
||||
tracking_points_count +
|
||||
1 + /* cursor */
|
||||
|
|
|
|||
25
ime.c
25
ime.c
|
|
@ -177,8 +177,10 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
|||
ime_reset_preedit(seat);
|
||||
|
||||
if (term != NULL) {
|
||||
if (term->is_searching)
|
||||
render_refresh_search(term);
|
||||
if (term->is_vimming)
|
||||
// TODO (kociap): refresh
|
||||
// render_refresh_search(term);
|
||||
(void)0;
|
||||
else
|
||||
render_refresh(term);
|
||||
}
|
||||
|
|
@ -198,9 +200,11 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
|||
size_t len = strlen(text);
|
||||
|
||||
if (term != NULL) {
|
||||
if (term->is_searching) {
|
||||
search_add_chars(term, text, len);
|
||||
render_refresh_search(term);
|
||||
if (term->is_vimming) {
|
||||
// TODO (kociap): input and refresh
|
||||
// search_add_chars(term, text, len);
|
||||
// render_refresh_search(term);
|
||||
(void)0;
|
||||
} else
|
||||
term_to_slave(term, text, len);
|
||||
}
|
||||
|
|
@ -367,8 +371,10 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
|||
ime_reset_pending_preedit(seat);
|
||||
|
||||
if (term != NULL) {
|
||||
if (term->is_searching)
|
||||
render_refresh_search(term);
|
||||
if (term->is_vimming)
|
||||
// TODO (kociap): refresh
|
||||
// render_refresh_search(term);
|
||||
(void)0;
|
||||
else
|
||||
render_refresh(term);
|
||||
}
|
||||
|
|
@ -474,8 +480,9 @@ ime_update_cursor_rect(struct seat *seat)
|
|||
goto update;
|
||||
|
||||
/* Set in render_search_box() */
|
||||
if (term->is_searching)
|
||||
goto update;
|
||||
// TODO (kociap): in vimode this most likely is not necessary.
|
||||
// if (term->is_searching)
|
||||
// goto update;
|
||||
|
||||
int x, y, width, height;
|
||||
int col = term->grid->cursor.point.col;
|
||||
|
|
|
|||
21
input.c
21
input.c
|
|
@ -31,7 +31,7 @@
|
|||
#include "macros.h"
|
||||
#include "quirks.h"
|
||||
#include "render.h"
|
||||
#include "search.h"
|
||||
#include "vimode.h"
|
||||
#include "selection.h"
|
||||
#include "spawn.h"
|
||||
#include "terminal.h"
|
||||
|
|
@ -183,8 +183,12 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
term_reset_view(term);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_SEARCH_START:
|
||||
search_begin(term);
|
||||
case BIND_ACTION_START_VIMODE:
|
||||
vimode_begin(term);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_START_VIMODE_SEARCH:
|
||||
vimode_search_begin(term);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_FONT_SIZE_UP:
|
||||
|
|
@ -1579,7 +1583,6 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
uint32_t key, uint32_t state)
|
||||
{
|
||||
xassert(serial != 0);
|
||||
|
||||
seat->kbd.serial = serial;
|
||||
if (seat->kbd.xkb == NULL ||
|
||||
seat->kbd.xkb_keymap == NULL ||
|
||||
|
|
@ -1632,15 +1635,17 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
|
||||
if (pressed) {
|
||||
if (term->unicode_mode.active) {
|
||||
printf("UNICODE INPUT\n");
|
||||
unicode_mode_input(seat, term, sym);
|
||||
return;
|
||||
}
|
||||
|
||||
else if (term->is_searching) {
|
||||
else if (term->is_vimming) {
|
||||
printf("VIMODE INPUT\n");
|
||||
if (should_repeat)
|
||||
start_repeater(seat, key);
|
||||
|
||||
search_input(
|
||||
vimode_input(
|
||||
seat, term, bindings, key, sym, mods, consumed,
|
||||
raw_syms, raw_count, serial);
|
||||
return;
|
||||
|
|
@ -2744,7 +2749,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
|||
selection_stop_scroll_timer(term);
|
||||
|
||||
/* Update selection */
|
||||
if (!term->is_searching) {
|
||||
if (!term->is_vimming) {
|
||||
if (auto_scroll_direction != SELECTION_SCROLL_NOT) {
|
||||
/*
|
||||
* Start 'selection auto-scrolling'
|
||||
|
|
@ -3207,7 +3212,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
break;
|
||||
|
||||
case TERM_SURF_GRID: {
|
||||
search_cancel(term);
|
||||
vimode_cancel(term);
|
||||
urls_reset(term);
|
||||
|
||||
bool cursor_is_on_grid = seat->mouse.col >= 0 && seat->mouse.row >= 0;
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ key_binding_new_for_seat(struct key_binding_manager *mgr,
|
|||
struct key_set set = {
|
||||
.public = {
|
||||
.key = tll_init(),
|
||||
.search = tll_init(),
|
||||
.vimode = tll_init(),
|
||||
.url = tll_init(),
|
||||
.mouse = tll_init(),
|
||||
},
|
||||
|
|
@ -152,7 +152,7 @@ key_binding_new_for_conf(struct key_binding_manager *mgr,
|
|||
struct key_set set = {
|
||||
.public = {
|
||||
.key = tll_init(),
|
||||
.search = tll_init(),
|
||||
.vimode = tll_init(),
|
||||
.url = tll_init(),
|
||||
.mouse = tll_init(),
|
||||
},
|
||||
|
|
@ -532,13 +532,25 @@ convert_key_bindings(struct key_set *set)
|
|||
}
|
||||
|
||||
static void
|
||||
convert_search_bindings(struct key_set *set)
|
||||
convert_vimode_bindings(struct key_set *set)
|
||||
{
|
||||
const struct config *conf = set->conf;
|
||||
|
||||
for (size_t i = 0; i < conf->bindings.search.count; i++) {
|
||||
const struct config_key_binding *binding = &conf->bindings.search.arr[i];
|
||||
convert_key_binding(set, binding, &set->public.search);
|
||||
for (size_t i = 0; i < conf->bindings.vimode.count; i++) {
|
||||
const struct config_key_binding *binding = &conf->bindings.vimode.arr[i];
|
||||
convert_key_binding(set, binding, &set->public.vimode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_vimode_search_bindings(struct key_set *set)
|
||||
{
|
||||
const struct config *conf = set->conf;
|
||||
|
||||
for (size_t i = 0; i < conf->bindings.vimode_search.count; i++) {
|
||||
const struct config_key_binding *binding =
|
||||
&conf->bindings.vimode_search.arr[i];
|
||||
convert_key_binding(set, binding, &set->public.vimode_search);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +609,8 @@ load_keymap(struct key_set *set)
|
|||
}
|
||||
|
||||
convert_key_bindings(set);
|
||||
convert_search_bindings(set);
|
||||
convert_vimode_bindings(set);
|
||||
convert_vimode_search_bindings(set);
|
||||
convert_url_bindings(set);
|
||||
convert_mouse_bindings(set);
|
||||
|
||||
|
|
@ -638,7 +651,8 @@ static void NOINLINE
|
|||
unload_keymap(struct key_set *set)
|
||||
{
|
||||
key_bindings_destroy(&set->public.key);
|
||||
key_bindings_destroy(&set->public.search);
|
||||
key_bindings_destroy(&set->public.vimode);
|
||||
key_bindings_destroy(&set->public.vimode_search);
|
||||
key_bindings_destroy(&set->public.url);
|
||||
key_bindings_destroy(&set->public.mouse);
|
||||
set->public.selection_overrides = 0;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ enum bind_action_normal {
|
|||
BIND_ACTION_CLIPBOARD_COPY,
|
||||
BIND_ACTION_CLIPBOARD_PASTE,
|
||||
BIND_ACTION_PRIMARY_PASTE,
|
||||
BIND_ACTION_SEARCH_START,
|
||||
BIND_ACTION_START_VIMODE,
|
||||
BIND_ACTION_START_VIMODE_SEARCH,
|
||||
BIND_ACTION_FONT_SIZE_UP,
|
||||
BIND_ACTION_FONT_SIZE_DOWN,
|
||||
BIND_ACTION_FONT_SIZE_RESET,
|
||||
|
|
@ -63,44 +64,41 @@ enum bind_action_normal {
|
|||
BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1,
|
||||
};
|
||||
|
||||
enum bind_action_search {
|
||||
BIND_ACTION_SEARCH_NONE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_UP_PAGE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_UP_HALF_PAGE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_UP_LINE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_DOWN_PAGE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_DOWN_HALF_PAGE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_DOWN_LINE,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_HOME,
|
||||
BIND_ACTION_SEARCH_SCROLLBACK_END,
|
||||
BIND_ACTION_SEARCH_CANCEL,
|
||||
BIND_ACTION_SEARCH_COMMIT,
|
||||
BIND_ACTION_SEARCH_FIND_PREV,
|
||||
BIND_ACTION_SEARCH_FIND_NEXT,
|
||||
BIND_ACTION_SEARCH_EDIT_LEFT,
|
||||
BIND_ACTION_SEARCH_EDIT_LEFT_WORD,
|
||||
BIND_ACTION_SEARCH_EDIT_RIGHT,
|
||||
BIND_ACTION_SEARCH_EDIT_RIGHT_WORD,
|
||||
BIND_ACTION_SEARCH_EDIT_HOME,
|
||||
BIND_ACTION_SEARCH_EDIT_END,
|
||||
BIND_ACTION_SEARCH_DELETE_PREV,
|
||||
BIND_ACTION_SEARCH_DELETE_PREV_WORD,
|
||||
BIND_ACTION_SEARCH_DELETE_NEXT,
|
||||
BIND_ACTION_SEARCH_DELETE_NEXT_WORD,
|
||||
BIND_ACTION_SEARCH_DELETE_TO_START,
|
||||
BIND_ACTION_SEARCH_DELETE_TO_END,
|
||||
BIND_ACTION_SEARCH_EXTEND_CHAR,
|
||||
BIND_ACTION_SEARCH_EXTEND_WORD,
|
||||
BIND_ACTION_SEARCH_EXTEND_WORD_WS,
|
||||
BIND_ACTION_SEARCH_EXTEND_LINE_DOWN,
|
||||
BIND_ACTION_SEARCH_EXTEND_BACKWARD_CHAR,
|
||||
BIND_ACTION_SEARCH_EXTEND_BACKWARD_WORD,
|
||||
BIND_ACTION_SEARCH_EXTEND_BACKWARD_WORD_WS,
|
||||
BIND_ACTION_SEARCH_EXTEND_LINE_UP,
|
||||
BIND_ACTION_SEARCH_CLIPBOARD_PASTE,
|
||||
BIND_ACTION_SEARCH_PRIMARY_PASTE,
|
||||
BIND_ACTION_SEARCH_UNICODE_INPUT,
|
||||
BIND_ACTION_SEARCH_COUNT,
|
||||
enum bind_action_vimode {
|
||||
BIND_ACTION_VIMODE_NONE,
|
||||
BIND_ACTION_VIMODE_UP,
|
||||
BIND_ACTION_VIMODE_DOWN,
|
||||
BIND_ACTION_VIMODE_LEFT,
|
||||
BIND_ACTION_VIMODE_RIGHT,
|
||||
BIND_ACTION_VIMODE_UP_PAGE,
|
||||
BIND_ACTION_VIMODE_DOWN_PAGE,
|
||||
BIND_ACTION_VIMODE_UP_HALF_PAGE,
|
||||
BIND_ACTION_VIMODE_DOWN_HALF_PAGE,
|
||||
BIND_ACTION_VIMODE_UP_LINE,
|
||||
BIND_ACTION_VIMODE_DOWN_LINE,
|
||||
BIND_ACTION_VIMODE_FIRST_LINE,
|
||||
BIND_ACTION_VIMODE_LAST_LINE,
|
||||
BIND_ACTION_VIMODE_CANCEL,
|
||||
BIND_ACTION_VIMODE_START_SEARCH,
|
||||
BIND_ACTION_VIMODE_FIND_NEXT,
|
||||
BIND_ACTION_VIMODE_FIND_PREV,
|
||||
BIND_ACTION_VIMODE_ENTER_VISUAL,
|
||||
BIND_ACTION_VIMODE_ENTER_VLINE,
|
||||
BIND_ACTION_VIMODE_ENTER_VBLOCK,
|
||||
BIND_ACTION_VIMODE_YANK,
|
||||
|
||||
BIND_ACTION_VIMODE_COUNT,
|
||||
};
|
||||
|
||||
enum bind_action_vimode_search {
|
||||
BIND_ACTION_VIMODE_SEARCH_NONE,
|
||||
BIND_ACTION_VIMODE_SEARCH_CONFIRM,
|
||||
BIND_ACTION_VIMODE_SEARCH_CANCEL,
|
||||
BIND_ACTION_VIMODE_SEARCH_DELETE_PREV_CHAR,
|
||||
BIND_ACTION_VIMODE_SEARCH_LEFT,
|
||||
BIND_ACTION_VIMODE_SEARCH_RIGHT,
|
||||
|
||||
BIND_ACTION_VIMODE_SEARCH_COUNT,
|
||||
};
|
||||
|
||||
enum bind_action_url {
|
||||
|
|
@ -140,7 +138,8 @@ struct wayland;
|
|||
|
||||
struct key_binding_set {
|
||||
key_binding_list_t key;
|
||||
key_binding_list_t search;
|
||||
key_binding_list_t vimode;
|
||||
key_binding_list_t vimode_search;
|
||||
key_binding_list_t url;
|
||||
key_binding_list_t mouse;
|
||||
xkb_mod_mask_t selection_overrides;
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ executable(
|
|||
'quirks.c', 'quirks.h',
|
||||
'reaper.c', 'reaper.h',
|
||||
'render.c', 'render.h',
|
||||
'search.c', 'search.h',
|
||||
'vimode.c', 'vimode.h',
|
||||
'server.c', 'server.h', 'client-protocol.h',
|
||||
'shm.c', 'shm.h',
|
||||
'slave.c', 'slave.h',
|
||||
|
|
|
|||
247
render.c
247
render.c
|
|
@ -36,7 +36,7 @@
|
|||
#include "grid.h"
|
||||
#include "ime.h"
|
||||
#include "quirks.h"
|
||||
#include "search.h"
|
||||
#include "vimode.h"
|
||||
#include "selection.h"
|
||||
#include "shm.h"
|
||||
#include "sixel.h"
|
||||
|
|
@ -598,6 +598,10 @@ draw_strikeout(const struct terminal *term, pixman_image_t *pix,
|
|||
cols * term->cell_width, thickness});
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO (kociap): The cell parameter is not used? We could make this
|
||||
* function more generic to be reusable in the search box.
|
||||
*/
|
||||
static void
|
||||
cursor_colors_for_cell(const struct terminal *term, const struct cell *cell,
|
||||
const pixman_color_t *fg, const pixman_color_t *bg,
|
||||
|
|
@ -701,11 +705,12 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
const int x = term->margins.left + col * width;
|
||||
const int y = term->margins.top + row_no * height;
|
||||
|
||||
const bool is_selected = cell->attrs.selected;
|
||||
|
||||
uint32_t _fg = 0;
|
||||
uint32_t _bg = 0;
|
||||
|
||||
uint16_t alpha = 0xffff;
|
||||
const bool is_selected = cell->attrs.selected;
|
||||
|
||||
/* Use cell specific color, if set, otherwise the default colors (possible reversed) */
|
||||
switch (cell->attrs.fg_src) {
|
||||
|
|
@ -762,19 +767,29 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
_fg = cell_bg;
|
||||
}
|
||||
|
||||
// Cursor is always inverted, thus we want to invert it when
|
||||
// the vi mode is visual or visual block for visibility
|
||||
// (otherwise it is difficult to tell its position within the
|
||||
// row).
|
||||
const bool mode_not_vline = term->vimode.mode == VI_MODE_VISUAL ||
|
||||
term->vimode.mode == VI_MODE_VBLOCK;
|
||||
if (has_cursor && mode_not_vline) {
|
||||
uint32_t swap = _fg;
|
||||
_fg = _bg;
|
||||
_bg = swap;
|
||||
}
|
||||
|
||||
if (unlikely(_fg == _bg)) {
|
||||
/* Invert bg when selected/highlighted text has same fg/bg */
|
||||
_bg = ~_bg;
|
||||
alpha = 0xffff;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (unlikely(cell->attrs.reverse)) {
|
||||
uint32_t swap = _fg;
|
||||
_fg = _bg;
|
||||
_bg = swap;
|
||||
}
|
||||
|
||||
else if (!term->window->is_fullscreen && term->colors.alpha != 0xffff) {
|
||||
switch (term->conf->colors.alpha_mode) {
|
||||
case ALPHA_MODE_DEFAULT: {
|
||||
|
|
@ -1722,7 +1737,7 @@ render_ime_preedit_for_seat(struct terminal *term, struct seat *seat,
|
|||
if (likely(seat->ime.preedit.cells == NULL))
|
||||
return;
|
||||
|
||||
if (unlikely(term->is_searching))
|
||||
if (unlikely(term->is_vimming))
|
||||
return;
|
||||
|
||||
const bool gamma_correct = wayl_do_linear_blending(term->wl, term->conf);
|
||||
|
|
@ -1965,7 +1980,7 @@ render_overlay(struct terminal *term)
|
|||
const bool unicode_mode_active = term->unicode_mode.active;
|
||||
|
||||
const enum overlay_style style =
|
||||
term->is_searching ? OVERLAY_SEARCH :
|
||||
term->is_vimming ? OVERLAY_SEARCH :
|
||||
term->flash.active ? OVERLAY_FLASH :
|
||||
unicode_mode_active ? OVERLAY_UNICODE_MODE :
|
||||
OVERLAY_NONE;
|
||||
|
|
@ -2065,33 +2080,34 @@ render_overlay(struct terminal *term)
|
|||
pixman_region32_clear(see_through);
|
||||
|
||||
/* Build region consisting of all current search matches */
|
||||
struct search_match_iterator iter = search_matches_new_iter(term);
|
||||
for (struct range match = search_matches_next(&iter);
|
||||
match.start.row >= 0;
|
||||
match = search_matches_next(&iter))
|
||||
{
|
||||
int r = match.start.row;
|
||||
int start_col = match.start.col;
|
||||
const int end_row = match.end.row;
|
||||
|
||||
while (true) {
|
||||
const int end_col =
|
||||
r == end_row ? match.end.col : term->cols - 1;
|
||||
|
||||
int x = term->margins.left + start_col * term->cell_width;
|
||||
int y = term->margins.top + r * term->cell_height;
|
||||
int width = (end_col + 1 - start_col) * term->cell_width;
|
||||
int height = 1 * term->cell_height;
|
||||
|
||||
pixman_region32_union_rect(
|
||||
see_through, see_through, x, y, width, height);
|
||||
|
||||
if (++r > end_row)
|
||||
break;
|
||||
|
||||
start_col = 0;
|
||||
}
|
||||
}
|
||||
// TODO (kociap): commented this because no search atm.
|
||||
// struct search_match_iterator iter = search_matches_new_iter(term);
|
||||
// for (struct range match = search_matches_next(&iter);
|
||||
// match.start.row >= 0;
|
||||
// match = search_matches_next(&iter))
|
||||
// {
|
||||
// int r = match.start.row;
|
||||
// int start_col = match.start.col;
|
||||
// const int end_row = match.end.row;
|
||||
//
|
||||
// while (true) {
|
||||
// const int end_col =
|
||||
// r == end_row ? match.end.col : term->cols - 1;
|
||||
//
|
||||
// int x = term->margins.left + start_col * term->cell_width;
|
||||
// int y = term->margins.top + r * term->cell_height;
|
||||
// int width = (end_col + 1 - start_col) * term->cell_width;
|
||||
// int height = 1 * term->cell_height;
|
||||
//
|
||||
// pixman_region32_union_rect(
|
||||
// see_through, see_through, x, y, width, height);
|
||||
//
|
||||
// if (++r > end_row)
|
||||
// break;
|
||||
//
|
||||
// start_col = 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Areas that need to be cleared: cells that were dimmed in
|
||||
* the last frame but is now see-through */
|
||||
|
|
@ -2198,9 +2214,17 @@ render_worker_thread(void *_ctx)
|
|||
|
||||
bool frame_done = false;
|
||||
|
||||
/* Translate offset-relative cursor row to view-relative */
|
||||
/*
|
||||
* We always show the vimode cursor when in vimode as that is
|
||||
* not dependent on the terminal state.
|
||||
*/
|
||||
struct coord cursor = {-1, -1};
|
||||
if (!term->hide_cursor) {
|
||||
if (term->is_vimming) {
|
||||
cursor = term->vimode.cursor;
|
||||
cursor.row += term->grid->offset;
|
||||
cursor.row -= term->grid->view;
|
||||
cursor.row &= term->grid->num_rows - 1;
|
||||
} else if (!term->hide_cursor) {
|
||||
cursor = term->grid->cursor.point;
|
||||
cursor.row += term->grid->offset;
|
||||
cursor.row -= term->grid->view;
|
||||
|
|
@ -3084,10 +3108,11 @@ render_scrollback_position(struct terminal *term)
|
|||
|
||||
case SCROLLBACK_INDICATOR_POSITION_RELATIVE: {
|
||||
int lines = term->rows - 2; /* Avoid using first and last rows */
|
||||
if (term->is_searching) {
|
||||
/* Make sure we don't collide with the scrollback search box */
|
||||
lines--;
|
||||
}
|
||||
// TODO (kociap): whatever this does
|
||||
// if (term->is_searching) {
|
||||
// /* Make sure we don't collide with the scrollback search box */
|
||||
// lines--;
|
||||
// }
|
||||
|
||||
lines = max(lines, 0);
|
||||
|
||||
|
|
@ -3303,7 +3328,6 @@ dirty_cursor(struct terminal *term)
|
|||
return;
|
||||
|
||||
const struct coord *cursor = &term->grid->cursor.point;
|
||||
|
||||
struct row *row = grid_row(term->grid, cursor->row);
|
||||
struct cell *cell = &row->cells[cursor->col];
|
||||
cell->attrs.clean = 0;
|
||||
|
|
@ -3603,7 +3627,8 @@ grid_render(struct terminal *term)
|
|||
|
||||
pixman_region32_fini(&damage);
|
||||
|
||||
render_overlay(term);
|
||||
// TODO (kociap): we want to eventually render the overlays.
|
||||
// render_overlay(term);
|
||||
render_ime_preedit(term, buf);
|
||||
render_scrollback_position(term);
|
||||
|
||||
|
|
@ -3709,9 +3734,20 @@ grid_render(struct terminal *term)
|
|||
wl_surface_commit(term->window->surface.surf);
|
||||
}
|
||||
|
||||
static void
|
||||
render_search_box_cursor(
|
||||
struct terminal* const term, pixman_image_t* const pix, pixman_color_t fg,
|
||||
int x, int y)
|
||||
{
|
||||
pixman_image_fill_rectangles(
|
||||
PIXMAN_OP_SRC, pix, &fg, 1,
|
||||
&(pixman_rectangle16_t){x, y, term->cell_width, term->cell_height});
|
||||
}
|
||||
|
||||
static void
|
||||
render_search_box(struct terminal *term)
|
||||
{
|
||||
printf("REDRAWING SEARCH BOX\n");
|
||||
xassert(term->window->search.sub != NULL);
|
||||
|
||||
/*
|
||||
|
|
@ -3735,7 +3771,7 @@ render_search_box(struct terminal *term)
|
|||
}
|
||||
}
|
||||
|
||||
size_t text_len = term->search.len;
|
||||
size_t text_len = term->vimode.search.len;
|
||||
if (ime_seat != NULL && ime_seat->ime.preedit.text != NULL)
|
||||
text_len += c32len(ime_seat->ime.preedit.text);
|
||||
|
||||
|
|
@ -3743,19 +3779,19 @@ render_search_box(struct terminal *term)
|
|||
text[0] = U'\0';
|
||||
|
||||
/* Copy everything up to the cursor */
|
||||
c32ncpy(text, term->search.buf, term->search.cursor);
|
||||
text[term->search.cursor] = U'\0';
|
||||
c32ncpy(text, term->vimode.search.buf, term->vimode.search.cursor);
|
||||
text[term->vimode.search.cursor] = U'\0';
|
||||
|
||||
/* Insert pre-edit text at cursor */
|
||||
if (ime_seat != NULL && ime_seat->ime.preedit.text != NULL)
|
||||
c32cat(text, ime_seat->ime.preedit.text);
|
||||
|
||||
/* And finally everything after the cursor */
|
||||
c32ncat(text, &term->search.buf[term->search.cursor],
|
||||
term->search.len - term->search.cursor);
|
||||
c32ncat(text, &term->vimode.search.buf[term->vimode.search.cursor],
|
||||
term->vimode.search.len - term->vimode.search.cursor);
|
||||
#else
|
||||
const char32_t *text = term->search.buf;
|
||||
const size_t text_len = term->search.len;
|
||||
const char32_t *text = term->vimode.search.buf;
|
||||
const size_t text_len = term->vimode.search.len;
|
||||
#endif
|
||||
|
||||
/* Calculate the width of each character */
|
||||
|
|
@ -3769,21 +3805,15 @@ render_search_box(struct terminal *term)
|
|||
|
||||
const float scale = term->scale;
|
||||
xassert(scale >= 1.);
|
||||
const size_t margin = (size_t)roundf(3 * scale);
|
||||
|
||||
size_t width = term->width - 2 * margin;
|
||||
size_t height = min(
|
||||
term->height - 2 * margin,
|
||||
margin + 1 * term->cell_height + margin);
|
||||
const size_t width = roundf(scale * ceilf(term->width / scale));
|
||||
const size_t height =
|
||||
roundf(scale * ceilf(min(term->height, term->cell_height) / scale));
|
||||
|
||||
width = roundf(scale * ceilf((term->width - 2 * margin) / scale));
|
||||
height = roundf(scale * ceilf(height / scale));
|
||||
const size_t visible_width =
|
||||
min(term->width, wanted_visible_cells * term->cell_width);
|
||||
|
||||
size_t visible_width = min(
|
||||
term->width - 2 * margin,
|
||||
margin + wanted_visible_cells * term->cell_width + margin);
|
||||
|
||||
const size_t visible_cells = (visible_width - 2 * margin) / term->cell_width;
|
||||
const size_t visible_cells = (visible_width) / term->cell_width;
|
||||
size_t glyph_offset = term->render.search_glyph_offset;
|
||||
|
||||
struct buffer_chain *chain = term->render.chains.search;
|
||||
|
|
@ -3794,52 +3824,46 @@ render_search_box(struct terminal *term)
|
|||
pixman_image_set_clip_region32(buf->pix[0], &clip);
|
||||
pixman_region32_fini(&clip);
|
||||
|
||||
#define WINDOW_X(x) (margin + x)
|
||||
#define WINDOW_Y(y) (term->height - margin - height + y)
|
||||
#define WINDOW_X(x) (x)
|
||||
#define WINDOW_Y(y) (term->height - height + y)
|
||||
|
||||
const bool is_match = term->search.match_len == text_len;
|
||||
const bool is_match = term->vimode.search.match_len == text_len;
|
||||
const bool custom_colors = is_match
|
||||
? term->conf->colors.use_custom.search_box_match
|
||||
: term->conf->colors.use_custom.search_box_no_match;
|
||||
|
||||
/* Background - yellow on empty/match, red on mismatch (default) */
|
||||
const bool gamma_correct = wayl_do_linear_blending(term->wl, term->conf);
|
||||
const pixman_color_t color = color_hex_to_pixman(
|
||||
const pixman_color_t bg = color_hex_to_pixman(
|
||||
is_match
|
||||
? (custom_colors
|
||||
? term->conf->colors.search_box.match.bg
|
||||
: term->colors.table[3])
|
||||
: term->colors.bg)
|
||||
: (custom_colors
|
||||
? term->conf->colors.search_box.no_match.bg
|
||||
: term->colors.table[1]),
|
||||
: term->colors.bg),
|
||||
gamma_correct);
|
||||
|
||||
pixman_image_fill_rectangles(
|
||||
PIXMAN_OP_SRC, buf->pix[0], &color,
|
||||
1, &(pixman_rectangle16_t){width - visible_width, 0, visible_width, height});
|
||||
|
||||
pixman_color_t transparent = color_hex_to_pixman_with_alpha(0, 0, gamma_correct);
|
||||
pixman_image_fill_rectangles(
|
||||
PIXMAN_OP_SRC, buf->pix[0], &transparent,
|
||||
1, &(pixman_rectangle16_t){0, 0, width - visible_width, height});
|
||||
PIXMAN_OP_SRC, buf->pix[0], &bg, 1,
|
||||
&(pixman_rectangle16_t){0, 0, width, height});
|
||||
|
||||
struct fcft_font *font = term->fonts[0];
|
||||
const int x_left = width - visible_width + margin;
|
||||
const int x_ofs = term->font_x_ofs;
|
||||
int x = x_left;
|
||||
int y = margin;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
pixman_color_t fg = color_hex_to_pixman(
|
||||
custom_colors
|
||||
? (is_match
|
||||
? term->conf->colors.search_box.match.fg
|
||||
: term->conf->colors.search_box.no_match.fg)
|
||||
: term->colors.table[0],
|
||||
: term->colors.table[244],
|
||||
gamma_correct);
|
||||
|
||||
/* Move offset we start rendering at, to ensure the cursor is visible */
|
||||
for (size_t i = 0, cell_idx = 0; i <= term->search.cursor; cell_idx += widths[i], i++) {
|
||||
if (i != term->search.cursor)
|
||||
for (size_t i = 0, cell_idx = 0; i <= term->vimode.search.cursor; cell_idx += widths[i], i++) {
|
||||
if (i != term->vimode.search.cursor)
|
||||
continue;
|
||||
|
||||
#if (FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||
|
|
@ -3905,7 +3929,8 @@ render_search_box(struct terminal *term)
|
|||
{
|
||||
/* Convert subsurface coordinates to window coordinates*/
|
||||
/* Render cursor */
|
||||
if (i == term->search.cursor) {
|
||||
bool const cursor_cell = i == term->vimode.search.cursor;
|
||||
if (cursor_cell) {
|
||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||
bool have_preedit =
|
||||
ime_seat != NULL && ime_seat->ime.preedit.cells != NULL;
|
||||
|
|
@ -3933,8 +3958,7 @@ render_search_box(struct terminal *term)
|
|||
|
||||
/* Bar-styled cursor, if in the visible area */
|
||||
if (start >= 0 && start <= visible_cells) {
|
||||
draw_beam_cursor(
|
||||
term, buf->pix[0], font, &fg,
|
||||
render_search_box_cursor(term, buf->pix[0], fg,
|
||||
x + start * term->cell_width, y);
|
||||
}
|
||||
|
||||
|
|
@ -3966,7 +3990,7 @@ render_search_box(struct terminal *term)
|
|||
/* Cursor *should* be in the visible area */
|
||||
xassert(cell_idx >= glyph_offset);
|
||||
xassert(cell_idx <= glyph_offset + visible_cells);
|
||||
draw_beam_cursor(term, buf->pix[0], font, &fg, x, y);
|
||||
render_search_box_cursor(term, buf->pix[0], fg, x, y);
|
||||
term_ime_set_cursor_rect(
|
||||
term, WINDOW_X(x), WINDOW_Y(y), 1, term->cell_height);
|
||||
}
|
||||
|
|
@ -4002,7 +4026,8 @@ render_search_box(struct terminal *term)
|
|||
? width * term->cell_width
|
||||
: (width - 1) * term->cell_width)
|
||||
: 0; /* Not a zero-width character - no additional offset */
|
||||
pixman_image_t *src = pixman_image_create_solid_fill(&fg);
|
||||
pixman_color_t color = cursor_cell ? bg : fg;
|
||||
pixman_image_t *src = pixman_image_create_solid_fill(&color);
|
||||
pixman_image_composite32(
|
||||
PIXMAN_OP_OVER, src, glyph->pix, buf->pix[0], 0, 0, 0, 0,
|
||||
x + x_ofs + combining_ofs + glyph->x,
|
||||
|
|
@ -4020,8 +4045,8 @@ render_search_box(struct terminal *term)
|
|||
/* Already rendered */;
|
||||
else
|
||||
#endif
|
||||
if (term->search.cursor >= term->search.len) {
|
||||
draw_beam_cursor(term, buf->pix[0], font, &fg, x, y);
|
||||
if (term->vimode.search.cursor >= term->vimode.search.len) {
|
||||
render_search_box_cursor(term, buf->pix[0], fg, x, y);
|
||||
term_ime_set_cursor_rect(
|
||||
term, WINDOW_X(x), WINDOW_Y(y), 1, term->cell_height);
|
||||
}
|
||||
|
|
@ -4031,8 +4056,8 @@ render_search_box(struct terminal *term)
|
|||
/* TODO: this is only necessary on a window resize */
|
||||
wl_subsurface_set_position(
|
||||
term->window->search.sub,
|
||||
roundf(margin / scale),
|
||||
roundf(max(0, (int32_t)term->height - height - margin) / scale));
|
||||
0,
|
||||
roundf(max(0, (int32_t)term->height - height) / scale));
|
||||
|
||||
wayl_surface_scale(term->window, &term->window->search.surface, buf, scale);
|
||||
wl_surface_attach(term->window->search.surface.surf, buf->wl_buf, 0, 0);
|
||||
|
|
@ -4040,7 +4065,7 @@ render_search_box(struct terminal *term)
|
|||
|
||||
struct wl_region *region = wl_compositor_create_region(term->wl->compositor);
|
||||
if (region != NULL) {
|
||||
wl_region_add(region, width - visible_width, 0, visible_width, height);
|
||||
wl_region_add(region, 0, 0, width, height);
|
||||
wl_surface_set_opaque_region(term->window->search.surface.surf, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
|
@ -4310,14 +4335,14 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
|
|||
wl_callback_destroy(wl_callback);
|
||||
term->window->frame_callback = NULL;
|
||||
|
||||
bool grid = term->render.pending.grid;
|
||||
bool csd = term->render.pending.csd;
|
||||
bool search = term->is_searching && term->render.pending.search;
|
||||
bool urls = urls_mode_is_active(term) > 0 && term->render.pending.urls;
|
||||
bool const grid = term->render.pending.grid;
|
||||
bool const csd = term->render.pending.csd;
|
||||
bool const search_box = term->render.pending.vimode_search_box;
|
||||
bool const urls = urls_mode_is_active(term) > 0 && term->render.pending.urls;
|
||||
|
||||
term->render.pending.grid = false;
|
||||
term->render.pending.csd = false;
|
||||
term->render.pending.search = false;
|
||||
term->render.pending.vimode_search_box = false;
|
||||
term->render.pending.urls = false;
|
||||
|
||||
struct grid *original_grid = term->grid;
|
||||
|
|
@ -4332,13 +4357,13 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
|
|||
quirk_weston_csd_off(term);
|
||||
}
|
||||
|
||||
if (search)
|
||||
if (search_box)
|
||||
render_search_box(term);
|
||||
|
||||
if (urls)
|
||||
render_urls(term);
|
||||
|
||||
if ((grid && !term->delayed_render_timer.is_armed) || (csd | search | urls))
|
||||
if ((grid && !term->delayed_render_timer.is_armed) || (csd | search_box | urls))
|
||||
grid_render(term);
|
||||
|
||||
tll_foreach(term->wl->seats, it) {
|
||||
|
|
@ -4984,7 +5009,7 @@ damage_view:
|
|||
term->render.last_buf = NULL;
|
||||
term_damage_view(term);
|
||||
render_refresh_csd(term);
|
||||
render_refresh_search(term);
|
||||
render_refresh_vimode_search_box(term);
|
||||
render_refresh(term);
|
||||
|
||||
return true;
|
||||
|
|
@ -5129,20 +5154,20 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data)
|
|||
if (unlikely(term->shutdown.in_progress || !term->window->is_configured))
|
||||
continue;
|
||||
|
||||
bool grid = term->render.refresh.grid;
|
||||
bool csd = term->render.refresh.csd;
|
||||
bool search = term->is_searching && term->render.refresh.search;
|
||||
bool urls = urls_mode_is_active(term) && term->render.refresh.urls;
|
||||
bool const grid = term->render.refresh.grid;
|
||||
bool const csd = term->render.refresh.csd;
|
||||
bool const search_box = term->render.refresh.vimode_search_box;
|
||||
bool const urls = urls_mode_is_active(term) && term->render.refresh.urls;
|
||||
|
||||
if (!(grid | csd | search | urls))
|
||||
if (!(grid | csd | search_box | urls))
|
||||
continue;
|
||||
|
||||
if (term->render.app_sync_updates.enabled && !(csd | search | urls))
|
||||
if (term->render.app_sync_updates.enabled && !(csd | search_box | urls))
|
||||
continue;
|
||||
|
||||
term->render.refresh.grid = false;
|
||||
term->render.refresh.csd = false;
|
||||
term->render.refresh.search = false;
|
||||
term->render.refresh.vimode_search_box = false;
|
||||
term->render.refresh.urls = false;
|
||||
|
||||
if (term->window->frame_callback == NULL) {
|
||||
|
|
@ -5157,11 +5182,11 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data)
|
|||
render_csd(term);
|
||||
quirk_weston_csd_off(term);
|
||||
}
|
||||
if (search)
|
||||
if (search_box)
|
||||
render_search_box(term);
|
||||
if (urls)
|
||||
render_urls(term);
|
||||
if (grid | csd | search | urls)
|
||||
if (grid | csd | search_box | urls)
|
||||
grid_render(term);
|
||||
|
||||
tll_foreach(term->wl->seats, it) {
|
||||
|
|
@ -5174,7 +5199,7 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data)
|
|||
/* Tells the frame callback to render again */
|
||||
term->render.pending.grid |= grid;
|
||||
term->render.pending.csd |= csd;
|
||||
term->render.pending.search |= search;
|
||||
term->render.pending.vimode_search_box |= search_box;
|
||||
term->render.pending.urls |= urls;
|
||||
}
|
||||
}
|
||||
|
|
@ -5292,11 +5317,13 @@ render_refresh_csd(struct terminal *term)
|
|||
term->render.refresh.csd = true;
|
||||
}
|
||||
|
||||
// TODO (kociap): Rename to something more indicative, e.g.
|
||||
// render_refresh_vimode_search_box_search_box
|
||||
void
|
||||
render_refresh_search(struct terminal *term)
|
||||
render_refresh_vimode_search_box(struct terminal *term)
|
||||
{
|
||||
if (term->is_searching)
|
||||
term->render.refresh.search = true;
|
||||
if (term->is_vimming && term->vimode.is_searching)
|
||||
term->render.refresh.vimode_search_box = true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
2
render.h
2
render.h
|
|
@ -24,7 +24,7 @@ void render_refresh(struct terminal *term);
|
|||
void render_refresh_app_id(struct terminal *term);
|
||||
void render_refresh_icon(struct terminal *term);
|
||||
void render_refresh_csd(struct terminal *term);
|
||||
void render_refresh_search(struct terminal *term);
|
||||
void render_refresh_vimode_search_box(struct terminal *term);
|
||||
void render_refresh_title(struct terminal *term);
|
||||
void render_refresh_urls(struct terminal *term);
|
||||
bool render_xcursor_set(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "grid.h"
|
||||
#include "misc.h"
|
||||
#include "render.h"
|
||||
#include "search.h"
|
||||
#include "vimode.h"
|
||||
#include "uri.h"
|
||||
#include "util.h"
|
||||
#include "vt.h"
|
||||
|
|
@ -1615,8 +1615,6 @@ selection_cancel(struct terminal *term)
|
|||
term->selection.pivot.end = (struct coord){-1, -1};
|
||||
term->selection.direction = SELECTION_UNDIR;
|
||||
term->selection.ongoing = false;
|
||||
|
||||
search_selection_cancelled(term);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
25
terminal.c
25
terminal.c
|
|
@ -46,6 +46,7 @@
|
|||
#include "vt.h"
|
||||
#include "xmalloc.h"
|
||||
#include "xsnprintf.h"
|
||||
#include "vimode.h"
|
||||
|
||||
#define PTMX_TIMING 0
|
||||
|
||||
|
|
@ -1886,8 +1887,9 @@ term_destroy(struct terminal *term)
|
|||
free_custom_glyphs(
|
||||
&term->custom_glyphs.octants, GLYPH_OCTANTS_COUNT);
|
||||
|
||||
free(term->search.buf);
|
||||
free(term->search.last.buf);
|
||||
// TODO (kociap): Free the vimode search buffers.
|
||||
// free(term->search.buf);
|
||||
// free(term->search.last.buf);
|
||||
|
||||
if (term->render.workers.threads != NULL) {
|
||||
for (size_t i = 0; i < term->render.workers.count; i++) {
|
||||
|
|
@ -2477,6 +2479,18 @@ term_font_baseline(const struct terminal *term)
|
|||
return term->font_y_ofs + line_height - glyph_top_y - font->descent;
|
||||
}
|
||||
|
||||
void
|
||||
term_damage_cell_in_view(struct terminal* const term, int const row, int const col)
|
||||
{
|
||||
if(col >= term->grid->num_cols || col < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct row* const r = grid_row_in_view(term->grid, row);
|
||||
r->dirty = true;
|
||||
r->cells[col].attrs.clean = 0;
|
||||
}
|
||||
|
||||
void
|
||||
term_damage_rows(struct terminal *term, int start, int end)
|
||||
{
|
||||
|
|
@ -3056,6 +3070,7 @@ selection_on_bottom_region(const struct terminal *term,
|
|||
void
|
||||
term_scroll_partial(struct terminal *term, struct scroll_region region, int rows)
|
||||
{
|
||||
printf("SCROLL PARTIAL [rows=%d, region.start=%d, region.end=%d]\n", rows, region.start, region.end);
|
||||
LOG_DBG("scroll: rows=%d, region.start=%d, region.end=%d",
|
||||
rows, region.start, region.end);
|
||||
|
||||
|
|
@ -3113,6 +3128,7 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
|||
}
|
||||
|
||||
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||
vimode_view_down(term, rows);
|
||||
|
||||
#if defined(_DEBUG)
|
||||
for (int r = 0; r < term->rows; r++)
|
||||
|
|
@ -3798,8 +3814,8 @@ term_enable_app_sync_updates(struct terminal *term)
|
|||
|
||||
/* Disable pending refresh *iff* the grid is the *only* thing
|
||||
* scheduled to be re-rendered */
|
||||
if (!term->render.refresh.csd && !term->render.refresh.search &&
|
||||
!term->render.pending.csd && !term->render.pending.search)
|
||||
if (!term->render.refresh.csd && !term->render.refresh.vimode_search_box &&
|
||||
!term->render.pending.csd && !term->render.pending.vimode_search_box)
|
||||
{
|
||||
term->render.refresh.grid = false;
|
||||
term->render.pending.grid = false;
|
||||
|
|
@ -3960,6 +3976,7 @@ term_fill(struct terminal *term, int r, int c, uint8_t data, size_t count,
|
|||
void
|
||||
term_print(struct terminal *term, char32_t wc, int width, bool insert_mode_disable)
|
||||
{
|
||||
printf("TERM PRINT\n");
|
||||
xassert(width > 0);
|
||||
|
||||
struct grid *grid = term->grid;
|
||||
|
|
|
|||
46
terminal.h
46
terminal.h
|
|
@ -374,11 +374,19 @@ enum term_surface {
|
|||
|
||||
enum overlay_style {
|
||||
OVERLAY_NONE,
|
||||
// TODO (kociap): rename to OVERLAY_VIMODE
|
||||
OVERLAY_SEARCH,
|
||||
OVERLAY_FLASH,
|
||||
OVERLAY_UNICODE_MODE,
|
||||
};
|
||||
|
||||
enum vi_mode {
|
||||
VI_MODE_NORMAL,
|
||||
VI_MODE_VISUAL,
|
||||
VI_MODE_VLINE,
|
||||
VI_MODE_VBLOCK,
|
||||
};
|
||||
|
||||
typedef tll(struct ptmx_buffer) ptmx_buffer_list_t;
|
||||
|
||||
enum url_action { URL_ACTION_COPY, URL_ACTION_LAUNCH, URL_ACTION_PERSISTENT };
|
||||
|
|
@ -621,23 +629,34 @@ struct terminal {
|
|||
} auto_scroll;
|
||||
} selection;
|
||||
|
||||
bool is_searching;
|
||||
bool is_vimming;
|
||||
struct {
|
||||
char32_t *buf;
|
||||
size_t len;
|
||||
size_t sz;
|
||||
size_t cursor;
|
||||
enum vi_mode mode;
|
||||
struct coord cursor;
|
||||
bool is_searching;
|
||||
|
||||
int original_view;
|
||||
bool view_followed_offset;
|
||||
struct coord match;
|
||||
size_t match_len;
|
||||
struct {
|
||||
struct coord start;
|
||||
} selection;
|
||||
|
||||
struct vimode_search {
|
||||
char32_t *buf;
|
||||
size_t len;
|
||||
size_t sz;
|
||||
size_t cursor;
|
||||
|
||||
enum search_direction direction;
|
||||
int original_view;
|
||||
struct coord match;
|
||||
size_t match_len;
|
||||
} search;
|
||||
|
||||
struct {
|
||||
char32_t *buf;
|
||||
size_t len;
|
||||
} last;
|
||||
} search;
|
||||
enum search_direction direction;
|
||||
} confirmed_search;
|
||||
} vimode;
|
||||
|
||||
struct wayland *wl;
|
||||
struct wl_window *window;
|
||||
|
|
@ -660,7 +679,7 @@ struct terminal {
|
|||
struct {
|
||||
bool grid;
|
||||
bool csd;
|
||||
bool search;
|
||||
bool vimode_search_box;
|
||||
bool urls;
|
||||
} refresh;
|
||||
|
||||
|
|
@ -668,7 +687,7 @@ struct terminal {
|
|||
struct {
|
||||
bool grid;
|
||||
bool csd;
|
||||
bool search;
|
||||
bool vimode_search_box;
|
||||
bool urls;
|
||||
} pending;
|
||||
|
||||
|
|
@ -878,6 +897,7 @@ int term_pt_or_px_as_pixels(
|
|||
|
||||
void term_window_configured(struct terminal *term);
|
||||
|
||||
void term_damage_cell_in_view(struct terminal* term, int row, int col);
|
||||
void term_damage_rows(struct terminal *term, int start, int end);
|
||||
void term_damage_rows_in_view(struct terminal *term, int start, int end);
|
||||
|
||||
|
|
|
|||
|
|
@ -1165,22 +1165,22 @@ test_section_key_bindings_collisions(void)
|
|||
}
|
||||
|
||||
static void
|
||||
test_section_search_bindings(void)
|
||||
test_section_vimode_bindings(void)
|
||||
{
|
||||
struct config conf = {0};
|
||||
struct context ctx = {
|
||||
.conf = &conf, .section = "search-bindings", .path = "unittest"};
|
||||
.conf = &conf, .section = "vimode-bindings", .path = "unittest"};
|
||||
|
||||
test_invalid_key(&ctx, &parse_section_search_bindings, "invalid-key");
|
||||
test_invalid_key(&ctx, &parse_section_vimode_bindings, "invalid-key");
|
||||
|
||||
for (int action = 0; action < BIND_ACTION_SEARCH_COUNT; action++) {
|
||||
if (search_binding_action_map[action] == NULL)
|
||||
for (int action = 0; action < BIND_ACTION_VIMODE_COUNT; action++) {
|
||||
if (vimode_binding_action_map[action] == NULL)
|
||||
continue;
|
||||
|
||||
test_key_binding(
|
||||
&ctx, &parse_section_search_bindings,
|
||||
action, BIND_ACTION_SEARCH_COUNT - 1,
|
||||
search_binding_action_map, &conf.bindings.search, KEY_BINDING,
|
||||
&ctx, &parse_section_vimode_bindings,
|
||||
action, BIND_ACTION_VIMODE_COUNT - 1,
|
||||
vimode_binding_action_map, &conf.bindings.vimode, KEY_BINDING,
|
||||
false, false);
|
||||
}
|
||||
|
||||
|
|
@ -1188,15 +1188,52 @@ test_section_search_bindings(void)
|
|||
}
|
||||
|
||||
static void
|
||||
test_section_search_bindings_collisions(void)
|
||||
test_section_vimode_search_bindings(void)
|
||||
{
|
||||
struct config conf = {0};
|
||||
struct context ctx = {
|
||||
.conf = &conf, .section = "search-bindings", .path = "unittest"};
|
||||
.conf = &conf, .section = "vimode-search-bindings", .path = "unittest"};
|
||||
|
||||
test_invalid_key(&ctx, &parse_section_vimode_search_bindings, "invalid-key");
|
||||
|
||||
for (int action = 0; action < BIND_ACTION_VIMODE_COUNT; action++) {
|
||||
if (vimode_search_binding_action_map[action] == NULL)
|
||||
continue;
|
||||
|
||||
test_key_binding(
|
||||
&ctx, &parse_section_vimode_search_bindings,
|
||||
action, BIND_ACTION_VIMODE_COUNT - 1,
|
||||
vimode_search_binding_action_map, &conf.bindings.vimode_search, KEY_BINDING,
|
||||
false, false);
|
||||
}
|
||||
|
||||
config_free(&conf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_section_vimode_bindings_collisions(void)
|
||||
{
|
||||
struct config conf = {0};
|
||||
struct context ctx = {
|
||||
.conf = &conf, .section = "vimode-bindings", .path = "unittest"};
|
||||
|
||||
test_binding_collisions(
|
||||
&ctx,
|
||||
BIND_ACTION_SEARCH_COUNT - 1, search_binding_action_map, KEY_BINDING);
|
||||
BIND_ACTION_VIMODE_COUNT - 1, vimode_binding_action_map, KEY_BINDING);
|
||||
|
||||
config_free(&conf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_section_vimode_search_bindings_collisions(void)
|
||||
{
|
||||
struct config conf = {0};
|
||||
struct context ctx = {
|
||||
.conf = &conf, .section = "vimode-search-bindings", .path = "unittest"};
|
||||
|
||||
test_binding_collisions(
|
||||
&ctx,
|
||||
BIND_ACTION_VIMODE_COUNT - 1, vimode_search_binding_action_map, KEY_BINDING);
|
||||
|
||||
config_free(&conf);
|
||||
}
|
||||
|
|
@ -1448,8 +1485,10 @@ main(int argc, const char *const *argv)
|
|||
test_section_csd();
|
||||
test_section_key_bindings();
|
||||
test_section_key_bindings_collisions();
|
||||
test_section_search_bindings();
|
||||
test_section_search_bindings_collisions();
|
||||
test_section_vimode_bindings();
|
||||
test_section_vimode_search_bindings();
|
||||
test_section_vimode_bindings_collisions();
|
||||
test_section_vimode_search_bindings_collisions();
|
||||
test_section_url_bindings();
|
||||
test_section_url_bindings_collisions();
|
||||
test_section_mouse_bindings();
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@ unicode_mode_updated(struct terminal *term)
|
|||
{
|
||||
if (term == NULL)
|
||||
return;
|
||||
|
||||
if (term->is_searching)
|
||||
render_refresh_search(term);
|
||||
printf("UNICODE UPDATE\n");
|
||||
if (term->is_vimming)
|
||||
// TODO (kociap): refresh
|
||||
// render_refresh_search(term);
|
||||
(void)0;
|
||||
else
|
||||
render_refresh(term);
|
||||
}
|
||||
|
|
@ -44,6 +46,7 @@ void
|
|||
unicode_mode_input(struct seat *seat, struct terminal *term,
|
||||
xkb_keysym_t sym)
|
||||
{
|
||||
printf("UNICODE INPUT\n");
|
||||
if (sym == XKB_KEY_Return ||
|
||||
sym == XKB_KEY_space ||
|
||||
sym == XKB_KEY_KP_Enter ||
|
||||
|
|
@ -57,8 +60,10 @@ unicode_mode_input(struct seat *seat, struct terminal *term,
|
|||
term->unicode_mode.character, (int)chars, utf8);
|
||||
|
||||
if (chars != (size_t)-1) {
|
||||
if (term->is_searching)
|
||||
search_add_chars(term, utf8, chars);
|
||||
if (term->is_vimming)
|
||||
// TODO (kociap): input
|
||||
// search_add_chars(term, utf8, chars);
|
||||
(void)0;
|
||||
else
|
||||
term_to_slave(term, utf8, chars);
|
||||
}
|
||||
|
|
|
|||
33
vimode.h
Normal file
33
vimode.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "key-binding.h"
|
||||
#include "terminal.h"
|
||||
|
||||
void vimode_begin(struct terminal *term);
|
||||
|
||||
/* vimode_search_begin
|
||||
*
|
||||
* Enter search mode directly without needing to interact with the
|
||||
* vimode first. Enters vimode as well.
|
||||
*/
|
||||
void vimode_search_begin(struct terminal *term);
|
||||
|
||||
void vimode_cancel(struct terminal *term);
|
||||
void vimode_input(struct seat *seat, struct terminal *term,
|
||||
const struct key_binding_set *bindings, uint32_t key,
|
||||
xkb_keysym_t sym, xkb_mod_mask_t mods,
|
||||
xkb_mod_mask_t consumed, const xkb_keysym_t *raw_syms,
|
||||
size_t raw_count, uint32_t serial);
|
||||
// void search_add_chars(struct terminal *term, const char *text, size_t len);
|
||||
|
||||
struct search_match_iterator {
|
||||
struct terminal *term;
|
||||
struct coord start;
|
||||
};
|
||||
|
||||
struct search_match_iterator search_matches_new_iter(struct terminal *term);
|
||||
struct range search_matches_next(struct search_match_iterator *iter);
|
||||
|
||||
void vimode_view_down(struct terminal *term, int delta);
|
||||
Loading…
Add table
Add a link
Reference in a new issue