diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f16b6420..d61ec442 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,6 +12,7 @@ * Add `TreatJongseongAsChoseong` addon * Add `FlexibleComposeOrder` addon [#318](https://github.com/Riey/kime/issues/318) * Check LANG env in kime-check [#317](https://github.com/Riey/kime/issues/317) +* Add `Commit` hotkey, `ConsumeIfProcessed` hotkey result [#315](https://github.com/Riey/kime/issues/315) ## 1.1.3 diff --git a/docs/CONFIGURATION.ko.md b/docs/CONFIGURATION.ko.md index cb7721d2..febe47c0 100644 --- a/docs/CONFIGURATION.ko.md +++ b/docs/CONFIGURATION.ko.md @@ -71,6 +71,10 @@ Super-Space: 한글모드로 바꿉니다 +##### Commit + +현재 조합상태를 종료하고 커밋합니다 + #### result ##### Bypass @@ -81,6 +85,10 @@ Super-Space: 키 처리를 종료합니다 +##### ConsumeIfProcessed + +단축키가 실행됐을 경우에는 Consume처럼, 아닐때는 Bypass처럼 동작합니다. + ## xim_preedit_font XIM에서 쓸 편집창 글꼴과 크기입니다. diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index b3b1722d..1a421df8 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -59,6 +59,10 @@ Set english mode Set hangul mode +##### Commit + +End current preedit state then commit + #### result ##### Bypass @@ -69,6 +73,10 @@ Bypass key to continue key process Consume key to end key process +##### ConsumeIfProcessed + +When hotkey processed it act like Consume otherwise it act like Bypass + ### default ```yaml diff --git a/src/engine/core/src/config.rs b/src/engine/core/src/config.rs index 18c72873..e6342e0b 100644 --- a/src/engine/core/src/config.rs +++ b/src/engine/core/src/config.rs @@ -26,12 +26,14 @@ pub enum HotkeyBehavior { ToggleHangul, ToHangul, ToEnglish, + Commit, } #[derive(Serialize, Deserialize, Clone, Copy, Debug)] pub enum HotkeyResult { Consume, Bypass, + ConsumeIfProcessed, } #[derive(Serialize, Deserialize, Clone, Copy, Debug)] diff --git a/src/engine/core/src/lib.rs b/src/engine/core/src/lib.rs index a4032da7..2f810633 100644 --- a/src/engine/core/src/lib.rs +++ b/src/engine/core/src/lib.rs @@ -8,10 +8,9 @@ use ahash::AHashMap; use std::io::Read; use self::characters::KeyValue; -use self::config::{HotkeyBehavior, HotkeyResult}; use self::state::HangulState; -pub use self::config::{Addon, Config, RawConfig}; +pub use self::config::{Addon, Config, Hotkey, HotkeyBehavior, HotkeyResult, RawConfig}; pub use self::input_result::InputResult; pub use self::keycode::{Key, KeyCode, ModifierState}; @@ -100,27 +99,49 @@ impl InputEngine { pub fn press_key(&mut self, key: Key, config: &Config) -> InputResult { if let Some(hotkey) = config.hotkeys.get(&key) { - let first = self.enable_hangul; + let mut processed = false; + let mut ret = InputResult::empty(); match hotkey.behavior() { HotkeyBehavior::ToEnglish => { - self.enable_hangul = false; + if self.enable_hangul { + self.enable_hangul = false; + ret |= InputResult::LANGUAGE_CHANGED; + processed = true; + } } HotkeyBehavior::ToHangul => { - self.enable_hangul = true; + if !self.enable_hangul { + self.enable_hangul = true; + ret |= InputResult::LANGUAGE_CHANGED; + processed = true; + } } HotkeyBehavior::ToggleHangul => { self.enable_hangul = !self.enable_hangul; + ret |= InputResult::LANGUAGE_CHANGED; + processed = true; + } + HotkeyBehavior::Commit => { + if self + .state + .preedit_result() + .contains(InputResult::HAS_PREEDIT) + { + self.state.clear_preedit(); + ret |= InputResult::NEED_RESET; + processed = true; + } } } - let mut ret = match hotkey.result() { - HotkeyResult::Bypass => self.bypass(), - HotkeyResult::Consume => InputResult::CONSUMED | self.state.preedit_result(), - }; - - if self.enable_hangul != first { - ret.insert(InputResult::LANGUAGE_CHANGED); + match (hotkey.result(), processed) { + (HotkeyResult::Bypass, _) | (HotkeyResult::ConsumeIfProcessed, false) => { + ret |= self.bypass(); + } + (HotkeyResult::Consume, _) | (HotkeyResult::ConsumeIfProcessed, true) => { + ret |= InputResult::CONSUMED | self.state.preedit_result(); + } } ret diff --git a/src/engine/core/tests/dubeolsik.rs b/src/engine/core/tests/dubeolsik.rs index 5bf24966..7cc3373b 100644 --- a/src/engine/core/tests/dubeolsik.rs +++ b/src/engine/core/tests/dubeolsik.rs @@ -1,5 +1,9 @@ +use std::collections::BTreeMap; + use enumset::EnumSet; -use kime_engine_core::{Addon, Config, InputEngine, InputResult, Key, KeyCode::*, RawConfig}; +use kime_engine_core::{ + Addon, Config, Hotkey, InputEngine, InputResult, Key, KeyCode::*, RawConfig, +}; fn default_config() -> Config { Config::from_raw_config( @@ -22,6 +26,17 @@ fn addon_config(addon: EnumSet) -> Config { ) } +fn hotkey_config(hotkeys: BTreeMap) -> Config { + Config::from_raw_config( + RawConfig { + layout: "dubeolsik".into(), + hotkeys, + ..Default::default() + }, + None, + ) +} + #[track_caller] fn test_input_impl(config: &Config, word_commit: bool, keys: &[(Key, &str, &str)]) { let mut engine = InputEngine::new(word_commit); @@ -67,6 +82,11 @@ fn test_input_with_addon(keys: &[(Key, &str, &str)], addon: EnumSet) { test_input_impl(&addon_config(addon), false, keys); } +#[track_caller] +fn test_input_with_hotkey(keys: &[(Key, &str, &str)], hotkeys: BTreeMap) { + test_input_impl(&hotkey_config(hotkeys), false, keys); +} + #[track_caller] fn test_word_input(keys: &[(Key, &str, &str)]) { test_input_impl(&default_config(), true, keys); @@ -80,6 +100,29 @@ fn flexible_compose_order_addon() { ); } +#[test] +fn space_commit() { + test_input_with_hotkey( + &[ + (Key::normal(R), "ㄱ", ""), + (Key::normal(K), "가", ""), + (Key::normal(Space), "", "가"), + (Key::normal(S), "ㄴ", ""), + (Key::normal(K), "나", ""), + (Key::normal(Space), "", "나"), + (Key::normal(Space), "", "PASS"), + ], + std::iter::once(( + Key::normal(Space), + Hotkey::new( + kime_engine_core::HotkeyBehavior::Commit, + kime_engine_core::HotkeyResult::ConsumeIfProcessed, + ), + )) + .collect(), + ) +} + #[test] fn word_hello() { test_word_input(&[