From 6e1756541b197661af6e2602da051a6c401898b6 Mon Sep 17 00:00:00 2001 From: Slava Date: Tue, 22 Apr 2025 16:53:51 +0500 Subject: [PATCH 1/4] implement UNICODE_MODE_VIM --- data/constants/keycodes/keycodes_0.0.8.hjson | 0 .../keycodes/keycodes_0.0.8_quantum.hjson | 11 +++++++++++ docs/features/unicode.md | 14 +++++++++++++- docs/keycodes.md | 3 ++- keyboards/mlego/m65/m65.c | 3 +++ .../process_keycode/process_unicode_common.c | 3 +++ quantum/unicode/unicode.c | 18 ++++++++++++++++++ quantum/unicode/unicode.h | 1 + 8 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 data/constants/keycodes/keycodes_0.0.8.hjson create mode 100644 data/constants/keycodes/keycodes_0.0.8_quantum.hjson diff --git a/data/constants/keycodes/keycodes_0.0.8.hjson b/data/constants/keycodes/keycodes_0.0.8.hjson new file mode 100644 index 00000000000..e69de29bb2d diff --git a/data/constants/keycodes/keycodes_0.0.8_quantum.hjson b/data/constants/keycodes/keycodes_0.0.8_quantum.hjson new file mode 100644 index 00000000000..c9560628a15 --- /dev/null +++ b/data/constants/keycodes/keycodes_0.0.8_quantum.hjson @@ -0,0 +1,11 @@ +{ + "keycodes": { + "0x7C38": { + "group": "quantum", + "key": "QK_UNICODE_MODE_VIM", + "aliases": [ + "UC_VIM" + ] + } + } +} diff --git a/docs/features/unicode.md b/docs/features/unicode.md index 7ed178c30d7..0ff370feba9 100644 --- a/docs/features/unicode.md +++ b/docs/features/unicode.md @@ -42,6 +42,8 @@ Add the following to your `config.h`: |`UNICODE_SONG_BSD` |*n/a* |The song to play when the BSD input mode is selected | |`UNICODE_SONG_WIN` |*n/a* |The song to play when the Windows input mode is selected | |`UNICODE_SONG_WINC`|*n/a* |The song to play when the WinCompose input mode is selected| +|`UNICODE_SONG_EMACS`|*n/a* |The song to play when the Emacs input mode is selected | +|`UNICODE_SONG_VIM` |*n/a* |The song to play when the Vim input mode is selected | ## Input Subsystems {#input-subsystems} @@ -201,6 +203,12 @@ Emacs supports code point input with the `insert-char` command. Not currently implemented. If you're a BSD user and want to contribute support for this input mode, please [feel free](../contributing)! +==== VIM + +**Mode Name:** `UNICODE_MODE_VIM` + +Vim supports input of unicode characters up to `U+FFFF`. To insert a unicode character, press `ctrl+v u` in insert mode. For more informaton, see `:h utf-8-typing`. + ::::: ## Keycodes {#keycodes} @@ -217,7 +225,8 @@ Not currently implemented. If you're a BSD user and want to contribute support f |`QK_UNICODE_MODE_WINDOWS` |`UC_WIN` |Switch to Windows input | |`QK_UNICODE_MODE_BSD` |`UC_BSD` |Switch to BSD input (not implemented) | |`QK_UNICODE_MODE_WINCOMPOSE`|`UC_WINC`|Switch to Windows input using WinCompose | -|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to emacs (`C-x-8 RET`) | +|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to emacs input (`C-x-8 RET`) | +|`QK_UNICODE_MODE_VIM` |`UC_VIM`|Switch to vim input (`CTRL-V u`) | ## API {#api} @@ -285,6 +294,7 @@ Begin the Unicode input sequence. The exact behavior depends on the currently se - **WinCompose**: Tap `UNICODE_KEY_WINC`, then U - **HexNumpad**: Hold Left Alt, then tap Numpad + - **Emacs**: Tap Ctrl+X, then 8, then Enter + - **Vim**: Tap Ctrl+V, then u This function is weakly defined, and can be overridden in user code. @@ -299,6 +309,7 @@ Complete the Unicode input sequence. The exact behavior depends on the currently - **WinCompose**: Tap Enter - **HexNumpad**: Release Left Alt - **Emacs**: Tap Enter + - **Vim**: Do nothing This function is weakly defined, and can be overridden in user code. @@ -313,6 +324,7 @@ Cancel the Unicode input sequence. The exact behavior depends on the currently s - **WinCompose**: Tap Escape - **HexNumpad**: Release Left Alt - **Emacs**: Tap Ctrl+G + - **Vim**: Do nothing This function is weakly defined, and can be overridden in user code. diff --git a/docs/keycodes.md b/docs/keycodes.md index cf170721c81..82333fe596b 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -902,4 +902,5 @@ See also: [Unicode Support](features/unicode) |`QK_UNICODE_MODE_WINDOWS` |`UC_WIN` |Switch to Windows input | |`QK_UNICODE_MODE_BSD` |`UC_BSD` |Switch to BSD input (not implemented) | |`QK_UNICODE_MODE_WINCOMPOSE`|`UC_WINC`|Switch to Windows input using WinCompose | -|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to emacs (`C-x-8 RET`) | +|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to Emacs input (`C-x-8 RET`) | +|`QK_UNICODE_MODE_VIM` |`UC_VIM` |Switch to Vim input (`i_CTRL-V u`) | diff --git a/keyboards/mlego/m65/m65.c b/keyboards/mlego/m65/m65.c index fd9ee5b9471..39592e2025e 100644 --- a/keyboards/mlego/m65/m65.c +++ b/keyboards/mlego/m65/m65.c @@ -120,6 +120,9 @@ void user_oled_magic(void) { case UNICODE_MODE_EMACS: oled_write_P(PSTR("emacs"), false); break; + case UNICODE_MODE_VIM: + oled_write_P(PSTR("vim"), false); + break; default: oled_write_ln_P(PSTR("not supported"), false); } diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index f43770977aa..98f53440f34 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c @@ -64,6 +64,9 @@ bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { case QK_UNICODE_MODE_EMACS: set_unicode_input_mode(UNICODE_MODE_EMACS); break; + case QK_UNICODE_MODE_VIM: + set_unicode_input_mode(UNICODE_MODE_VIM); + break; } } diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c index dff1d43fb41..9a50abdb944 100644 --- a/quantum/unicode/unicode.c +++ b/quantum/unicode/unicode.c @@ -97,6 +97,9 @@ static float song_winc[][2] = UNICODE_SONG_WINC; # ifdef UNICODE_SONG_EMACS static float song_emacs[][2] = UNICODE_SONG_EMACS; # endif +# ifdef UNICODE_SONG_VIM +static float song_vim[][2] = UNICODE_SONG_VIM; +# endif static void unicode_play_song(uint8_t mode) { switch (mode) { @@ -129,6 +132,11 @@ static void unicode_play_song(uint8_t mode) { case UNICODE_MODE_EMACS: PLAY_SONG(song_emacs); break; +# endif +# ifdef UNICODE_SONG_VIM + case UNICODE_MODE_VIM: + PLAY_SONG(song_vim); + break; # endif } } @@ -248,6 +256,10 @@ __attribute__((weak)) void unicode_input_start(void) { tap_code16(KC_8); tap_code16(KC_ENTER); break; + case UNICODE_MODE_VIM: + tap_code16(LCTL(KC_V)); + tap_code16(KC_U); + break; } wait_ms(UNICODE_TYPE_DELAY); @@ -276,6 +288,9 @@ __attribute__((weak)) void unicode_input_finish(void) { case UNICODE_MODE_EMACS: tap_code16(KC_ENTER); break; + case UNICODE_MODE_VIM: + // It finishes by itself when 4 hex digits received + break; } set_mods(unicode_saved_mods); // Reregister previously set mods @@ -304,6 +319,9 @@ __attribute__((weak)) void unicode_input_cancel(void) { case UNICODE_MODE_EMACS: tap_code16(LCTL(KC_G)); // C-g cancels break; + case UNICODE_MODE_VIM: + // It looks like there is no way to cancel + break; } set_mods(unicode_saved_mods); // Reregister previously set mods diff --git a/quantum/unicode/unicode.h b/quantum/unicode/unicode.h index 7cddc78b7a1..4eb128ef3e0 100644 --- a/quantum/unicode/unicode.h +++ b/quantum/unicode/unicode.h @@ -46,6 +46,7 @@ enum unicode_input_modes { UNICODE_MODE_BSD, // BSD (not implemented) UNICODE_MODE_WINCOMPOSE, // Windows using WinCompose (https://github.com/samhocevar/wincompose) UNICODE_MODE_EMACS, // Emacs is an operating system in search of a good text editor + UNICODE_MODE_VIM, // Vim or Neovim UNICODE_MODE_COUNT // Number of available input modes (always leave at the end) }; From 11848645609a6ffca0075b18459a00c2d2aae629 Mon Sep 17 00:00:00 2001 From: Slava Date: Fri, 16 May 2025 18:20:49 +0500 Subject: [PATCH 2/4] regen keycodes --- quantum/keycodes.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/quantum/keycodes.h b/quantum/keycodes.h index 6a59aa376d0..93feb9215e9 100644 --- a/quantum/keycodes.h +++ b/quantum/keycodes.h @@ -26,11 +26,11 @@ #pragma once // clang-format off -#define QMK_KEYCODES_VERSION "0.0.7" -#define QMK_KEYCODES_VERSION_BCD 0x00000007 +#define QMK_KEYCODES_VERSION "0.0.8" +#define QMK_KEYCODES_VERSION_BCD 0x00000008 #define QMK_KEYCODES_VERSION_MAJOR 0 #define QMK_KEYCODES_VERSION_MINOR 0 -#define QMK_KEYCODES_VERSION_PATCH 7 +#define QMK_KEYCODES_VERSION_PATCH 8 enum qk_keycode_ranges { // Ranges @@ -725,6 +725,7 @@ enum qk_keycode_defines { QK_UNICODE_MODE_BSD = 0x7C35, QK_UNICODE_MODE_WINCOMPOSE = 0x7C36, QK_UNICODE_MODE_EMACS = 0x7C37, + QK_UNICODE_MODE_VIM = 0x7C38, QK_HAPTIC_ON = 0x7C40, QK_HAPTIC_OFF = 0x7C41, QK_HAPTIC_TOGGLE = 0x7C42, @@ -1413,6 +1414,7 @@ enum qk_keycode_defines { UC_BSD = QK_UNICODE_MODE_BSD, UC_WINC = QK_UNICODE_MODE_WINCOMPOSE, UC_EMAC = QK_UNICODE_MODE_EMACS, + UC_VIM = QK_UNICODE_MODE_VIM, HF_ON = QK_HAPTIC_ON, HF_OFF = QK_HAPTIC_OFF, HF_TOGG = QK_HAPTIC_TOGGLE, From fc09ffb34a6272eaaa572c8609ad3ff61c4191dc Mon Sep 17 00:00:00 2001 From: Slava Date: Mon, 19 May 2025 17:22:06 +0500 Subject: [PATCH 3/4] UNICODE_MODE_VIM: switch from `i_CTRL-V u` to `i_CTRL-V U` --- docs/features/unicode.md | 8 ++++---- docs/keycodes.md | 2 +- quantum/unicode/unicode.c | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/features/unicode.md b/docs/features/unicode.md index 0ff370feba9..e28db9c564b 100644 --- a/docs/features/unicode.md +++ b/docs/features/unicode.md @@ -207,7 +207,7 @@ Not currently implemented. If you're a BSD user and want to contribute support f **Mode Name:** `UNICODE_MODE_VIM` -Vim supports input of unicode characters up to `U+FFFF`. To insert a unicode character, press `ctrl+v u` in insert mode. For more informaton, see `:h utf-8-typing`. +Vim supports input of all the unicode characters. For more information check `:h i_CTRL-V_digit`. In Vim unicode mode, keyboard sends `ctrl+v`, `shift+u`, and then digits of the unicode point. ::::: @@ -225,8 +225,8 @@ Vim supports input of unicode characters up to `U+FFFF`. To insert a unicode cha |`QK_UNICODE_MODE_WINDOWS` |`UC_WIN` |Switch to Windows input | |`QK_UNICODE_MODE_BSD` |`UC_BSD` |Switch to BSD input (not implemented) | |`QK_UNICODE_MODE_WINCOMPOSE`|`UC_WINC`|Switch to Windows input using WinCompose | -|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to emacs input (`C-x-8 RET`) | -|`QK_UNICODE_MODE_VIM` |`UC_VIM`|Switch to vim input (`CTRL-V u`) | +|`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to Emacs input (`C-x-8 RET`) | +|`QK_UNICODE_MODE_VIM` |`UC_VIM`|Switch to Vim input (`CTRL-V U`) | ## API {#api} @@ -294,7 +294,7 @@ Begin the Unicode input sequence. The exact behavior depends on the currently se - **WinCompose**: Tap `UNICODE_KEY_WINC`, then U - **HexNumpad**: Hold Left Alt, then tap Numpad + - **Emacs**: Tap Ctrl+X, then 8, then Enter - - **Vim**: Tap Ctrl+V, then u + - **Vim**: Tap Ctrl+V, then Shift+U This function is weakly defined, and can be overridden in user code. diff --git a/docs/keycodes.md b/docs/keycodes.md index 82333fe596b..def002f9c10 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -903,4 +903,4 @@ See also: [Unicode Support](features/unicode) |`QK_UNICODE_MODE_BSD` |`UC_BSD` |Switch to BSD input (not implemented) | |`QK_UNICODE_MODE_WINCOMPOSE`|`UC_WINC`|Switch to Windows input using WinCompose | |`QK_UNICODE_MODE_EMACS` |`UC_EMAC`|Switch to Emacs input (`C-x-8 RET`) | -|`QK_UNICODE_MODE_VIM` |`UC_VIM` |Switch to Vim input (`i_CTRL-V u`) | +|`QK_UNICODE_MODE_VIM` |`UC_VIM` |Switch to Vim input (`i_CTRL-V U`) | diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c index 9a50abdb944..a1407099838 100644 --- a/quantum/unicode/unicode.c +++ b/quantum/unicode/unicode.c @@ -258,7 +258,7 @@ __attribute__((weak)) void unicode_input_start(void) { break; case UNICODE_MODE_VIM: tap_code16(LCTL(KC_V)); - tap_code16(KC_U); + tap_code16(LSFT(KC_U)); break; } @@ -289,7 +289,7 @@ __attribute__((weak)) void unicode_input_finish(void) { tap_code16(KC_ENTER); break; case UNICODE_MODE_VIM: - // It finishes by itself when 4 hex digits received + // It finishes by itself when enough hex digits received break; } @@ -350,6 +350,16 @@ void register_hex(uint16_t hex) { } void register_hex32(uint32_t hex) { + // In vim, `i_CTRL-V U` waits for exactly 8 digits, so we send them all + // @see `:h i_CTRL-V_digit` + if (unicode_config.input_mode == UNICODE_MODE_VIM) { + for (int i = 7; i >= 0; i--) { + uint8_t digit = ((hex >> (i * 4)) & 0xF); + send_nibble(digit); + } + return; + } + bool first_digit = true; bool needs_leading_zero = (unicode_config.input_mode == UNICODE_MODE_WINCOMPOSE); for (int i = 7; i >= 0; i--) { From 6fcc2ba9218837db30e4f94db305e8b53e5b1f20 Mon Sep 17 00:00:00 2001 From: Slava Date: Tue, 20 May 2025 13:50:08 +0500 Subject: [PATCH 4/4] UNICODE_MODE_VIM: a bit less code, a bit more cpu usage All the loop is reused now, and there is no duplicated code But we have one extra check for each of 4 first digits, that is 4 checks for a character In previous version there was only 1 check for each unicode character. --- quantum/unicode/unicode.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c index a1407099838..f7f84842d03 100644 --- a/quantum/unicode/unicode.c +++ b/quantum/unicode/unicode.c @@ -350,16 +350,6 @@ void register_hex(uint16_t hex) { } void register_hex32(uint32_t hex) { - // In vim, `i_CTRL-V U` waits for exactly 8 digits, so we send them all - // @see `:h i_CTRL-V_digit` - if (unicode_config.input_mode == UNICODE_MODE_VIM) { - for (int i = 7; i >= 0; i--) { - uint8_t digit = ((hex >> (i * 4)) & 0xF); - send_nibble(digit); - } - return; - } - bool first_digit = true; bool needs_leading_zero = (unicode_config.input_mode == UNICODE_MODE_WINCOMPOSE); for (int i = 7; i >= 0; i--) { @@ -372,9 +362,13 @@ void register_hex32(uint32_t hex) { send_nibble_wrapper(0); } - // Always send digits (including zero) if we're down to the last - // two bytes of nibbles. - bool must_send = i < 4; + bool must_send = + // Always send digits (including zero) if we're down to the last + // two bytes of nibbles. + (i < 4) + // In vim, `i_CTRL-V U` waits for exactly 8 digits, so we send them all + // @see `:h i_CTRL-V_digit` + || (unicode_config.input_mode == UNICODE_MODE_VIM); // If we've found a digit worth transmitting, do so. if (digit != 0 || !first_digit || must_send) {