mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
input: add new Unicode input mode
This mode is activated through the new key-bindings.unicode-input and search-bindings.unicode-input key bindings. When active, the user can “build” a Unicode codepoint by typing its hexadecimal value. Note that there’s no visual feedback in this mode. This is intentional. This mode is intended to be a fallback for users that don’t use an IME. Closes #1116
This commit is contained in:
parent
fa2d9f8699
commit
8967dd9cfe
11 changed files with 167 additions and 2 deletions
|
|
@ -52,11 +52,16 @@
|
|||
`ctrl`+`shift`+`x` respectively ([#30][30]).
|
||||
* `colors.search-box-no-match` and `colors.search-box-match` options
|
||||
to `foot.ini` ([#1112][1112]).
|
||||
* Very basic Unicode input mode via the new
|
||||
`key-bindings.unicode-input` and `search-bindings.unicode-input` key
|
||||
bindings. Note that there is no visual feedback, as the preferred
|
||||
way of entering Unicode characters is with an IME ([#1116][1116]).
|
||||
|
||||
[1058]: https://codeberg.org/dnkl/foot/issues/1058
|
||||
[1070]: https://codeberg.org/dnkl/foot/issues/1070
|
||||
[30]: https://codeberg.org/dnkl/foot/issues/30
|
||||
[1112]: https://codeberg.org/dnkl/foot/issues/1112
|
||||
[1116]: https://codeberg.org/dnkl/foot/issues/1116
|
||||
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
2
config.c
2
config.c
|
|
@ -117,6 +117,7 @@ static const char *const binding_action_map[] = {
|
|||
[BIND_ACTION_TEXT_BINDING] = "text-binding",
|
||||
[BIND_ACTION_PROMPT_PREV] = "prompt-prev",
|
||||
[BIND_ACTION_PROMPT_NEXT] = "prompt-next",
|
||||
[BIND_ACTION_UNICODE_INPUT] = "unicode-input",
|
||||
|
||||
/* Mouse-specific actions */
|
||||
[BIND_ACTION_SELECT_BEGIN] = "select-begin",
|
||||
|
|
@ -148,6 +149,7 @@ static const char *const search_binding_action_map[] = {
|
|||
[BIND_ACTION_SEARCH_EXTEND_WORD_WS] = "extend-to-next-whitespace",
|
||||
[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 url_binding_action_map[] = {
|
||||
|
|
|
|||
|
|
@ -791,6 +791,32 @@ e.g. *search-start=none*.
|
|||
Jump the next prompt (requires shell integration, see
|
||||
*foot*(1)). Default: _Control+Shift+x_.
|
||||
|
||||
*unicode-input*
|
||||
Input a Unicode character by typing its codepoint in hexadecimal,
|
||||
followed by *Enter* or *Space*.
|
||||
|
||||
For example, to input the character _ö_ (LATIN SMALL LETTER O WITH
|
||||
DIAERESIS, Unicode codepoint 0xf6), you would first activate this
|
||||
key binding, then type: *f*, *6*, *Enter*.
|
||||
|
||||
Another example: to input 😍 (SMILING FACE WITH HEART-SHAPED EYES,
|
||||
Unicode codepoint 0x1f60d), activate this key binding, then type:
|
||||
*1*, *f*, *6*, *0*, *d*, *Enter*.
|
||||
|
||||
Recognized key bindings in Unicode input mode:
|
||||
|
||||
- Enter, Space: commit the Unicode character, then exit this mode.
|
||||
- Escape, Ctrl+c, Ctrl+d, Ctrl+g: abort input, then exit this mode.
|
||||
- 0-9, a-f: append next digit to the Unicode's codepoint.
|
||||
- Backspace: undo the last digit.
|
||||
|
||||
Note that there is no visual feedback while in this mode. This is
|
||||
by design; foot's Unicode input mode is considered to be a
|
||||
fallback. The preferred way of entering Unicode characters, emojis
|
||||
etc is by using an IME.
|
||||
|
||||
Default: _none_.
|
||||
|
||||
# SECTION: search-bindings
|
||||
|
||||
This section lets you override the default key bindings used in
|
||||
|
|
@ -869,6 +895,10 @@ scrollback search mode. The syntax is exactly the same as the regular
|
|||
Paste from the _primary selection_ into the search
|
||||
buffer. Default: _Shift+Insert_.
|
||||
|
||||
*unicode-input*
|
||||
Unicode input mode. See _key-bindings.unicode-input_ for
|
||||
details. Default: _none_.
|
||||
|
||||
# SECTION: url-bindings
|
||||
|
||||
This section lets you override the default key bindings used in URL
|
||||
|
|
|
|||
2
foot.ini
2
foot.ini
|
|
@ -150,6 +150,7 @@
|
|||
# show-urls-persistent=none
|
||||
# prompt-prev=Control+Shift+z
|
||||
# prompt-next=Control+Shift+x
|
||||
# unicode-input=none
|
||||
# noop=none
|
||||
|
||||
[search-bindings]
|
||||
|
|
@ -171,6 +172,7 @@
|
|||
# extend-to-next-whitespace=Control+Shift+w
|
||||
# clipboard-paste=Control+v Control+Shift+v Control+y XF86Paste
|
||||
# primary-paste=Shift+Insert
|
||||
# unicode-input=none
|
||||
|
||||
[url-bindings]
|
||||
# cancel=Control+g Control+c Control+d Escape
|
||||
|
|
|
|||
69
input.c
69
input.c
|
|
@ -36,6 +36,7 @@
|
|||
#include "spawn.h"
|
||||
#include "terminal.h"
|
||||
#include "tokenize.h"
|
||||
#include "unicode-mode.h"
|
||||
#include "url-mode.h"
|
||||
#include "util.h"
|
||||
#include "vt.h"
|
||||
|
|
@ -416,6 +417,10 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
return true;
|
||||
}
|
||||
|
||||
case BIND_ACTION_UNICODE_INPUT:
|
||||
unicode_mode_activate(seat);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_SELECT_BEGIN:
|
||||
selection_start(
|
||||
term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false);
|
||||
|
|
@ -1405,7 +1410,69 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
xassert(bindings != NULL);
|
||||
|
||||
if (pressed) {
|
||||
if (term->is_searching) {
|
||||
if (seat->unicode_mode.active) {
|
||||
if (sym == XKB_KEY_Return ||
|
||||
sym == XKB_KEY_space ||
|
||||
sym == XKB_KEY_KP_Enter ||
|
||||
sym == XKB_KEY_KP_Space)
|
||||
{
|
||||
char utf8[MB_CUR_MAX];
|
||||
size_t chars = c32rtomb(
|
||||
utf8, seat->unicode_mode.character, &(mbstate_t){0});
|
||||
|
||||
LOG_DBG("Unicode input: 0x%06x -> %.*s",
|
||||
seat->unicode_mode.character, (int)chars, utf8);
|
||||
|
||||
if (chars != (size_t)-1) {
|
||||
if (term->is_searching)
|
||||
search_add_chars(term, utf8, chars);
|
||||
else
|
||||
term_to_slave(term, utf8, chars);
|
||||
}
|
||||
|
||||
unicode_mode_deactivate(seat);
|
||||
}
|
||||
|
||||
else if (sym == XKB_KEY_Escape ||
|
||||
(seat->kbd.ctrl && (sym == XKB_KEY_c ||
|
||||
sym == XKB_KEY_d ||
|
||||
sym == XKB_KEY_g)))
|
||||
{
|
||||
unicode_mode_deactivate(seat);
|
||||
}
|
||||
|
||||
else if (sym == XKB_KEY_BackSpace) {
|
||||
if (seat->unicode_mode.count > 0) {
|
||||
seat->unicode_mode.character >>= 4;
|
||||
seat->unicode_mode.count--;
|
||||
unicode_mode_updated(seat);
|
||||
}
|
||||
}
|
||||
|
||||
else if (seat->unicode_mode.count < 6) {
|
||||
int digit = -1;
|
||||
|
||||
/* 0-9, a-f, A-F */
|
||||
if (sym >= XKB_KEY_0 && sym <= XKB_KEY_9)
|
||||
digit = sym - XKB_KEY_0;
|
||||
else if (sym >= XKB_KEY_a && sym <= XKB_KEY_f)
|
||||
digit = 0xa + (sym - XKB_KEY_a);
|
||||
else if (sym >= XKB_KEY_A && sym <= XKB_KEY_F)
|
||||
digit = 0xa + (sym - XKB_KEY_A);
|
||||
|
||||
if (digit >= 0) {
|
||||
xassert(digit >= 0 && digit <= 0xf);
|
||||
seat->unicode_mode.character <<= 4;
|
||||
seat->unicode_mode.character |= digit;
|
||||
seat->unicode_mode.count++;
|
||||
unicode_mode_updated(seat);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
else if (term->is_searching) {
|
||||
if (should_repeat)
|
||||
start_repeater(seat, key);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ enum bind_action_normal {
|
|||
BIND_ACTION_TEXT_BINDING,
|
||||
BIND_ACTION_PROMPT_PREV,
|
||||
BIND_ACTION_PROMPT_NEXT,
|
||||
BIND_ACTION_UNICODE_INPUT,
|
||||
|
||||
/* Mouse specific actions - i.e. they require a mouse coordinate */
|
||||
BIND_ACTION_SELECT_BEGIN,
|
||||
|
|
@ -48,7 +49,7 @@ enum bind_action_normal {
|
|||
BIND_ACTION_SELECT_WORD_WS,
|
||||
BIND_ACTION_SELECT_ROW,
|
||||
|
||||
BIND_ACTION_KEY_COUNT = BIND_ACTION_PROMPT_NEXT + 1,
|
||||
BIND_ACTION_KEY_COUNT = BIND_ACTION_UNICODE_INPUT + 1,
|
||||
BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1,
|
||||
};
|
||||
|
||||
|
|
@ -72,6 +73,7 @@ enum bind_action_search {
|
|||
BIND_ACTION_SEARCH_EXTEND_WORD_WS,
|
||||
BIND_ACTION_SEARCH_CLIPBOARD_PASTE,
|
||||
BIND_ACTION_SEARCH_PRIMARY_PASTE,
|
||||
BIND_ACTION_SEARCH_UNICODE_INPUT,
|
||||
BIND_ACTION_SEARCH_COUNT,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ executable(
|
|||
'slave.c', 'slave.h',
|
||||
'spawn.c', 'spawn.h',
|
||||
'tokenize.c', 'tokenize.h',
|
||||
'unicode-mode.c', 'unicode-mode.h',
|
||||
'url-mode.c', 'url-mode.h',
|
||||
'user-notification.c', 'user-notification.h',
|
||||
'wayland.c', 'wayland.h', 'shm-formats.h',
|
||||
|
|
|
|||
5
search.c
5
search.c
|
|
@ -18,6 +18,7 @@
|
|||
#include "render.h"
|
||||
#include "selection.h"
|
||||
#include "shm.h"
|
||||
#include "unicode-mode.h"
|
||||
#include "util.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
|
|
@ -993,6 +994,10 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
*update_search_result = *redraw = true;
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_SEARCH_UNICODE_INPUT:
|
||||
unicode_mode_activate(seat);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_SEARCH_COUNT:
|
||||
BUG("Invalid action type");
|
||||
return true;
|
||||
|
|
|
|||
38
unicode-mode.c
Normal file
38
unicode-mode.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "unicode-mode.h"
|
||||
|
||||
#include "render.h"
|
||||
|
||||
void
|
||||
unicode_mode_activate(struct seat *seat)
|
||||
{
|
||||
if (seat->unicode_mode.active)
|
||||
return;
|
||||
|
||||
seat->unicode_mode.active = true;
|
||||
seat->unicode_mode.character = u'\0';
|
||||
seat->unicode_mode.count = 0;
|
||||
unicode_mode_updated(seat);
|
||||
}
|
||||
|
||||
void
|
||||
unicode_mode_deactivate(struct seat *seat)
|
||||
{
|
||||
if (!seat->unicode_mode.active)
|
||||
return;
|
||||
|
||||
seat->unicode_mode.active = false;
|
||||
unicode_mode_updated(seat);
|
||||
}
|
||||
|
||||
void
|
||||
unicode_mode_updated(struct seat *seat)
|
||||
{
|
||||
struct terminal *term = seat->kbd_focus;
|
||||
if (term == NULL)
|
||||
return;
|
||||
|
||||
if (term->is_searching)
|
||||
render_refresh_search(term);
|
||||
else
|
||||
render_refresh(term);
|
||||
}
|
||||
7
unicode-mode.h
Normal file
7
unicode-mode.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "wayland.h"
|
||||
|
||||
void unicode_mode_activate(struct seat *seat);
|
||||
void unicode_mode_deactivate(struct seat *seat);
|
||||
void unicode_mode_updated(struct seat *seat);
|
||||
|
|
@ -206,6 +206,12 @@ struct seat {
|
|||
uint32_t serial;
|
||||
} ime;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
bool active;
|
||||
int count;
|
||||
char32_t character;
|
||||
} unicode_mode;
|
||||
};
|
||||
|
||||
enum csd_surface {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue