Skip to content

Commit 563635c

Browse files
authored
Merge pull request #59 from azooKey/codex/アクション仕様調査と設計検討
2 parents 3185363 + 4c500e7 commit 563635c

File tree

8 files changed

+86
-0
lines changed

8 files changed

+86
-0
lines changed

json/howToMake.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ azooKeyでは`"input"`の他にいくつかの動作を行うことができま
9696
| move_tab | tab_type: str<br />identifier: str | identifierで指定したタブに移動します。tab_typeが`"system"`の場合はazooKeyが標準で搭載しているタブに移動し、`"custom"`の場合はidentifierを持ったカスタムタブに移動します。システムタブとして指定できる値は後に記述します。 |
9797
| select_candidate | type: str<br /> value: int | 引数で指定した候補を選択状態にします。typeは4種類あります。`"first"`(最初の候補)と`"last"`(最後の候補)の場合は`"value"`の指定は不要です。`"exact"`(value個目の候補を選択)と`"offset"`(value個隣の候補を選択)の場合は`"value"`に数値を指定してください。 |
9898
| complete | なし | 変換を確定します |
99+
| complete_character_form | forms: [str] | formsで指定した文字種に変換してから確定します。指定できる値は`hiragana`, `katakana`, `halfwidth_katakana`, `uppercase`, `lowercase`です。 |
99100
| replace_last_characters | table: {str: str} | カーソル文頭方向の文字列を引数のtableに基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 |
100101
| replace_default | replace_type: str, dakuten, handakutenなど<br />fallbacks: [str] | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 |
101102
| smart_delete | direction: str<br />targets: [str] | directionに`"forward"`または`"backward"`を指定します。targetsに指定した文字のいずれかがカーソル進行方向に現れるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、`"direction": "backward", "targets": [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 |

python/howToMake.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ azooKeyでは`InputAction`の他にいくつかの動作を行うことができ
8484
| MoveTabAction | tab_type: TabType<br />identifier: str | identifierで指定したタブに移動します。tab_typeが`system`の場合はazooKeyが標準で搭載しているタブに移動し、`custom`の場合はidentifierを持ったカスタムタブに移動します。システムタブとして指定できる値は後に記述します。 |
8585
| SelectCandidateAction | type: str<br /> value: int | 引数で指定した候補を選択状態にします。typeは4種類あります。`"first"`(最初の候補)と`"last"`(最後の候補)の場合は`"value"`の指定は不要です。`"exact"`(value個目の候補を選択)と`"offset"`(value個隣の候補を選択)の場合は`"value"`に数値を指定してください。 |
8686
| CompleteAction | なし | 変換を確定します |
87+
| CompleteCharacterFormAction | forms: list[CharacterForm] | 入力中の文字列をformsで指定した形式に変換して確定します。 |
8788
| ReplaceLastCharactersAction | table: {str: str} | カーソル文頭方向の文字列を引数のtableに基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 |
8889
| ReplaceDefaultAction | replace_type: ReplaceType<br />fallbacks: list[ReplaceType] | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 |
8990
| SmartDeleteAction | direction: ScanDirection<br />targets: list[str] | directionに`ScanDirection.forward`または`ScanDirection.backward`を指定します。targetsに指定した文字のいずれかがカーソル進行方向に現れるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、`direction = ScanDirection.backward, target = [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 |

python/source/actions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ def __init__(self, replace_type: ReplaceType = ReplaceType.default, fallbacks: l
8888
self.fallbacks = fallbacks
8989

9090

91+
@unique
92+
class CharacterForm(str, Enum):
93+
hiragana = "hiragana"
94+
katakana = "katakana"
95+
halfwidth_katakana = "halfwidth_katakana"
96+
uppercase = "uppercase"
97+
lowercase = "lowercase"
98+
99+
100+
class CompleteCharacterFormAction(metaclass=ActionMeta):
101+
type = "complete_character_form"
102+
103+
def __init__(self, forms: list[CharacterForm]):
104+
"""指定した形式に変換して確定するアクション"""
105+
self.forms = forms
106+
107+
91108
@unique
92109
class TabType(str, Enum):
93110
system = "system"

python/test/test_actions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,22 @@ def test_ReplaceDefaultAction(self):
150150
}
151151
self.assertEqual(expected_json, actual)
152152

153+
def test_CompleteCharacterFormAction(self):
154+
actual = to_json(CompleteCharacterFormAction([
155+
CharacterForm.katakana, CharacterForm.uppercase]))
156+
expected_json = {
157+
"type": "complete_character_form",
158+
"forms": [CharacterForm.katakana, CharacterForm.uppercase]
159+
}
160+
self.assertEqual(expected_json, actual)
161+
162+
actual = to_json(CompleteCharacterFormAction([CharacterForm.hiragana]))
163+
expected_json = {
164+
"type": "complete_character_form",
165+
"forms": [CharacterForm.hiragana]
166+
}
167+
self.assertEqual(expected_json, actual)
168+
153169
def test_NoArgumentsAction(self):
154170
"""test method for actions without arguments
155171
"""

swift/howToMake.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ azooKeyでは`input`の他にいくつかの動作を行うことができます
8787
| .selectCandidate | CandidateSelection | 引数で指定した候補を選択状態にします |
8888
| .complete | なし | 変換を確定します |
8989
| .replaceLastCharacters | [String: String] | カーソル文頭方向の文字列を引数に基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 |
90+
| .completeCharacterForm | [CharacterForm] | 指定した文字種に変換してから確定します。CharacterFormは`hiragana`, `katakana`, `halfwidthKatakana`, `uppercase`, `lowercase`を指定できます。 |
9091
| .replaceDefault | ReplaceBehavior | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 |
9192
| .smartDelete | ScanItem | 引数で指定した方向に、指定した文字を見つけるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、方向が`.backward`かつ文字の指定が` [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 |
9293
| .smartDeleteDefault | なし | azooKeyが標準で用いている「文頭まで削除」のアクションです。 |

swift/sources/CustardActions.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ public struct ReplaceBehavior: Hashable, Sendable {
174174
public var fallbacks: [ReplaceType]
175175
}
176176

177+
public enum CharacterForm: String, Codable, Hashable, Sendable {
178+
case hiragana
179+
case katakana
180+
case halfwidthKatakana = "halfwidth_katakana"
181+
case uppercase
182+
case lowercase
183+
}
184+
177185
/// - アクション
178186
/// - actions done in key pressing
179187
public enum CodableActionData: Codable, Hashable, Sendable {
@@ -203,6 +211,9 @@ public enum CodableActionData: Codable, Hashable, Sendable {
203211
/// - select candidate to complete
204212
case selectCandidate(CandidateSelection)
205213

214+
/// - convert character form then complete current inputting words
215+
case completeCharacterForm([CharacterForm])
216+
206217
/// - complete current inputting words
207218
case complete
208219

@@ -248,6 +259,7 @@ public extension CodableActionData {
248259
case scheme_type, target
249260
case selection
250261
case replace_type, fallbacks
262+
case forms
251263
}
252264

253265
private enum ValueType: String, Codable {
@@ -259,6 +271,7 @@ public extension CodableActionData {
259271
case smart_delete
260272
case smart_delete_default
261273
case select_candidate
274+
case complete_character_form
262275
case complete
263276
case move_cursor
264277
case smart_move_cursor
@@ -276,6 +289,7 @@ public extension CodableActionData {
276289
private var key: ValueType {
277290
switch self {
278291
case .selectCandidate: return .select_candidate
292+
case .completeCharacterForm: return .complete_character_form
279293
case .complete: return .complete
280294
case .delete: return .delete
281295
case .dismissKeyboard: return .dismiss_keyboard
@@ -359,6 +373,8 @@ public extension CodableActionData {
359373
try container.encode(value.target, forKey: .target)
360374
case let .selectCandidate(value):
361375
try container.encode(value, forKey: .selection)
376+
case let .completeCharacterForm(value):
377+
try container.encode(value, forKey: .forms)
362378
case let .moveTab(value):
363379
try CodableTabArgument(tab: value).containerEncode(container: &container)
364380
case .dismissKeyboard, .enableResizingMode, .toggleTabBar, .toggleCursorBar, .toggleCapsLockState, .complete, .smartDeleteDefault, .paste: break
@@ -391,6 +407,9 @@ public extension CodableActionData {
391407
case .select_candidate:
392408
let selection = try container.decode(CandidateSelection.self, forKey: .selection)
393409
self = .selectCandidate(selection)
410+
case .complete_character_form:
411+
let forms = try container.decode([CharacterForm].self, forKey: .forms)
412+
self = .completeCharacterForm(forms)
394413
case .complete:
395414
self = .complete
396415
case .move_cursor:

swift/tests/CustardKitTests/DecodeCodableActionTest.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,29 @@ final class DecodeCodableActionTest: XCTestCase {
202202
}
203203
}
204204

205+
func testDecodeCompleteCharacterForm() {
206+
do {
207+
let target = """
208+
{
209+
"type": "complete_character_form",
210+
"forms": ["katakana", "uppercase"]
211+
}
212+
"""
213+
let decoded = CodableActionData.quickDecode(target: target)
214+
XCTAssertEqual(decoded, .completeCharacterForm([.katakana, .uppercase]))
215+
}
216+
do {
217+
let target = """
218+
{
219+
"type": "complete_character_form",
220+
"forms": ["hiragana"]
221+
}
222+
"""
223+
let decoded = CodableActionData.quickDecode(target: target)
224+
XCTAssertEqual(decoded, .completeCharacterForm([.hiragana]))
225+
}
226+
}
227+
205228
func testDecodeNoArgumentActions() {
206229
do {
207230
let target = """
@@ -311,6 +334,7 @@ final class DecodeCodableActionTest: XCTestCase {
311334
("testDecodeMoveCursor", testDecodeMoveCursor),
312335
("testDecodeSmartMoveCursor", testDecodeSmartMoveCursor),
313336
("testDecodeMoveTab", testDecodeMoveTab),
337+
("testDecodeCompleteCharacterForm", testDecodeCompleteCharacterForm),
314338
("testDecodeNoArgumentActions", testDecodeNoArgumentActions)
315339
]
316340
}

swift/tests/CustardKitTests/EncodeCodableActionTest.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ final class EncodeCodableActionTest: XCTestCase {
6464
XCTAssertQuickEncodeDecode(CodableActionData.replaceDefault(.init(type: .handakuten, fallbacks: [.default])))
6565
}
6666

67+
func testEncodeCompleteCharacterForm() {
68+
let target = CodableActionData.completeCharacterForm([.katakana, .uppercase])
69+
XCTAssertEqual(target.quickEncodeDecode(), target)
70+
XCTAssertEqual(CodableActionData.completeCharacterForm([.hiragana]).quickEncodeDecode(), .completeCharacterForm([.hiragana]))
71+
}
72+
6773
func testEncodeNoArgumentActions() {
6874
XCTAssertEqual(CodableActionData.smartDeleteDefault.quickEncodeDecode(), .smartDeleteDefault)
6975
XCTAssertEqual(CodableActionData.complete.quickEncodeDecode(), .complete)
@@ -82,6 +88,7 @@ final class EncodeCodableActionTest: XCTestCase {
8288
("testEncodeMoveCursor", testEncodeMoveCursor),
8389
("testEncodeSmartMoveCursor", testEncodeSmartMoveCursor),
8490
("testEncodeMoveTab", testEncodeMoveTab),
91+
("testEncodeCompleteCharacterForm", testEncodeCompleteCharacterForm),
8592
("testEncodeNoArgumentActions", testEncodeNoArgumentActions)
8693
]
8794
}

0 commit comments

Comments
 (0)