Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions json/howToMake.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ azooKeyでは`"input"`の他にいくつかの動作を行うことができま
| move_tab | tab_type: str<br />identifier: str | identifierで指定したタブに移動します。tab_typeが`"system"`の場合はazooKeyが標準で搭載しているタブに移動し、`"custom"`の場合はidentifierを持ったカスタムタブに移動します。システムタブとして指定できる値は後に記述します。 |
| select_candidate | type: str<br /> value: int | 引数で指定した候補を選択状態にします。typeは4種類あります。`"first"`(最初の候補)と`"last"`(最後の候補)の場合は`"value"`の指定は不要です。`"exact"`(value個目の候補を選択)と`"offset"`(value個隣の候補を選択)の場合は`"value"`に数値を指定してください。 |
| complete | なし | 変換を確定します |
| complete_character_form | forms: [str] | formsで指定した文字種に変換してから確定します。指定できる値は`hiragana`, `katakana`, `halfwidth_katakana`, `uppercase`, `lowercase`です。 |
| replace_last_characters | table: {str: str} | カーソル文頭方向の文字列を引数のtableに基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 |
| replace_default | replace_type: str, dakuten, handakutenなど<br />fallbacks: [str] | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 |
| smart_delete | direction: str<br />targets: [str] | directionに`"forward"`または`"backward"`を指定します。targetsに指定した文字のいずれかがカーソル進行方向に現れるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、`"direction": "backward", "targets": [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 |
Expand Down
1 change: 1 addition & 0 deletions python/howToMake.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ azooKeyでは`InputAction`の他にいくつかの動作を行うことができ
| MoveTabAction | tab_type: TabType<br />identifier: str | identifierで指定したタブに移動します。tab_typeが`system`の場合はazooKeyが標準で搭載しているタブに移動し、`custom`の場合はidentifierを持ったカスタムタブに移動します。システムタブとして指定できる値は後に記述します。 |
| SelectCandidateAction | type: str<br /> value: int | 引数で指定した候補を選択状態にします。typeは4種類あります。`"first"`(最初の候補)と`"last"`(最後の候補)の場合は`"value"`の指定は不要です。`"exact"`(value個目の候補を選択)と`"offset"`(value個隣の候補を選択)の場合は`"value"`に数値を指定してください。 |
| CompleteAction | なし | 変換を確定します |
| CompleteCharacterFormAction | forms: list[CharacterForm] | 入力中の文字列をformsで指定した形式に変換して確定します。 |
| ReplaceLastCharactersAction | table: {str: str} | カーソル文頭方向の文字列を引数のtableに基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 |
| ReplaceDefaultAction | replace_type: ReplaceType<br />fallbacks: list[ReplaceType] | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 |
| SmartDeleteAction | direction: ScanDirection<br />targets: list[str] | directionに`ScanDirection.forward`または`ScanDirection.backward`を指定します。targetsに指定した文字のいずれかがカーソル進行方向に現れるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、`direction = ScanDirection.backward, target = [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 |
Expand Down
17 changes: 17 additions & 0 deletions python/source/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ def __init__(self, replace_type: ReplaceType = ReplaceType.default, fallbacks: l
self.fallbacks = fallbacks


@unique
class CharacterForm(str, Enum):
hiragana = "hiragana"
katakana = "katakana"
halfwidth_katakana = "halfwidth_katakana"
uppercase = "uppercase"
lowercase = "lowercase"


class CompleteCharacterFormAction(metaclass=ActionMeta):
type = "complete_character_form"

def __init__(self, forms: list[CharacterForm]):
"""指定した形式に変換して確定するアクション"""
self.forms = forms


@unique
class TabType(str, Enum):
system = "system"
Expand Down
16 changes: 16 additions & 0 deletions python/test/test_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,22 @@ def test_ReplaceDefaultAction(self):
}
self.assertEqual(expected_json, actual)

def test_CompleteCharacterFormAction(self):
actual = to_json(CompleteCharacterFormAction([
CharacterForm.katakana, CharacterForm.uppercase]))
expected_json = {
"type": "complete_character_form",
"forms": [CharacterForm.katakana, CharacterForm.uppercase]
}
self.assertEqual(expected_json, actual)

actual = to_json(CompleteCharacterFormAction([CharacterForm.hiragana]))
expected_json = {
"type": "complete_character_form",
"forms": [CharacterForm.hiragana]
}
self.assertEqual(expected_json, actual)

def test_NoArgumentsAction(self):
"""test method for actions without arguments
"""
Expand Down
1 change: 1 addition & 0 deletions swift/howToMake.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ azooKeyでは`input`の他にいくつかの動作を行うことができます
| .selectCandidate | CandidateSelection | 引数で指定した候補を選択状態にします |
| .complete | なし | 変換を確定します |
| .replaceLastCharacters | [String: String] | カーソル文頭方向の文字列を引数に基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 |
| .completeCharacterForm | [CharacterForm] | 指定した文字種に変換してから確定します。CharacterFormは`hiragana`, `katakana`, `halfwidthKatakana`, `uppercase`, `lowercase`を指定できます。 |
| .replaceDefault | ReplaceBehavior | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 |
| .smartDelete | ScanItem | 引数で指定した方向に、指定した文字を見つけるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、方向が`.backward`かつ文字の指定が` [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 |
| .smartDeleteDefault | なし | azooKeyが標準で用いている「文頭まで削除」のアクションです。 |
Expand Down
19 changes: 19 additions & 0 deletions swift/sources/CustardActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ public struct ReplaceBehavior: Hashable, Sendable {
public var fallbacks: [ReplaceType]
}

public enum CharacterForm: String, Codable, Hashable, Sendable {
case hiragana
case katakana
case halfwidthKatakana = "halfwidth_katakana"
case uppercase
case lowercase
}

/// - アクション
/// - actions done in key pressing
public enum CodableActionData: Codable, Hashable, Sendable {
Expand Down Expand Up @@ -203,6 +211,9 @@ public enum CodableActionData: Codable, Hashable, Sendable {
/// - select candidate to complete
case selectCandidate(CandidateSelection)

/// - convert character form then complete current inputting words
case completeCharacterForm([CharacterForm])

/// - complete current inputting words
case complete

Expand Down Expand Up @@ -248,6 +259,7 @@ public extension CodableActionData {
case scheme_type, target
case selection
case replace_type, fallbacks
case forms
}

private enum ValueType: String, Codable {
Expand All @@ -259,6 +271,7 @@ public extension CodableActionData {
case smart_delete
case smart_delete_default
case select_candidate
case complete_character_form
case complete
case move_cursor
case smart_move_cursor
Expand All @@ -276,6 +289,7 @@ public extension CodableActionData {
private var key: ValueType {
switch self {
case .selectCandidate: return .select_candidate
case .completeCharacterForm: return .complete_character_form
case .complete: return .complete
case .delete: return .delete
case .dismissKeyboard: return .dismiss_keyboard
Expand Down Expand Up @@ -359,6 +373,8 @@ public extension CodableActionData {
try container.encode(value.target, forKey: .target)
case let .selectCandidate(value):
try container.encode(value, forKey: .selection)
case let .completeCharacterForm(value):
try container.encode(value, forKey: .forms)
case let .moveTab(value):
try CodableTabArgument(tab: value).containerEncode(container: &container)
case .dismissKeyboard, .enableResizingMode, .toggleTabBar, .toggleCursorBar, .toggleCapsLockState, .complete, .smartDeleteDefault, .paste: break
Expand Down Expand Up @@ -391,6 +407,9 @@ public extension CodableActionData {
case .select_candidate:
let selection = try container.decode(CandidateSelection.self, forKey: .selection)
self = .selectCandidate(selection)
case .complete_character_form:
let forms = try container.decode([CharacterForm].self, forKey: .forms)
self = .completeCharacterForm(forms)
case .complete:
self = .complete
case .move_cursor:
Expand Down
24 changes: 24 additions & 0 deletions swift/tests/CustardKitTests/DecodeCodableActionTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,29 @@ final class DecodeCodableActionTest: XCTestCase {
}
}

func testDecodeCompleteCharacterForm() {
do {
let target = """
{
"type": "complete_character_form",
"forms": ["katakana", "uppercase"]
}
"""
let decoded = CodableActionData.quickDecode(target: target)
XCTAssertEqual(decoded, .completeCharacterForm([.katakana, .uppercase]))
}
do {
let target = """
{
"type": "complete_character_form",
"forms": ["hiragana"]
}
"""
let decoded = CodableActionData.quickDecode(target: target)
XCTAssertEqual(decoded, .completeCharacterForm([.hiragana]))
}
}

func testDecodeNoArgumentActions() {
do {
let target = """
Expand Down Expand Up @@ -311,6 +334,7 @@ final class DecodeCodableActionTest: XCTestCase {
("testDecodeMoveCursor", testDecodeMoveCursor),
("testDecodeSmartMoveCursor", testDecodeSmartMoveCursor),
("testDecodeMoveTab", testDecodeMoveTab),
("testDecodeCompleteCharacterForm", testDecodeCompleteCharacterForm),
("testDecodeNoArgumentActions", testDecodeNoArgumentActions)
]
}
7 changes: 7 additions & 0 deletions swift/tests/CustardKitTests/EncodeCodableActionTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ final class EncodeCodableActionTest: XCTestCase {
XCTAssertQuickEncodeDecode(CodableActionData.replaceDefault(.init(type: .handakuten, fallbacks: [.default])))
}

func testEncodeCompleteCharacterForm() {
let target = CodableActionData.completeCharacterForm([.katakana, .uppercase])
XCTAssertEqual(target.quickEncodeDecode(), target)
XCTAssertEqual(CodableActionData.completeCharacterForm([.hiragana]).quickEncodeDecode(), .completeCharacterForm([.hiragana]))
}

func testEncodeNoArgumentActions() {
XCTAssertEqual(CodableActionData.smartDeleteDefault.quickEncodeDecode(), .smartDeleteDefault)
XCTAssertEqual(CodableActionData.complete.quickEncodeDecode(), .complete)
Expand All @@ -82,6 +88,7 @@ final class EncodeCodableActionTest: XCTestCase {
("testEncodeMoveCursor", testEncodeMoveCursor),
("testEncodeSmartMoveCursor", testEncodeSmartMoveCursor),
("testEncodeMoveTab", testEncodeMoveTab),
("testEncodeCompleteCharacterForm", testEncodeCompleteCharacterForm),
("testEncodeNoArgumentActions", testEncodeNoArgumentActions)
]
}