| | |
| | | ) -> [QuickSearchIndexedField] { |
| | | let names = uniqueOrdered([appName] + localizedNames) |
| | | let nameFields = names.map { |
| | | let allowsRomanizedFuzzy = containsNonLatinLetter($0) |
| | | return QuickSearchIndexedField( |
| | | kind: .name, |
| | | text: $0, |
| | | normalized: normalizeField($0), |
| | | acronym: acronym(for: $0), |
| | | pinyinCandidates: pinyinCandidates(for: $0), |
| | | allowPinyinSubstring: allowsRomanizedFuzzy, |
| | | allowPinyinFuzzySubsequence: allowsRomanizedFuzzy |
| | | pinyinCandidates: pinyinCandidates(for: $0, includeLatin: true), |
| | | allowPinyinSubstring: true, |
| | | allowPinyinFuzzySubsequence: true |
| | | ) |
| | | } |
| | | let tagFields = tagNames.map { |
| | |
| | | .lowercased() |
| | | } |
| | | |
| | | private static func pinyinCandidates(for value: String) -> [String] { |
| | | guard containsNonLatinLetter(value) else { return [] } |
| | | private static func pinyinCandidates(for value: String, includeLatin: Bool = false) -> [String] { |
| | | guard includeLatin || containsNonLatinLetter(value) else { return [] } |
| | | let mutable = NSMutableString(string: value) |
| | | CFStringTransform(mutable, nil, kCFStringTransformToLatin, false) |
| | | CFStringTransform(mutable, nil, kCFStringTransformStripCombiningMarks, false) |
| | |
| | | field.placeholderString = placeholder |
| | | field.delegate = context.coordinator |
| | | field.onCommand = onCommand |
| | | context.coordinator.onCommand = onCommand |
| | | field.setAccessibilityLabel(tr("quickSearch.inputAccessibility")) |
| | | context.coordinator.field = field |
| | | requestFocus(field) |
| | |
| | | } |
| | | field.placeholderString = placeholder |
| | | field.onCommand = onCommand |
| | | context.coordinator.onCommand = onCommand |
| | | if context.coordinator.lastFocusToken != focusToken { |
| | | context.coordinator.lastFocusToken = focusToken |
| | | requestFocus(field) |
| | |
| | | final class Coordinator: NSObject, NSTextFieldDelegate { |
| | | var text: Binding<String> |
| | | var lastFocusToken = 0 |
| | | var onCommand: ((QuickSearchCommand) -> Void)? |
| | | weak var field: NSTextField? |
| | | |
| | | init(text: Binding<String>) { |
| | |
| | | guard let field = obj.object as? NSTextField else { return } |
| | | text.wrappedValue = field.stringValue |
| | | } |
| | | |
| | | func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { |
| | | switch commandSelector { |
| | | case #selector(NSResponder.moveUp(_:)): |
| | | onCommand?(.moveUp) |
| | | return true |
| | | case #selector(NSResponder.moveDown(_:)): |
| | | onCommand?(.moveDown) |
| | | return true |
| | | case #selector(NSResponder.insertNewline(_:)): |
| | | onCommand?(.submit) |
| | | return true |
| | | case #selector(NSResponder.insertNewlineIgnoringFieldEditor(_:)): |
| | | onCommand?(.submit) |
| | | return true |
| | | case #selector(NSResponder.cancelOperation(_:)): |
| | | onCommand?(.dismiss) |
| | | return true |
| | | default: |
| | | return false |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |