Skip to content

Commit

Permalink
Separate okuri ari entries and make userdict compatible like ddskk (#205
Browse files Browse the repository at this point in the history
)

* Separate okuri-ari and okuri-nashi dict entries

* Read strict okuri and use

* Make user dict ordering recent used first
  • Loading branch information
naokiri authored Oct 14, 2022
1 parent 5c01033 commit 1bd9520
Show file tree
Hide file tree
Showing 20 changed files with 1,227 additions and 403 deletions.
61 changes: 60 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cskk"
# Have to also change the deb package destination filename below
version = "0.10.3"
version = "0.11.0"
authors = ["Naoaki Iwakiri <naokiri@gmail.com>"]
license = "GPL-3.0-or-later"
edition = "2018"
Expand Down Expand Up @@ -33,6 +33,8 @@ regex = "^1.5"
lazy_static = "1.4"
xdg = { version = "^2.4" }
anyhow = { version = "^1.0.65" }
nom = "^7.1"
lru = "^0.8.1"

[dev-dependencies]
env_logger = "^0.9.0"
Expand Down
2 changes: 1 addition & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ To install to non-standard directories, append following options like this. See
- [x] Basic 漢字変換
- [x] static dictionary
- [x] user dictionary
- not ddskk compatible
- ddskk compatible since v0.11.0
- [ ] 接頭辞・接尾辞変換
- [x] 数値変換
- [x] auto-start-henkan
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ root権限がある場合、以下を実行する。
- [x] Basic 漢字変換
- [x] static dictionary
- [x] user dictionary
- not ddskk compatible
- ddskk compatible since v0.11.0
- [ ] 接頭辞・接尾辞変換
- [x] 数値変換
- [x] auto-start-henkan
Expand Down
9 changes: 5 additions & 4 deletions src/candidate_list.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::dictionary::candidate::Candidate;
use crate::dictionary::CompositeKey;
use crate::error::CskkError;

