mirror of
https://github.com/mii443/akaza.git
synced 2025-08-22 14:55:31 +00:00
keymap を別ファイルにうつした #155
This commit is contained in:
1
Makefile
1
Makefile
@ -3,5 +3,6 @@ DATADIR ?= $(PREFIX)/share
|
||||
|
||||
install:
|
||||
install -m 0644 -v -D -t $(DATADIR)/akaza/romkan romkan/*
|
||||
install -m 0644 -v -D -t $(DATADIR)/akaza/keymap keymap/*
|
||||
$(MAKE) -C ibus-akaza install
|
||||
|
||||
|
@ -11,3 +11,4 @@
|
||||
だくせい /諾成/
|
||||
とーかないず /トーカナイズ/
|
||||
いしのうえにもさんねん /石の上にも三年/
|
||||
かなにゅうりょく /かな入力/仮名入力/
|
||||
|
@ -10,6 +10,7 @@ exec 2>&1
|
||||
|
||||
export AKAZA_DATA_DIR="$BASEDIR/../akaza-data/data/"
|
||||
export AKAZA_ROMKAN_DIR="$BASEDIR/../romkan/"
|
||||
export AKAZA_KEYMAP_DIR="$BASEDIR/../keymap/"
|
||||
|
||||
export RUST_BACKTRACE=4
|
||||
|
||||
|
@ -42,6 +42,7 @@ use libakaza::engine::base::HenkanEngine;
|
||||
use libakaza::engine::bigram_word_viterbi_engine::BigramWordViterbiEngine;
|
||||
use libakaza::extend_clause::{extend_left, extend_right};
|
||||
use libakaza::graph::candidate::Candidate;
|
||||
use libakaza::keymap::KeyState;
|
||||
use libakaza::lm::system_bigram::MarisaSystemBigramLM;
|
||||
use libakaza::lm::system_unigram_lm::MarisaSystemUnigramLM;
|
||||
use libakaza::romkan::RomKanConverter;
|
||||
@ -53,16 +54,6 @@ use crate::input_mode::{
|
||||
};
|
||||
use crate::keymap::KeyMap;
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Copy, Clone)]
|
||||
pub enum KeyState {
|
||||
// 何も入力されていない状態。
|
||||
PreComposition,
|
||||
// 変換処理に入る前。ひらがなを入力している段階。
|
||||
Composition,
|
||||
// 変換中
|
||||
Conversion,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AkazaContext {
|
||||
pub(crate) input_mode: InputMode,
|
||||
@ -189,7 +180,7 @@ impl AkazaContext {
|
||||
is_invalidate: false,
|
||||
cursor_moved: false,
|
||||
node_selected: HashMap::new(),
|
||||
keymap: KeyMap::new(),
|
||||
keymap: KeyMap::new()?,
|
||||
force_selected_clause: Vec::new(),
|
||||
prop_list,
|
||||
input_mode_prop,
|
||||
|
@ -1,21 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CString;
|
||||
|
||||
use log::trace;
|
||||
use anyhow::bail;
|
||||
use log::{error, info, trace};
|
||||
|
||||
use ibus_sys::core::{IBusModifierType_IBUS_CONTROL_MASK, IBusModifierType_IBUS_SHIFT_MASK};
|
||||
use ibus_sys::ibus_key::{
|
||||
IBUS_KEY_BackSpace, IBUS_KEY_Down, IBUS_KEY_Escape, IBUS_KEY_Hangul, IBUS_KEY_Hangul_Hanja,
|
||||
IBUS_KEY_Henkan, IBUS_KEY_KP_Down, IBUS_KEY_KP_Enter, IBUS_KEY_KP_Left, IBUS_KEY_KP_Page_Down,
|
||||
IBUS_KEY_KP_Page_Up, IBUS_KEY_KP_Right, IBUS_KEY_KP_Up, IBUS_KEY_Left, IBUS_KEY_Muhenkan,
|
||||
IBUS_KEY_Page_Down, IBUS_KEY_Page_Up, IBUS_KEY_Return, IBUS_KEY_Right, IBUS_KEY_Up,
|
||||
IBUS_KEY_colon, IBUS_KEY_h, IBUS_KEY_j, IBUS_KEY_k, IBUS_KEY_l, IBUS_KEY_space, IBUS_KEY_0,
|
||||
IBUS_KEY_1, IBUS_KEY_2, IBUS_KEY_3, IBUS_KEY_4, IBUS_KEY_5, IBUS_KEY_6, IBUS_KEY_7, IBUS_KEY_8,
|
||||
IBUS_KEY_9, IBUS_KEY_F10, IBUS_KEY_F6, IBUS_KEY_F7, IBUS_KEY_F8, IBUS_KEY_F9, IBUS_KEY_KP_0,
|
||||
IBUS_KEY_KP_1, IBUS_KEY_KP_2, IBUS_KEY_KP_3, IBUS_KEY_KP_4, IBUS_KEY_KP_5, IBUS_KEY_KP_6,
|
||||
IBUS_KEY_KP_7, IBUS_KEY_KP_8, IBUS_KEY_KP_9,
|
||||
};
|
||||
|
||||
use crate::context::KeyState;
|
||||
use ibus_sys::glib::guint;
|
||||
use ibus_sys::ibus_key::IBUS_KEY_VoidSymbol;
|
||||
use ibus_sys::keys::ibus_keyval_from_name;
|
||||
use libakaza::keymap::{KeyState, Keymap};
|
||||
|
||||
#[derive(Hash, PartialEq)]
|
||||
struct KeyPattern {
|
||||
@ -36,255 +29,67 @@ impl KeyPattern {
|
||||
}
|
||||
}
|
||||
|
||||
struct KeyMapBuilder {
|
||||
keymap: HashMap<KeyPattern, String>,
|
||||
}
|
||||
|
||||
impl KeyMapBuilder {
|
||||
fn new() -> Self {
|
||||
KeyMapBuilder {
|
||||
keymap: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn insert(&mut self, key_states: &[KeyState], keyvals: &[u32], modifier: u32, func_name: &str) {
|
||||
trace!(
|
||||
"INSERT KEY: {:?} {:?} {:?} {:?}",
|
||||
key_states,
|
||||
keyvals,
|
||||
modifier,
|
||||
func_name
|
||||
);
|
||||
for key_state in key_states {
|
||||
for keyval in keyvals {
|
||||
self.keymap.insert(
|
||||
KeyPattern::new(*key_state, *keyval, modifier),
|
||||
func_name.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct KeyMap {
|
||||
keymap: HashMap<KeyPattern, String>,
|
||||
}
|
||||
|
||||
impl KeyMap {
|
||||
pub(crate) fn new() -> Self {
|
||||
let mut builder = KeyMapBuilder::new();
|
||||
/// - first: modifier
|
||||
/// - second: keyval
|
||||
/// ただし、keyval が不明なものの場合は IBUS_KEY_VoidSymbol になる。
|
||||
fn split_key(key: &str) -> anyhow::Result<(u32, u32)> {
|
||||
fn p(s: &str) -> guint {
|
||||
let cs = CString::new(s.to_string()).unwrap();
|
||||
unsafe { ibus_keyval_from_name(cs.as_ptr()) }
|
||||
}
|
||||
|
||||
let mut modifier = 0_u32;
|
||||
if key.contains('-') {
|
||||
let keys = key.split('-').collect::<Vec<_>>();
|
||||
for m in &keys[0..keys.len() - 1] {
|
||||
match *m {
|
||||
"C" => {
|
||||
modifier |= IBusModifierType_IBUS_CONTROL_MASK;
|
||||
}
|
||||
"S" => {
|
||||
modifier |= IBusModifierType_IBUS_SHIFT_MASK;
|
||||
}
|
||||
_ => {
|
||||
bail!("Unknown modifier in keymap: {}", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((modifier, p(keys[keys.len() - 1])))
|
||||
} else {
|
||||
Ok((0, p(key)))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new() -> anyhow::Result<Self> {
|
||||
// TODO use IBus.Hotkey
|
||||
|
||||
// 入力モードの切り替え
|
||||
builder.insert(
|
||||
&[
|
||||
KeyState::Composition,
|
||||
KeyState::PreComposition,
|
||||
KeyState::Conversion,
|
||||
],
|
||||
&[IBUS_KEY_j],
|
||||
IBusModifierType_IBUS_SHIFT_MASK | IBusModifierType_IBUS_CONTROL_MASK,
|
||||
"set_input_mode_hiragana",
|
||||
);
|
||||
builder.insert(
|
||||
&[
|
||||
KeyState::Composition,
|
||||
KeyState::PreComposition,
|
||||
KeyState::Conversion,
|
||||
],
|
||||
&[IBUS_KEY_Henkan, IBUS_KEY_Hangul],
|
||||
0,
|
||||
"set_input_mode_hiragana",
|
||||
);
|
||||
builder.insert(
|
||||
&[
|
||||
KeyState::Composition,
|
||||
KeyState::PreComposition,
|
||||
KeyState::Conversion,
|
||||
],
|
||||
&[IBUS_KEY_Muhenkan, IBUS_KEY_Hangul_Hanja],
|
||||
0,
|
||||
"set_input_mode_alnum",
|
||||
);
|
||||
builder.insert(
|
||||
&[
|
||||
KeyState::Composition,
|
||||
KeyState::PreComposition,
|
||||
KeyState::Conversion,
|
||||
],
|
||||
&[IBUS_KEY_colon],
|
||||
IBusModifierType_IBUS_SHIFT_MASK | IBusModifierType_IBUS_CONTROL_MASK,
|
||||
"set_input_mode_alnum",
|
||||
);
|
||||
builder.insert(
|
||||
&[
|
||||
KeyState::Composition,
|
||||
KeyState::PreComposition,
|
||||
KeyState::Conversion,
|
||||
],
|
||||
&[IBUS_KEY_l],
|
||||
IBusModifierType_IBUS_SHIFT_MASK | IBusModifierType_IBUS_CONTROL_MASK,
|
||||
"set_input_mode_fullwidth_alnum",
|
||||
);
|
||||
builder.insert(
|
||||
&[
|
||||
KeyState::Composition,
|
||||
KeyState::PreComposition,
|
||||
KeyState::Conversion,
|
||||
],
|
||||
&[IBUS_KEY_k],
|
||||
IBusModifierType_IBUS_SHIFT_MASK | IBusModifierType_IBUS_CONTROL_MASK,
|
||||
"set_input_mode_katakana",
|
||||
);
|
||||
let keymap = Keymap::load("default")?;
|
||||
let mut mapping: HashMap<KeyPattern, String> = HashMap::new();
|
||||
|
||||
// basic operations.
|
||||
builder.insert(
|
||||
&[KeyState::Composition],
|
||||
&[IBUS_KEY_space],
|
||||
0,
|
||||
"update_candidates",
|
||||
);
|
||||
builder.insert(&[KeyState::Conversion], &[IBUS_KEY_space], 0, "cursor_down");
|
||||
|
||||
builder.insert(
|
||||
&[KeyState::Conversion, KeyState::Composition],
|
||||
&[IBUS_KEY_BackSpace],
|
||||
0,
|
||||
"erase_character_before_cursor",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion, KeyState::Composition],
|
||||
&[IBUS_KEY_h],
|
||||
IBusModifierType_IBUS_CONTROL_MASK,
|
||||
"erase_character_before_cursor",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Return, IBUS_KEY_KP_Enter],
|
||||
0,
|
||||
"commit_candidate",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Composition],
|
||||
&[IBUS_KEY_Return, IBUS_KEY_KP_Enter],
|
||||
0,
|
||||
"commit_preedit",
|
||||
);
|
||||
|
||||
builder.insert(
|
||||
&[KeyState::Conversion, KeyState::Composition],
|
||||
&[IBUS_KEY_Escape],
|
||||
0,
|
||||
"escape",
|
||||
);
|
||||
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Up, IBUS_KEY_KP_Up],
|
||||
0,
|
||||
"cursor_up",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Down, IBUS_KEY_KP_Down],
|
||||
0,
|
||||
"cursor_down",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Right, IBUS_KEY_KP_Right],
|
||||
0,
|
||||
"cursor_right",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Left, IBUS_KEY_KP_Left],
|
||||
0,
|
||||
"cursor_left",
|
||||
);
|
||||
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Right, IBUS_KEY_KP_Right],
|
||||
IBusModifierType_IBUS_SHIFT_MASK,
|
||||
"extend_clause_right",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_Left, IBUS_KEY_KP_Left],
|
||||
IBusModifierType_IBUS_SHIFT_MASK,
|
||||
"extend_clause_left",
|
||||
);
|
||||
|
||||
// 後から文字タイプを指定する
|
||||
builder.insert(
|
||||
&[KeyState::Composition, KeyState::Conversion],
|
||||
&[IBUS_KEY_F6],
|
||||
0,
|
||||
"convert_to_full_hiragana",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Composition, KeyState::Conversion],
|
||||
&[IBUS_KEY_F7],
|
||||
0,
|
||||
"convert_to_full_katakana",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Composition, KeyState::Conversion],
|
||||
&[IBUS_KEY_F8],
|
||||
0,
|
||||
"convert_to_half_katakana",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Composition, KeyState::Conversion],
|
||||
&[IBUS_KEY_F9],
|
||||
0,
|
||||
"convert_to_full_romaji",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Composition, KeyState::Conversion],
|
||||
&[IBUS_KEY_F10],
|
||||
0,
|
||||
"convert_to_half_romaji",
|
||||
);
|
||||
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_KP_Page_Up, IBUS_KEY_Page_Up],
|
||||
0,
|
||||
"page_up",
|
||||
);
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
&[IBUS_KEY_KP_Page_Down, IBUS_KEY_Page_Down],
|
||||
0,
|
||||
"page_down",
|
||||
);
|
||||
|
||||
let mut num = |keyvals: &[u32], n: i32| {
|
||||
// fn insert(&mut self, key_states: &[KeyState], keyvals: &[u32], modifier: u32, func_name: &str) {
|
||||
builder.insert(
|
||||
&[KeyState::Conversion],
|
||||
keyvals,
|
||||
0,
|
||||
format!("press_number_{}", n).as_str(),
|
||||
)
|
||||
};
|
||||
num(&[IBUS_KEY_1, IBUS_KEY_KP_1], 1);
|
||||
num(&[IBUS_KEY_2, IBUS_KEY_KP_2], 2);
|
||||
num(&[IBUS_KEY_3, IBUS_KEY_KP_3], 3);
|
||||
num(&[IBUS_KEY_4, IBUS_KEY_KP_4], 4);
|
||||
num(&[IBUS_KEY_5, IBUS_KEY_KP_5], 5);
|
||||
num(&[IBUS_KEY_6, IBUS_KEY_KP_6], 6);
|
||||
num(&[IBUS_KEY_7, IBUS_KEY_KP_7], 7);
|
||||
num(&[IBUS_KEY_8, IBUS_KEY_KP_8], 8);
|
||||
num(&[IBUS_KEY_9, IBUS_KEY_KP_9], 9);
|
||||
num(&[IBUS_KEY_0, IBUS_KEY_KP_0], 0);
|
||||
|
||||
KeyMap {
|
||||
keymap: builder.keymap,
|
||||
for kc in keymap.keys {
|
||||
for key in &kc.key {
|
||||
let (modifier, keyval) = Self::split_key(key.as_str())?;
|
||||
if keyval == IBUS_KEY_VoidSymbol {
|
||||
error!("Unknown key symbol: {} {:?}", key, kc);
|
||||
continue;
|
||||
}
|
||||
info!("Insert: {} {} {} {:?}", modifier, keyval, key, kc);
|
||||
for state in &kc.states {
|
||||
mapping.insert(
|
||||
KeyPattern::new(*state, keyval, modifier),
|
||||
kc.command.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(KeyMap { keymap: mapping })
|
||||
}
|
||||
|
||||
pub fn get(&self, key_state: &KeyState, keyval: u32, modifier: u32) -> Option<&String> {
|
||||
@ -293,3 +98,40 @@ impl KeyMap {
|
||||
.get(&KeyPattern::new(*key_state, keyval, modifier))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ibus_sys::ibus_key::{IBUS_KEY_Right, IBUS_KEY_h};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_c_h() -> anyhow::Result<()> {
|
||||
let (modifier, keyval) = KeyMap::split_key("C-h")?;
|
||||
assert_eq!(modifier, IBusModifierType_IBUS_CONTROL_MASK);
|
||||
assert_eq!(keyval, IBUS_KEY_h);
|
||||
info!("Key: C-h, {}, {}", modifier, keyval);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_c_s_h() -> anyhow::Result<()> {
|
||||
let (modifier, keyval) = KeyMap::split_key("C-S-h")?;
|
||||
assert_eq!(
|
||||
modifier,
|
||||
IBusModifierType_IBUS_CONTROL_MASK | IBusModifierType_IBUS_SHIFT_MASK
|
||||
);
|
||||
assert_eq!(keyval, IBUS_KEY_h);
|
||||
info!("Key: C-S-h, {}, {}", modifier, keyval);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shift() -> anyhow::Result<()> {
|
||||
let (modifier, keyval) = KeyMap::split_key("S-Right")?;
|
||||
assert_eq!(modifier, IBusModifierType_IBUS_SHIFT_MASK);
|
||||
assert_eq!(keyval, IBUS_KEY_Right);
|
||||
info!("Key: S-Right, {}, {}", modifier, keyval);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
6
ibus-sys/src/keys.rs
Normal file
6
ibus-sys/src/keys.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use crate::glib::{gchar, guint};
|
||||
|
||||
extern "C" {
|
||||
pub fn ibus_keyval_name(keyval: guint) -> *const gchar;
|
||||
pub fn ibus_keyval_from_name(keyval_name: *const gchar) -> guint;
|
||||
}
|
@ -7,6 +7,7 @@ pub mod core;
|
||||
pub mod engine;
|
||||
pub mod glib;
|
||||
pub mod ibus_key;
|
||||
pub mod keys;
|
||||
pub mod lookup_table;
|
||||
pub mod prop_list;
|
||||
pub mod property;
|
||||
|
121
keymap/default.yml
Normal file
121
keymap/default.yml
Normal file
@ -0,0 +1,121 @@
|
||||
---
|
||||
keys:
|
||||
# 入力モードの切り替え
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [C-S-j]
|
||||
command: set_input_mode_hiragana
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [Henkan]
|
||||
command: set_input_mode_hiragana
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [Hangul]
|
||||
command: set_input_mode_hiragana
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [Muhenkan]
|
||||
command: set_input_mode_alnum
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [Hangul_Hanja]
|
||||
command: set_input_mode_alnum
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [C-S-colon]
|
||||
command: set_input_mode_alnum
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [C-S-l]
|
||||
command: set_input_mode_fullwidth_alnum
|
||||
- states: [Composition, PreComposition, Conversion]
|
||||
key: [C-S-k]
|
||||
command: set_input_mode_katakana
|
||||
|
||||
# 基本的な操作
|
||||
- states: [Composition]
|
||||
key: [space]
|
||||
command: update_candidates
|
||||
- states: [Conversion]
|
||||
key: [space]
|
||||
command: cursor_down
|
||||
- states: [Conversion, Composition]
|
||||
key: [BackSpace]
|
||||
command: erase_character_before_cursor
|
||||
- states: [Conversion, Composition]
|
||||
key: [C-h]
|
||||
command: erase_character_before_cursor
|
||||
- states: [Conversion]
|
||||
key: [Return, KP_Enter]
|
||||
command: commit_candidate
|
||||
- states: [Composition]
|
||||
key: [Return, KP_Enter]
|
||||
command: commit_preedit
|
||||
- states: [Conversion, Composition]
|
||||
key: [Escape]
|
||||
command: escape
|
||||
- states: [Conversion]
|
||||
key: [Up, KP_Up]
|
||||
command: cursor_up
|
||||
- states: [Conversion]
|
||||
key: [Down, KP_Down]
|
||||
command: cursor_down
|
||||
- states: [Conversion]
|
||||
key: [Left, KP_Left]
|
||||
command: cursor_left
|
||||
- states: [Conversion]
|
||||
key: [S-Right, S-KP_Right]
|
||||
command: extend_clause_right
|
||||
- states: [Conversion]
|
||||
key: [S-Left, S-KP_Left]
|
||||
command: extend_clause_left
|
||||
- states: [Composition, Conversion]
|
||||
key: [Page_Up, KP_Page_Up]
|
||||
command : page_up
|
||||
- states: [Composition, Conversion]
|
||||
key: [Page_Down, KP_Page_Down]
|
||||
command : page_down
|
||||
|
||||
# あとから文字タイプを指定する
|
||||
- states: [Composition, Conversion]
|
||||
key: [F6]
|
||||
command: convert_to_full_hiragana
|
||||
- states: [Composition, Conversion]
|
||||
key: [F7]
|
||||
command : convert_to_full_katakana
|
||||
- states: [Composition, Conversion]
|
||||
key: [F8]
|
||||
command : convert_to_half_katakana
|
||||
- states: [Composition, Conversion]
|
||||
key: [F9]
|
||||
command : convert_to_full_romaji
|
||||
- states: [Composition, Conversion]
|
||||
key: [F10]
|
||||
command : convert_to_half_romaji
|
||||
|
||||
# 数字キーによる選択
|
||||
- states: [Conversion]
|
||||
key: [1, KP_1]
|
||||
command : press_number_1
|
||||
- states: [Conversion]
|
||||
key: [2, KP_2]
|
||||
command : press_number_2
|
||||
- states: [Conversion]
|
||||
key: [3, KP_3]
|
||||
command : press_number_3
|
||||
- states: [Conversion]
|
||||
key: [4, KP_4]
|
||||
command : press_number_4
|
||||
- states: [Conversion]
|
||||
key: [5, KP_5]
|
||||
command : press_number_5
|
||||
- states: [Conversion]
|
||||
key: [6, KP_6]
|
||||
command : press_number_6
|
||||
- states: [Conversion]
|
||||
key: [7, KP_7]
|
||||
command : press_number_7
|
||||
- states: [Conversion]
|
||||
key: [8, KP_8]
|
||||
command : press_number_8
|
||||
- states: [Conversion]
|
||||
key: [9, KP_9]
|
||||
command : press_number_9
|
||||
- states: [Conversion]
|
||||
key: [0, KP_0]
|
||||
command : press_number_0
|
||||
|
67
libakaza/src/keymap.rs
Normal file
67
libakaza/src/keymap.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use anyhow::Context;
|
||||
use log::info;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub struct Keymap {
|
||||
pub keys: Vec<KeyConfig>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub struct KeyConfig {
|
||||
pub states: Vec<KeyState>,
|
||||
pub key: Vec<String>,
|
||||
pub command: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Copy, Clone, Serialize, Deserialize)]
|
||||
pub enum KeyState {
|
||||
// 何も入力されていない状態。
|
||||
PreComposition,
|
||||
// 変換処理に入る前。ひらがなを入力している段階。
|
||||
Composition,
|
||||
// 変換中
|
||||
Conversion,
|
||||
}
|
||||
|
||||
impl Keymap {
|
||||
pub fn load(name: &str) -> anyhow::Result<Keymap> {
|
||||
let pathstr: String = if cfg!(test) || cfg!(feature = "it") {
|
||||
format!("{}/../keymap/{}.yml", env!("CARGO_MANIFEST_DIR"), name)
|
||||
} else if let Ok(env) = env::var("AKAZA_KEYMAP_DIR") {
|
||||
format!("{}/{}.yml", env, name)
|
||||
} else {
|
||||
let pathbuf = xdg::BaseDirectories::with_prefix("akaza")
|
||||
.with_context(|| "Opening xdg directory with 'akaza' prefix")?
|
||||
.get_config_file(format!("keymap/{}.yml", name));
|
||||
pathbuf.to_string_lossy().to_string()
|
||||
};
|
||||
info!("Load {}", pathstr);
|
||||
let got: Keymap = serde_yaml::from_reader(BufReader::new(
|
||||
File::open(&pathstr).with_context(|| pathstr)?,
|
||||
))?;
|
||||
Ok(got)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::keymap::KeyState::Conversion;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_keymap() -> anyhow::Result<()> {
|
||||
let keymap: Keymap =
|
||||
serde_yaml::from_reader(BufReader::new(File::open("../keymap/default.yml")?))?;
|
||||
for kc in keymap.keys {
|
||||
println!("{:?}", kc);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -15,3 +15,4 @@ pub mod lm;
|
||||
pub mod romkan;
|
||||
pub mod trie;
|
||||
pub mod user_side_data;
|
||||
pub mod keymap;
|
||||
|
Reference in New Issue
Block a user