mirror of
https://github.com/mii443/akaza.git
synced 2025-08-22 23:05:26 +00:00
keymap を別ファイルにうつした #155
This commit is contained in:
1
Makefile
1
Makefile
@ -3,5 +3,6 @@ DATADIR ?= $(PREFIX)/share
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
install -m 0644 -v -D -t $(DATADIR)/akaza/romkan romkan/*
|
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
|
$(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_DATA_DIR="$BASEDIR/../akaza-data/data/"
|
||||||
export AKAZA_ROMKAN_DIR="$BASEDIR/../romkan/"
|
export AKAZA_ROMKAN_DIR="$BASEDIR/../romkan/"
|
||||||
|
export AKAZA_KEYMAP_DIR="$BASEDIR/../keymap/"
|
||||||
|
|
||||||
export RUST_BACKTRACE=4
|
export RUST_BACKTRACE=4
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ use libakaza::engine::base::HenkanEngine;
|
|||||||
use libakaza::engine::bigram_word_viterbi_engine::BigramWordViterbiEngine;
|
use libakaza::engine::bigram_word_viterbi_engine::BigramWordViterbiEngine;
|
||||||
use libakaza::extend_clause::{extend_left, extend_right};
|
use libakaza::extend_clause::{extend_left, extend_right};
|
||||||
use libakaza::graph::candidate::Candidate;
|
use libakaza::graph::candidate::Candidate;
|
||||||
|
use libakaza::keymap::KeyState;
|
||||||
use libakaza::lm::system_bigram::MarisaSystemBigramLM;
|
use libakaza::lm::system_bigram::MarisaSystemBigramLM;
|
||||||
use libakaza::lm::system_unigram_lm::MarisaSystemUnigramLM;
|
use libakaza::lm::system_unigram_lm::MarisaSystemUnigramLM;
|
||||||
use libakaza::romkan::RomKanConverter;
|
use libakaza::romkan::RomKanConverter;
|
||||||
@ -53,16 +54,6 @@ use crate::input_mode::{
|
|||||||
};
|
};
|
||||||
use crate::keymap::KeyMap;
|
use crate::keymap::KeyMap;
|
||||||
|
|
||||||
#[derive(Debug, Hash, PartialEq, Copy, Clone)]
|
|
||||||
pub enum KeyState {
|
|
||||||
// 何も入力されていない状態。
|
|
||||||
PreComposition,
|
|
||||||
// 変換処理に入る前。ひらがなを入力している段階。
|
|
||||||
Composition,
|
|
||||||
// 変換中
|
|
||||||
Conversion,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct AkazaContext {
|
pub struct AkazaContext {
|
||||||
pub(crate) input_mode: InputMode,
|
pub(crate) input_mode: InputMode,
|
||||||
@ -189,7 +180,7 @@ impl AkazaContext {
|
|||||||
is_invalidate: false,
|
is_invalidate: false,
|
||||||
cursor_moved: false,
|
cursor_moved: false,
|
||||||
node_selected: HashMap::new(),
|
node_selected: HashMap::new(),
|
||||||
keymap: KeyMap::new(),
|
keymap: KeyMap::new()?,
|
||||||
force_selected_clause: Vec::new(),
|
force_selected_clause: Vec::new(),
|
||||||
prop_list,
|
prop_list,
|
||||||
input_mode_prop,
|
input_mode_prop,
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
use std::collections::HashMap;
|
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::core::{IBusModifierType_IBUS_CONTROL_MASK, IBusModifierType_IBUS_SHIFT_MASK};
|
||||||
use ibus_sys::ibus_key::{
|
use ibus_sys::glib::guint;
|
||||||
IBUS_KEY_BackSpace, IBUS_KEY_Down, IBUS_KEY_Escape, IBUS_KEY_Hangul, IBUS_KEY_Hangul_Hanja,
|
use ibus_sys::ibus_key::IBUS_KEY_VoidSymbol;
|
||||||
IBUS_KEY_Henkan, IBUS_KEY_KP_Down, IBUS_KEY_KP_Enter, IBUS_KEY_KP_Left, IBUS_KEY_KP_Page_Down,
|
use ibus_sys::keys::ibus_keyval_from_name;
|
||||||
IBUS_KEY_KP_Page_Up, IBUS_KEY_KP_Right, IBUS_KEY_KP_Up, IBUS_KEY_Left, IBUS_KEY_Muhenkan,
|
use libakaza::keymap::{KeyState, Keymap};
|
||||||
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;
|
|
||||||
|
|
||||||
#[derive(Hash, PartialEq)]
|
#[derive(Hash, PartialEq)]
|
||||||
struct KeyPattern {
|
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 {
|
pub struct KeyMap {
|
||||||
keymap: HashMap<KeyPattern, String>,
|
keymap: HashMap<KeyPattern, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyMap {
|
impl KeyMap {
|
||||||
pub(crate) fn new() -> Self {
|
/// - first: modifier
|
||||||
let mut builder = KeyMapBuilder::new();
|
/// - 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
|
// TODO use IBus.Hotkey
|
||||||
|
|
||||||
// 入力モードの切り替え
|
let keymap = Keymap::load("default")?;
|
||||||
builder.insert(
|
let mut mapping: HashMap<KeyPattern, String> = HashMap::new();
|
||||||
&[
|
|
||||||
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",
|
|
||||||
);
|
|
||||||
|
|
||||||
// basic operations.
|
for kc in keymap.keys {
|
||||||
builder.insert(
|
for key in &kc.key {
|
||||||
&[KeyState::Composition],
|
let (modifier, keyval) = Self::split_key(key.as_str())?;
|
||||||
&[IBUS_KEY_space],
|
if keyval == IBUS_KEY_VoidSymbol {
|
||||||
0,
|
error!("Unknown key symbol: {} {:?}", key, kc);
|
||||||
"update_candidates",
|
continue;
|
||||||
);
|
}
|
||||||
builder.insert(&[KeyState::Conversion], &[IBUS_KEY_space], 0, "cursor_down");
|
info!("Insert: {} {} {} {:?}", modifier, keyval, key, kc);
|
||||||
|
for state in &kc.states {
|
||||||
builder.insert(
|
mapping.insert(
|
||||||
&[KeyState::Conversion, KeyState::Composition],
|
KeyPattern::new(*state, keyval, modifier),
|
||||||
&[IBUS_KEY_BackSpace],
|
kc.command.clone(),
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(KeyMap { keymap: mapping })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, key_state: &KeyState, keyval: u32, modifier: u32) -> Option<&String> {
|
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))
|
.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 engine;
|
||||||
pub mod glib;
|
pub mod glib;
|
||||||
pub mod ibus_key;
|
pub mod ibus_key;
|
||||||
|
pub mod keys;
|
||||||
pub mod lookup_table;
|
pub mod lookup_table;
|
||||||
pub mod prop_list;
|
pub mod prop_list;
|
||||||
pub mod property;
|
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 romkan;
|
||||||
pub mod trie;
|
pub mod trie;
|
||||||
pub mod user_side_data;
|
pub mod user_side_data;
|
||||||
|
pub mod keymap;
|
||||||
|
Reference in New Issue
Block a user