#[derive(Debug)]
pub(crate) struct CandidateList {
// 現在保持している選択肢の元
to_composite: String,
to_composite: CompositeKey,
// 現在のカーソル位置
selection_cursor_position: usize,
// 変換中の選択肢
Expand All @@ -14,13 +15,13 @@ pub(crate) struct CandidateList {
impl CandidateList {
pub(crate) fn new() -> Self {
CandidateList {
to_composite: "".to_string(),
to_composite: CompositeKey::new("", None),
selection_cursor_position: 0,
composition_candidates: vec![],
}
}

pub(crate) fn set(&mut self, raw_to_composite: String, candidates: Vec<Candidate>) {
pub(crate) fn set(&mut self, raw_to_composite: CompositeKey, candidates: Vec<Candidate>) {
self.to_composite = raw_to_composite;
self.composition_candidates = candidates;
self.selection_cursor_position = 0;
Expand All @@ -41,7 +42,7 @@ impl CandidateList {
}
}

pub(crate) fn get_current_to_composite(&self) -> &str {
pub(crate) fn get_current_to_composite(&self) -> &CompositeKey {
&self.to_composite
}

Expand Down
30 changes: 12 additions & 18 deletions src/cskkstate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::candidate_list::CandidateList;
use crate::dictionary::candidate::Candidate;
use crate::dictionary::CompositeKey;
use crate::form_changer::KanaFormChanger;
use crate::skk_modes::{CompositionMode, InputMode};
use std::fmt::{Debug, Formatter};
Expand All @@ -23,7 +24,7 @@ pub(crate) struct CskkState {
raw_to_composite: String,
// 未確定入力の漢字の読み部分。主にひらがな、Abbrev等の時は英字もありうる。出力時にInputModeにあわせて変換される。
converted_kana_to_composite: String,
// 未確定入力の漢字の読み以外の部分。多くの場合送り仮名であり、その想定のもとに変数名を付けてしまったが、auto_start_henkan等の強制的に変換を開始する場合にはおくりがな以外のpostfixが入ることもある。convertがあるInputMode時のみ使用
// 未確定入力の漢字の読み以外の部分。多くの場合送り仮名であり、その想定のもとに変数名を付けてしまったが、auto_start_henkan等の強制的に変換を開始する場合にはおくりがな以外のpostfixが入ることもある。
converted_kana_to_okuri: String,
// 現在の変換候補リスト
candidate_list: CandidateList,
Expand All @@ -33,7 +34,7 @@ pub(crate) struct CskkState {
confirmed: String,
// 今のかな変換の間に大文字でモード変更をしたかどうか。このステートによってシフトを押したままキー入力をしてしまった時に連続してモード変更しないようにしている。
capital_transition: bool,
// 現在送り仮名を入力しているかどうか。postfixを送り仮名として用いるべきかどうか
// 現在送り仮名を入力しているかどうか。converted_kana_to_okuriを送り仮名として用いるべきかどうか
use_okurigana: bool,
}

Expand Down Expand Up @@ -276,22 +277,15 @@ impl CskkState {
}

/// 今のステートで変換する時の辞書のキーとして使うべき文字列を返す。
pub(crate) fn get_composite_key(&self) -> String {
// ローマ字ベースではない入力規則に対応するため、送り仮名の最初の文字はひらがなから対応表を引く。
if self.use_okurigana {
// ひらがなはUnicode Scalar Valueなのでchars()で十分。
if let Some(first_kana) = self.converted_kana_to_okuri.chars().next() {
if let Some(okuri_first) =
KanaFormChanger::kana_to_okuri_prefix(&first_kana.to_string())
{
let mut string = self.raw_to_composite.to_owned();
string.push_str(okuri_first);
return string;
}
}
pub(crate) fn get_composite_key(&self) -> CompositeKey {
if self.use_okurigana && !self.converted_kana_to_okuri.is_empty() {
return CompositeKey::new(
&self.raw_to_composite,
Some(self.converted_kana_to_okuri.to_owned()),
);
}

self.raw_to_composite.to_owned()
CompositeKey::new(&self.raw_to_composite, None)
}

pub(crate) fn set_capital_transition(&mut self, has_transitioned: bool) {
Expand Down Expand Up @@ -339,8 +333,8 @@ impl CskkState {

/// 現在の変換候補を設定し、最初の候補を指す
pub(crate) fn set_new_candidate_list(&mut self, candidates: Vec<Candidate>) {
let raw_to_composite = self.get_composite_key();
self.candidate_list.set(raw_to_composite, candidates);
let composite_key = self.get_composite_key();
self.candidate_list.set(composite_key, candidates);
self.composited_okuri = self.converted_kana_to_okuri.to_string();
}
}
Expand Down
97 changes: 27 additions & 70 deletions src/dictionary/candidate.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
use crate::dictionary::dictentry::DictEntry;
use crate::error::CskkError;
use log::*;
use std::fmt::Write;
use std::sync::Arc;
use crate::dictionary::dictionary_candidate::DictionaryCandidate;
use crate::dictionary::CompositeKey;

// Blind copy of libskk vala Candidate class
// CandidateListに持たせる情報。
// libskk vala Candidate classを元に、単体で送り仮名の厳密マッチの登録に必要な情報を持たせている。TODO: libskk 由来なので重複した情報を整理、valaなので外に見せすぎ、特にcomposite_keyに含まれる情報は不要かも
#[derive(Debug, Clone)]
pub struct Candidate {
pub(crate) midashi: Arc<String>,
#[allow(dead_code)]
// 取り回しの都合上DictEntryと重複して持つ
pub(crate) midashi: String,
pub(crate) okuri: bool,
// Raw kouho_text that might include "#0回" etc
pub(crate) kouho_text: Arc<String>,
pub(crate) annotation: Option<Arc<String>>,
// Output to show the candidate.
pub(crate) kouho_text: String,
pub(crate) annotation: Option<String>,
// Output to show the candidate. "第#0回"が"第壱回"のように後処理されている想定。
pub(crate) output: String,
}

impl Default for Candidate {
fn default() -> Self {
Candidate {
midashi: Arc::new("エラー".to_owned()),
midashi: "エラー".to_string(),
okuri: false,
kouho_text: Arc::new("エラー".to_owned()),
kouho_text: "エラー".to_string(),
annotation: None,
output: "エラー".to_string(),
}
Expand All @@ -40,10 +38,10 @@ impl PartialEq for Candidate {

impl Candidate {
pub(crate) fn new(
midashi: Arc<String>,
midashi: String,
okuri: bool,
kouho_text: Arc<String>,
annotation: Option<Arc<String>>,
kouho_text: String,
annotation: Option<String>,
output: String,
) -> Self {
Candidate {
Expand All @@ -55,60 +53,19 @@ impl Candidate {
}
}

pub(crate) fn from_skk_jisyo_string(midashi: &str, raw_entry: &str) -> Result<Self, CskkError> {
let mut chunk = raw_entry.split(';');
if let Some(text) = chunk.next() {
let kouho = DictEntry::process_lisp_fun(text);
let annotation = chunk
.next()
.map(|entry| Arc::new(DictEntry::process_lisp_fun(entry)));
Ok(Candidate::new(
Arc::new(midashi.to_string()),
false,
Arc::new(kouho.to_string()),
annotation,
kouho,
))
} else {
debug!("Failed to parse candidate from: {:?}", raw_entry);
Err(CskkError::Error("No candidate".to_string()))
}
}

// entry string between '/'
// {候補};アノテーション
// {候補};*アノテーション
// TODO: 将来的には [{優先送り仮名}/{候補}] のような優先送り仮名エントリも扱えると嬉しい
pub(crate) fn to_skk_jisyo_string(&self) -> String {
let mut result = String::new();
result.push_str(&DictEntry::escape_dictionary_string(
self.kouho_text.as_str(),
));
if let Some(annotation) = &self.annotation {
write!(
result,
";{}",
&DictEntry::escape_dictionary_string(annotation.as_str())
)
.expect("Failed to allocate jisyo string for candidate.");
///
/// 辞書の候補からそのままの内容で候補リスト用のcandidateを返す。
///
pub(in crate::dictionary) fn from_dictionary_candidate(
composite_key: &CompositeKey,
dictionary_cand: &DictionaryCandidate,
) -> Self {
Self {
midashi: composite_key.get_to_composite().to_string(),
okuri: composite_key.has_okuri(),
kouho_text: dictionary_cand.kouho_text.to_owned(),
annotation: dictionary_cand.annotation.to_owned(),
output: dictionary_cand.kouho_text.to_owned(),
}
result
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn skk_jisyo_string_no_annotation() {
let candidate = Candidate::new(
Arc::new("みだし".to_string()),
false,
Arc::new("候補".to_string()),
None,
"候補".to_string(),
);
assert_eq!("候補", candidate.to_skk_jisyo_string())
}
}
Loading

0 comments on commit 1bd9520

Please sign in to comment.