Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 英語でも予測入力の候補を利用可能に #113

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
10 changes: 3 additions & 7 deletions azooKeyMac/InputController/Actions/ClientAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ enum ClientAction {
case selectPrevCandidate
case selectNumberCandidate(Int)

case selectInputMode(InputMode)
case commitMarkedTextAndSelectInputMode(InputMode)
case selectInputLanguage(InputLanguage)
case commitMarkedTextAndSelectInputLanguage(InputLanguage)

/// MarkedTextを確定して、さらに追加で入力する
case commitMarkedTextAndAppendToMarkedText(String)

Expand Down Expand Up @@ -55,11 +56,6 @@ enum ClientAction {
case hideReplaceSuggestionWindow

case stopComposition

enum InputMode {
case roman
case japanese
}
}

enum ClientActionCallback {
Expand Down
6 changes: 6 additions & 0 deletions azooKeyMac/InputController/InputLanguage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation

enum InputLanguage: Sendable, Equatable, Hashable {
case japanese
case english
}
65 changes: 50 additions & 15 deletions azooKeyMac/InputController/InputState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,34 @@ enum InputState {
case selecting
case replaceSuggestion

struct EventCore: Sendable, Equatable {
var modifierFlags: NSEvent.ModifierFlags
}

func event( // swiftlint:disable:this function_parameter_count
_ event: NSEvent!,
userAction: UserAction,
inputLanguage: InputLanguage,
liveConversionEnabled: Bool,
enableDebugWindow: Bool,
enableSuggestion: Bool
) -> (ClientAction, ClientActionCallback) {
self.event(
eventCore: EventCore(modifierFlags: event.modifierFlags),
userAction: userAction,
inputLanguage: inputLanguage,
liveConversionEnabled: liveConversionEnabled,
enableDebugWindow: enableDebugWindow,
enableSuggestion: enableSuggestion
)
}

// この種のコードは複雑にしかならないので、lintを無効にする
// swiftlint:disable:next cyclomatic_complexity
func event(
_ event: NSEvent!,
func event( // swiftlint:disable:this function_parameter_count
eventCore event: EventCore,
userAction: UserAction,
inputLanguage: InputLanguage,
liveConversionEnabled: Bool,
enableDebugWindow: Bool,
enableSuggestion: Bool
Expand All @@ -28,19 +51,29 @@ enum InputState {
case .none:
switch userAction {
case .input(let string):
return (.appendToMarkedText(string), .transition(.composing))
switch inputLanguage {
case .japanese:
return (.appendToMarkedText(string), .transition(.composing))
case .english:
return (.insertWithoutMarkedText(string), .fallthrough)
}
case .number(let number):
return (.appendToMarkedText(number.inputString), .transition(.composing))
switch inputLanguage {
case .japanese:
return (.appendToMarkedText(number.inputString), .transition(.composing))
case .english:
return (.insertWithoutMarkedText(number.inputString), .fallthrough)
}
case .かな:
return (.selectInputMode(.japanese), .transition(.none))
return (.selectInputLanguage(.japanese), .fallthrough)
case .英数:
return (.selectInputMode(.roman), .transition(.none))
return (.selectInputLanguage(.english), .fallthrough)
case .space:
// Shift+Spaceでは半角スペースを入力
if event.modifierFlags.contains(.shift) {
return (.insertWithoutMarkedText(" "), .transition(.none))
if inputLanguage == .english || event.modifierFlags.contains(.shift) {
return (.insertWithoutMarkedText(" "), .fallthrough)
} else {
return (.insertWithoutMarkedText(" "), .transition(.none))
return (.insertWithoutMarkedText(" "), .fallthrough)
}
case .suggest:
if enableSuggestion {
Expand Down Expand Up @@ -79,9 +112,9 @@ enum InputState {
return (.submitHankakuKatakanaCandidate, .transition(.none))
}
case .かな:
return (.selectInputMode(.japanese), .fallthrough)
return (.consume, .fallthrough)
case .英数:
return (.commitMarkedTextAndSelectInputMode(.roman), .transition(.none))
return (.commitMarkedTextAndSelectInputLanguage(.english), .transition(.none))
case .navigation(let direction):
if direction == .down {
return (.enterCandidateSelectionMode, .transition(.selecting))
Expand Down Expand Up @@ -128,9 +161,9 @@ enum InputState {
return (.submitHankakuKatakanaCandidate, .transition(.none))
}
case .かな:
return (.selectInputMode(.japanese), .fallthrough)
return (.consume, .fallthrough)
case .英数:
return (.commitMarkedTextAndSelectInputMode(.roman), .transition(.none))
return (.commitMarkedTextAndSelectInputLanguage(.english), .transition(.none))
case .navigation(let direction):
if direction == .down {
return (.enterCandidateSelectionMode, .transition(.selecting))
Expand Down Expand Up @@ -208,9 +241,9 @@ enum InputState {
case .editSegment(let count):
return (.editSegment(count), .transition(.selecting))
case .かな:
return (.selectInputMode(.japanese), .fallthrough)
return (.consume, .fallthrough)
case .英数:
return (.commitMarkedTextAndSelectInputMode(.roman), .transition(.none))
return (.commitMarkedTextAndSelectInputLanguage(.english), .transition(.none))
case .unknown, .suggest, .tab:
return (.fallthrough, .fallthrough)
}
Expand All @@ -235,6 +268,8 @@ enum InputState {
return (.submitReplaceSuggestionCandidate, .transition(.none))
case .backspace, .escape:
return (.hideReplaceSuggestionWindow, .transition(.composing))
case .英数:
return (.submitReplaceSuggestionCandidate, .transition(.none))
default:
return (.fallthrough, .fallthrough)
}
Expand Down
8 changes: 7 additions & 1 deletion azooKeyMac/InputController/SegmentsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ final class SegmentsManager {
func makeIterator() -> Array<Element>.Iterator {
text.makeIterator()
}

var isEmpty: Bool {
self.text.isEmpty
}
}

@MainActor
Expand Down Expand Up @@ -486,7 +490,9 @@ final class SegmentsManager {

func getCurrentMarkedText(inputState: InputState) -> MarkedText {
switch inputState {
case .none, .composing:
case .none:
return MarkedText(text: [], selectionRange: .notFound)
case .composing:
let text = if self.lastOperation == .delete {
// 削除のあとは常にひらがなを示す
self.composingText.convertTarget
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,94 @@
import Cocoa

enum InputMode {

extension UserAction {
// この種のコードは複雑にしかならないので、lintを無効にする
// swiftlint:disable:next cyclomatic_complexity
static func getUserAction(event: NSEvent) -> UserAction {
static func getUserAction(event: NSEvent, inputLanguage: InputLanguage) -> UserAction {
// see: https://developer.mozilla.org/ja/docs/Web/API/UI_Events/Keyboard_event_code_values#mac_%E3%81%A7%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E5%80%A4
let keyMap: (String) -> String = switch inputLanguage {
case .english: { $0 }
case .japanese:
if Config.TypeCommaAndPeriod().value {
{
KeyMap.h2zMap($0)
.replacingOccurrences(of: "、", with: ",")
.replacingOccurrences(of: "。", with: ".")
}
} else {
KeyMap.h2zMap
}
}
switch event.keyCode {
case 0x04: // 'H'
// Ctrl + H is binding for backspace
if event.modifierFlags.contains(.control) {
return .backspace
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x23: // Control + p
if event.modifierFlags.contains(.control) {
return .navigation(.up)
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x2D: // Control + n
if event.modifierFlags.contains(.control) {
return .navigation(.down)
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x03: // Control + f
if event.modifierFlags.contains(.control) {
return .navigation(.right)
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x22: // Control + i
if event.modifierFlags.contains(.control) {
return .editSegment(-1) // Shift segment cursor left
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x1F: // Control + o
if event.modifierFlags.contains(.control) {
return .editSegment(1) // Shift segment cursor right
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x26: // Control + j
if event.modifierFlags.contains(.control) {
return .function(.six)
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x28: // Control + k
if event.modifierFlags.contains(.control) {
return .function(.seven)
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
case 0x01: // Control + s
if event.modifierFlags.contains(.control) {
return .suggest
} else if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
Expand All @@ -93,37 +105,31 @@ enum InputMode {
case 93: // Yen
switch (Config.TypeBackSlash().value, event.modifierFlags.contains(.shift), event.modifierFlags.contains(.option)) {
case (_, true, _):
return .input(KeyMap.h2zMap("|"))
return .input(keyMap("|"))
case (true, false, false), (false, false, true):
return .input(KeyMap.h2zMap("\\"))
return .input(keyMap("\\"))
case (true, false, true), (false, false, false):
return .input(KeyMap.h2zMap("¥"))
return .input(keyMap("¥"))
}
case 43: // Comma
switch (Config.TypeCommaAndPeriod().value, event.modifierFlags.contains(.shift)) {
case (true, false):
return .input(KeyMap.h2zMap(","))
case (false, false):
return .input(KeyMap.h2zMap("、"))
case (_, true):
if event.modifierFlags.contains(.shift) {
if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
} else {
return .input(keyMap(","))
}
case 47: // Period
switch (Config.TypeCommaAndPeriod().value, event.modifierFlags.contains(.shift)) {
case (true, false):
return .input(KeyMap.h2zMap("."))
case (false, false):
return .input(KeyMap.h2zMap("。"))
case (_, true):
if event.modifierFlags.contains(.shift) {
if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
} else {
return .input(keyMap("."))
}
case 97: // F6
return .function(.six)
Expand Down Expand Up @@ -164,7 +170,7 @@ enum InputMode {
}
default:
if let text = event.characters, isPrintable(text) {
return .input(KeyMap.h2zMap(text))
return .input(keyMap(text))
} else {
return .unknown
}
Expand Down
Loading