diff --git a/README.md b/README.md index 6e4b56dc..8dc982d2 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ preference settings. - HanYu PinYin - Taiwan Huayu Luomapinyin - MPS2 Pinyin + - Colemak - Colemak-DH ANSI - Colemak-DH Ortholinear diff --git a/capi/src/io.rs b/capi/src/io.rs index b1c6be48..07d7e688 100644 --- a/capi/src/io.rs +++ b/capi/src/io.rs @@ -556,6 +556,7 @@ pub unsafe extern "C" fn chewing_config_set_str( KB::ThlPinyin => (AnyKeyboardLayout::qwerty(), Box::new(Pinyin::thl())), KB::Mps2Pinyin => (AnyKeyboardLayout::qwerty(), Box::new(Pinyin::mps2())), KB::Carpalx => (AnyKeyboardLayout::qwerty(), Box::new(Standard::new())), + KB::Colemak => (AnyKeyboardLayout::colemak(), Box::new(Standard::new())), KB::ColemakDhAnsi => ( AnyKeyboardLayout::colemak_dh_ansi(), Box::new(Standard::new()), @@ -611,6 +612,7 @@ pub unsafe extern "C" fn chewing_set_KBType(ctx: *mut ChewingContext, kbtype: c_ KB::ThlPinyin => (AnyKeyboardLayout::qwerty(), Box::new(Pinyin::thl())), KB::Mps2Pinyin => (AnyKeyboardLayout::qwerty(), Box::new(Pinyin::mps2())), KB::Carpalx => (AnyKeyboardLayout::qwerty(), Box::new(Standard::new())), + KB::Colemak => (AnyKeyboardLayout::colemak(), Box::new(Standard::new())), KB::ColemakDhAnsi => ( AnyKeyboardLayout::colemak_dh_ansi(), Box::new(Standard::new()), diff --git a/capi/src/lib.rs b/capi/src/lib.rs index 642a311a..90f6bb6c 100644 --- a/capi/src/lib.rs +++ b/capi/src/lib.rs @@ -318,6 +318,7 @@ pub mod layout { /// * KB_THL_PINYIN /// * KB_MPS2_PINYIN /// * KB_CARPALX + /// * KB_COLEMAK /// * KB_COLEMAK_DH_ANSI /// * KB_COLEMAK_DH_ORTH /// * KB_WORKMAN diff --git a/capi/src/public.rs b/capi/src/public.rs index e61f851e..00386591 100644 --- a/capi/src/public.rs +++ b/capi/src/public.rs @@ -113,6 +113,7 @@ pub enum KB { ThlPinyin, Mps2Pinyin, Carpalx, + Colemak, ColemakDhAnsi, ColemakDhOrth, Workman, diff --git a/doc/libchewing.texi b/doc/libchewing.texi index fdad08c3..49fb2572 100644 --- a/doc/libchewing.texi +++ b/doc/libchewing.texi @@ -470,6 +470,7 @@ The string @var{str} might be one of the following layouts: @item @code{KB_THL_PINYIN} @item @code{KB_MPS2_PINYIN} @item @code{KB_CARPALX} +@item @code{KB_COLEMAK} @item @code{KB_COLEMAK_DH_ANSI} @item @code{KB_COLEMAK_DH_ORTH} @end itemize diff --git a/include/chewing.h b/include/chewing.h index ca374e1f..0c2b8261 100644 --- a/include/chewing.h +++ b/include/chewing.h @@ -172,6 +172,7 @@ typedef enum KB { KB_THL_PINYIN, KB_MPS2_PINYIN, KB_CARPALX, + KB_COLEMAK, KB_COLEMAK_DH_ANSI, KB_COLEMAK_DH_ORTH, KB_WORKMAN, diff --git a/src/editor/keyboard/colemak.rs b/src/editor/keyboard/colemak.rs new file mode 100644 index 00000000..71246d98 --- /dev/null +++ b/src/editor/keyboard/colemak.rs @@ -0,0 +1,48 @@ +use super::{ + generic_map_keycode, + KeyCode::{self, *}, + KeyEvent, KeyboardLayout, Modifiers, MATRIX_SIZE, +}; + +/// A Colemak keyboard. +#[derive(Debug)] +pub struct Colemak; + +#[rustfmt::skip] +static KEYCODE_INDEX: [KeyCode; MATRIX_SIZE] = [ + Unknown, + N1, N2, N3, N4, N5, N6, N7, N8, N9, N0, Minus, Equal, BSlash, Grave, + Q, W, F, P, G, J, L, U, Y, SColon, LBracket, RBracket, + A, R, S, T, D, H, N, E, I, O, Quote, + Z, X, C, V, B, K, M, Comma, Dot, Slash, Space, + Esc, Enter, Del, Backspace, Tab, Left, Right, Up, Down, Home, End, + PageUp, PageDown, NumLock, +]; + +#[rustfmt::skip] +static UNICODE_MAP: [char; MATRIX_SIZE] = [ + '�', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\\', '`', + 'q', 'w', 'f', 'p', 'g', 'j', 'l', 'u', 'y', ';', '[', ']', + 'a', 'r', 's', 't', 'd', 'h', 'n', 'e', 'i', 'o', '\'', + 'z', 'x', 'c', 'v', 'b', 'k', 'm', ',', '.', '/', ' ', + '�', '�', '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', +]; + +#[rustfmt::skip] +static SHIFT_MAP: [char; MATRIX_SIZE] = [ + '�', + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '|', '~', + 'Q', 'W', 'F', 'P', 'G', 'J', 'L', 'U', 'Y', ':', '{', '}', + 'A', 'R', 'S', 'T', 'D', 'H', 'N', 'E', 'I', 'O', '"', + 'Z', 'X', 'C', 'V', 'B', 'K', 'M', '<', '>', '?', ' ', + '�', '�', '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', +]; + +impl KeyboardLayout for Colemak { + fn map_with_mod(&self, keycode: KeyCode, modifiers: Modifiers) -> KeyEvent { + generic_map_keycode(&KEYCODE_INDEX, &UNICODE_MAP, &SHIFT_MAP, keycode, modifiers) + } +} diff --git a/src/editor/keyboard/mod.rs b/src/editor/keyboard/mod.rs index b6d3cddd..cdd6bdda 100644 --- a/src/editor/keyboard/mod.rs +++ b/src/editor/keyboard/mod.rs @@ -5,6 +5,7 @@ //! to map different English layouts to layout independent key indexes that can be //! used to drive the phonetic conversion engines. +mod colemak; mod colemak_dh_ansi; mod colemak_dh_orth; mod dvorak; @@ -15,6 +16,7 @@ mod workman; use core::fmt; +pub use colemak::Colemak; pub use colemak_dh_ansi::ColemakDhAnsi; pub use colemak_dh_orth::ColemakDhOrth; pub use dvorak::Dvorak; @@ -139,6 +141,7 @@ pub enum AnyKeyboardLayout { Dvorak(Dvorak), DvorakOnQwerty(DvorakOnQwerty), Qgmlwy(Qgmlwy), + Colemak(Colemak), ColemakDhAnsi(ColemakDhAnsi), ColemakDhOrth(ColemakDhOrth), Workman(Workman), @@ -157,6 +160,9 @@ impl AnyKeyboardLayout { pub fn qgmlwy() -> AnyKeyboardLayout { AnyKeyboardLayout::Qgmlwy(Qgmlwy) } + pub fn colemak() -> AnyKeyboardLayout { + AnyKeyboardLayout::Colemak(Colemak) + } pub fn colemak_dh_ansi() -> AnyKeyboardLayout { AnyKeyboardLayout::ColemakDhAnsi(ColemakDhAnsi) } @@ -175,6 +181,7 @@ impl KeyboardLayout for AnyKeyboardLayout { AnyKeyboardLayout::Dvorak(kb) => kb.map_with_mod(keycode, modifiers), AnyKeyboardLayout::DvorakOnQwerty(kb) => kb.map_with_mod(keycode, modifiers), AnyKeyboardLayout::Qgmlwy(kb) => kb.map_with_mod(keycode, modifiers), + AnyKeyboardLayout::Colemak(kb) => kb.map_with_mod(keycode, modifiers), AnyKeyboardLayout::ColemakDhAnsi(kb) => kb.map_with_mod(keycode, modifiers), AnyKeyboardLayout::ColemakDhOrth(kb) => kb.map_with_mod(keycode, modifiers), AnyKeyboardLayout::Workman(kb) => kb.map_with_mod(keycode, modifiers), diff --git a/src/editor/zhuyin_layout/mod.rs b/src/editor/zhuyin_layout/mod.rs index b820b883..97fb3470 100644 --- a/src/editor/zhuyin_layout/mod.rs +++ b/src/editor/zhuyin_layout/mod.rs @@ -75,6 +75,8 @@ pub enum KeyboardLayoutCompat { /// TODO: docs Carpalx, /// TODO: docs + Colemak, + /// TODO: docs ColemakDhAnsi, /// TODO: docs ColemakDhOrth, @@ -109,6 +111,7 @@ impl FromStr for KeyboardLayoutCompat { "KB_THL_PINYIN" => Self::ThlPinyin, "KB_MPS2_PINYIN" => Self::Mps2Pinyin, "KB_CARPALX" => Self::Carpalx, + "KB_COLEMAK" => Self::Colemak, "KB_COLEMAK_DH_ANSI" => Self::ColemakDhAnsi, "KB_COLEMAK_DH_ORTH" => Self::ColemakDhOrth, "KB_WORKMAN" => Self::Workman, @@ -134,6 +137,7 @@ impl Display for KeyboardLayoutCompat { KeyboardLayoutCompat::ThlPinyin => f.write_str("KB_THL_PINYIN"), KeyboardLayoutCompat::Mps2Pinyin => f.write_str("KB_MPS2_PINYIN"), KeyboardLayoutCompat::Carpalx => f.write_str("KB_CARPALX"), + KeyboardLayoutCompat::Colemak => f.write_str("KB_COLEMAK"), KeyboardLayoutCompat::ColemakDhAnsi => f.write_str("KB_COLEMAK_DH_ANSI"), KeyboardLayoutCompat::ColemakDhOrth => f.write_str("KB_COLEMAK_DH_ORTH"), KeyboardLayoutCompat::Workman => f.write_str("KB_WORKMAN"), @@ -162,6 +166,7 @@ impl TryFrom for KeyboardLayoutCompat { 13 => Self::ColemakDhAnsi, 14 => Self::ColemakDhOrth, 15 => Self::Workman, + 16 => Self::Colemak, _ => return Err(()), }) } diff --git a/tests/test-bopomofo.c b/tests/test-bopomofo.c index b6968ee7..8156c52e 100644 --- a/tests/test-bopomofo.c +++ b/tests/test-bopomofo.c @@ -2261,6 +2261,22 @@ void test_KB_DVORAK_HSU() chewing_delete(ctx); } +void test_KB_COLEMAK() +{ + ChewingContext *ctx; + + ctx = chewing_new(); + start_testcase(ctx, fd); + + chewing_set_KBType(ctx, KB_COLEMAK); + type_keystroke_by_string(ctx, "vl; sn4l; 5; 2e7c;31o4"); + ok_preedit_buffer(ctx, "\xE6\x96\xB0\xE9\x85\xB7\xE9\x9F\xB3\xE7\x9C\x9F\xE7\x9A\x84\xE5\xBE\x88\xE6\xA3\x92" + /* 新酷音真的很棒 */ ); + chewing_clean_preedit_buf(ctx); + + chewing_delete(ctx); +} + void test_KB_COLEMAK_DH_ANSI() { ChewingContext *ctx; @@ -2307,6 +2323,7 @@ void test_KB() test_KB_DACHEN_CP26(); test_KB_DVORAK(); test_KB_DVORAK_HSU(); + test_KB_COLEMAK(); test_KB_COLEMAK_DH_ANSI(); test_KB_COLEMAK_DH_ORTH(); diff --git a/tests/test-keyboard.c b/tests/test-keyboard.c index d84f520f..42c8bafc 100644 --- a/tests/test-keyboard.c +++ b/tests/test-keyboard.c @@ -35,7 +35,8 @@ static const char *const KEYBOARD_STRING[] = { "KB_CARPALX", "KB_COLEMAK_DH_ANSI", "KB_COLEMAK_DH_ORTH", - "KB_WORKMAN" + "KB_WORKMAN", + "KB_COLEMAK" }; static const int KEYBOARD_DEFAULT_TYPE = 0;