mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-27 15:53:31 +03:00
Reformat
This commit is contained in:
parent
b31a0e40e1
commit
cd798dd2fb
@ -4,12 +4,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
import RxSwift
|
|
||||||
import MessagePack
|
import MessagePack
|
||||||
|
import RxSwift
|
||||||
|
|
||||||
extension NvimView {
|
public extension NvimView {
|
||||||
|
override func keyDown(with event: NSEvent) {
|
||||||
override public func keyDown(with event: NSEvent) {
|
|
||||||
self.keyDownDone = false
|
self.keyDownDone = false
|
||||||
|
|
||||||
NSCursor.setHiddenUntilMouseMoves(true)
|
NSCursor.setHiddenUntilMouseMoves(true)
|
||||||
@ -19,9 +18,8 @@ extension NvimView {
|
|||||||
|| (self.isRightOptionMeta && modifierFlags.contains(.rightOption))
|
|| (self.isRightOptionMeta && modifierFlags.contains(.rightOption))
|
||||||
|
|
||||||
if !isMeta {
|
if !isMeta {
|
||||||
let cocoaHandledEvent
|
let cocoaHandledEvent = NSTextInputContext.current?.handleEvent(event) ?? false
|
||||||
= NSTextInputContext.current?.handleEvent(event) ?? false
|
if self.keyDownDone, cocoaHandledEvent { return }
|
||||||
if self.keyDownDone && cocoaHandledEvent { return }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let capslock = modifierFlags.contains(.capsLock)
|
let capslock = modifierFlags.contains(.capsLock)
|
||||||
@ -46,41 +44,27 @@ extension NvimView {
|
|||||||
self.keyDownDone = true
|
self.keyDownDone = true
|
||||||
}
|
}
|
||||||
|
|
||||||
public func insertText(_ object: Any, replacementRange: NSRange) {
|
func insertText(_ object: Any, replacementRange: NSRange) {
|
||||||
self.log.debug("\(object) with \(replacementRange)")
|
self.log.debug("\(object) with \(replacementRange)")
|
||||||
|
|
||||||
let text: String
|
let text: String
|
||||||
switch object {
|
switch object {
|
||||||
|
case let string as String: text = string
|
||||||
case let string as String:
|
case let attributedString as NSAttributedString: text = attributedString.string
|
||||||
text = string
|
default: return
|
||||||
|
|
||||||
case let attributedString as NSAttributedString:
|
|
||||||
text = attributedString.string
|
|
||||||
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let length = self.markedText?.count ?? 0
|
let length = self.markedText?.count ?? 0
|
||||||
try? self.bridge
|
try? self.bridge
|
||||||
.deleteCharacters(
|
.deleteCharacters(length, andInputEscapedString: self.vimPlainString(text))
|
||||||
length,
|
|
||||||
andInputEscapedString: self.vimPlainString(text)
|
|
||||||
)
|
|
||||||
.wait()
|
.wait()
|
||||||
|
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
self.ugrid.unmarkCell(at: self.markedPosition)
|
self.ugrid.unmarkCell(at: self.markedPosition)
|
||||||
self.markForRender(position: self.markedPosition)
|
self.markForRender(position: self.markedPosition)
|
||||||
if self.ugrid.isNextCellEmpty(self.markedPosition) {
|
if self.ugrid.isNextCellEmpty(self.markedPosition) {
|
||||||
self.ugrid.unmarkCell(
|
self.ugrid.unmarkCell(at: self.markedPosition.advancing(row: 0, column: 1))
|
||||||
at: self.markedPosition.advancing(row: 0, column: 1)
|
self.markForRender(position: self.markedPosition.advancing(row: 0, column: 1))
|
||||||
)
|
|
||||||
self.markForRender(
|
|
||||||
position: self.markedPosition.advancing(row: 0, column: 1)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +74,7 @@ extension NvimView {
|
|||||||
self.keyDownDone = true
|
self.keyDownDone = true
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func doCommand(by aSelector: Selector) {
|
override func doCommand(by aSelector: Selector) {
|
||||||
if self.responds(to: aSelector) {
|
if self.responds(to: aSelector) {
|
||||||
self.log.debug("calling \(aSelector)")
|
self.log.debug("calling \(aSelector)")
|
||||||
self.perform(aSelector, with: self)
|
self.perform(aSelector, with: self)
|
||||||
@ -99,40 +83,35 @@ extension NvimView {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.log.debug("\(aSelector) not implemented, " +
|
self.log.debug("\(aSelector) not implemented, forwarding input to neovim")
|
||||||
"forwarding input to neovim")
|
|
||||||
self.keyDownDone = false
|
self.keyDownDone = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func performKeyEquivalent(with event: NSEvent) -> Bool {
|
override func performKeyEquivalent(with event: NSEvent) -> Bool {
|
||||||
if .keyDown != event.type { return false }
|
if event.type != .keyDown { return false }
|
||||||
let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
|
let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
|
||||||
|
|
||||||
// <C-Tab> & <C-S-Tab> do not trigger keyDown events.
|
// <C-Tab> & <C-S-Tab> do not trigger keyDown events.
|
||||||
// Catch the key event here and pass it to keyDown.
|
// Catch the key event here and pass it to keyDown.
|
||||||
// By rogual in NeoVim dot app:
|
// By rogual in NeoVim dot app:
|
||||||
// https://github.com/rogual/neovim-dot-app/pull/248/files
|
// https://github.com/rogual/neovim-dot-app/pull/248/files
|
||||||
if flags.contains(.control) && 48 == event.keyCode {
|
if flags.contains(.control), event.keyCode == 48 {
|
||||||
self.keyDown(with: event)
|
self.keyDown(with: event)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emoji menu: Cmd-Ctrl-Space
|
// Emoji menu: Cmd-Ctrl-Space
|
||||||
if flags.contains([.command, .control]) && 49 == event.keyCode {
|
if flags.contains([.command, .control]), event.keyCode == 49 { return false }
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Space key (especially in combination with modifiers) can result in
|
// Space key (especially in combination with modifiers) can result in
|
||||||
// unexpected chars (e.g. ctrl-space = \0), so catch the event early and
|
// unexpected chars (e.g. ctrl-space = \0), so catch the event early and
|
||||||
// pass it to keyDown.
|
// pass it to keyDown.
|
||||||
if 49 == event.keyCode {
|
if event.keyCode == 49 {
|
||||||
self.keyDown(with: event)
|
self.keyDown(with: event)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let chars = event.characters else {
|
guard let chars = event.characters else { return false }
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Control code \0 causes rpc parsing problems.
|
// Control code \0 causes rpc parsing problems.
|
||||||
// So we escape as early as possible
|
// So we escape as early as possible
|
||||||
@ -149,7 +128,7 @@ extension NvimView {
|
|||||||
// For the following two conditions:
|
// For the following two conditions:
|
||||||
// See special cases in vim/os_win32.c from vim sources
|
// See special cases in vim/os_win32.c from vim sources
|
||||||
// Also mentioned in MacVim's KeyBindings.plist
|
// Also mentioned in MacVim's KeyBindings.plist
|
||||||
if .control == flags && chars == "6" {
|
if flags == .control, chars == "6" {
|
||||||
self.api
|
self.api
|
||||||
.input(keys: "\u{1e}", errWhenBlocked: false) // AKA ^^
|
.input(keys: "\u{1e}", errWhenBlocked: false) // AKA ^^
|
||||||
.subscribe(onError: { [weak self] error in
|
.subscribe(onError: { [weak self] error in
|
||||||
@ -159,7 +138,7 @@ extension NvimView {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if .control == flags && chars == "2" {
|
if flags == .control, chars == "2" {
|
||||||
// <C-2> should generate \0, escaping as above
|
// <C-2> should generate \0, escaping as above
|
||||||
self.api
|
self.api
|
||||||
.input(keys: self.wrapNamedKeys("Nul"), errWhenBlocked: false)
|
.input(keys: self.wrapNamedKeys("Nul"), errWhenBlocked: false)
|
||||||
@ -175,49 +154,37 @@ extension NvimView {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setMarkedText(
|
func setMarkedText(_ object: Any, selectedRange: NSRange, replacementRange: NSRange) {
|
||||||
_ object: Any,
|
self.log.debug(
|
||||||
selectedRange: NSRange,
|
"object: \(object), selectedRange: \(selectedRange), replacementRange: \(replacementRange)"
|
||||||
replacementRange: NSRange
|
)
|
||||||
) {
|
|
||||||
self.log.debug("object: \(object), selectedRange: \(selectedRange), " +
|
|
||||||
"replacementRange: \(replacementRange)")
|
|
||||||
|
|
||||||
defer { self.keyDownDone = true }
|
defer { self.keyDownDone = true }
|
||||||
|
|
||||||
if self.markedText == nil {
|
if self.markedText == nil { self.markedPosition = self.ugrid.cursorPosition }
|
||||||
self.markedPosition = self.ugrid.cursorPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldMarkedTextLength = self.markedText?.count ?? 0
|
let oldMarkedTextLength = self.markedText?.count ?? 0
|
||||||
|
|
||||||
switch object {
|
switch object {
|
||||||
case let string as String:
|
case let string as String: self.markedText = string
|
||||||
self.markedText = string
|
case let attributedString as NSAttributedString: self.markedText = attributedString.string
|
||||||
case let attributedString as NSAttributedString:
|
default: self.markedText = String(describing: object) // should not occur
|
||||||
self.markedText = attributedString.string
|
|
||||||
default:
|
|
||||||
self.markedText = String(describing: object) // should not occur
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if replacementRange != .notFound {
|
if replacementRange != .notFound {
|
||||||
guard let newMarkedPosition = self.ugrid.firstPosition(
|
guard let newMarkedPosition = self.ugrid.firstPosition(
|
||||||
fromFlatCharIndex: replacementRange.location
|
fromFlatCharIndex: replacementRange.location
|
||||||
) else {
|
) else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.markedPosition = newMarkedPosition
|
self.markedPosition = newMarkedPosition
|
||||||
|
|
||||||
self.log.debug("Deleting \(replacementRange.length) " +
|
self.log.debug("Deleting \(replacementRange.length) and inputting \(self.markedText!)")
|
||||||
"and inputting \(self.markedText!)")
|
|
||||||
try? self.bridge.deleteCharacters(
|
try? self.bridge.deleteCharacters(
|
||||||
replacementRange.length,
|
replacementRange.length,
|
||||||
andInputEscapedString: self.vimPlainString(self.markedText!)
|
andInputEscapedString: self.vimPlainString(self.markedText!)
|
||||||
).wait()
|
).wait()
|
||||||
} else {
|
} else {
|
||||||
self.log.debug("Deleting \(oldMarkedTextLength) " +
|
self.log.debug("Deleting \(oldMarkedTextLength) and inputting \(self.markedText!)")
|
||||||
"and inputting \(self.markedText!)")
|
|
||||||
try? self.bridge.deleteCharacters(
|
try? self.bridge.deleteCharacters(
|
||||||
oldMarkedTextLength,
|
oldMarkedTextLength,
|
||||||
andInputEscapedString: self.vimPlainString(self.markedText!)
|
andInputEscapedString: self.vimPlainString(self.markedText!)
|
||||||
@ -227,7 +194,7 @@ extension NvimView {
|
|||||||
self.keyDownDone = true
|
self.keyDownDone = true
|
||||||
}
|
}
|
||||||
|
|
||||||
public func unmarkText() {
|
func unmarkText() {
|
||||||
let position = self.markedPosition
|
let position = self.markedPosition
|
||||||
self.ugrid.unmarkCell(at: position)
|
self.ugrid.unmarkCell(at: position)
|
||||||
self.markForRender(position: position)
|
self.markForRender(position: position)
|
||||||
@ -247,7 +214,7 @@ extension NvimView {
|
|||||||
Emoji-popup at the rect by firstRectForCharacterRange(actualRange:) where
|
Emoji-popup at the rect by firstRectForCharacterRange(actualRange:) where
|
||||||
the first range is the result of this method.
|
the first range is the result of this method.
|
||||||
*/
|
*/
|
||||||
public func selectedRange() -> NSRange {
|
func selectedRange() -> NSRange {
|
||||||
// When the app starts and the Hangul input method is selected,
|
// When the app starts and the Hangul input method is selected,
|
||||||
// this method gets called very early...
|
// this method gets called very early...
|
||||||
guard self.ugrid.hasData else {
|
guard self.ugrid.hasData else {
|
||||||
@ -257,9 +224,7 @@ extension NvimView {
|
|||||||
|
|
||||||
let result: NSRange
|
let result: NSRange
|
||||||
result = NSRange(
|
result = NSRange(
|
||||||
location: self.ugrid.flatCharIndex(
|
location: self.ugrid.flatCharIndex(forPosition: self.ugrid.cursorPosition),
|
||||||
forPosition: self.ugrid.cursorPosition
|
|
||||||
),
|
|
||||||
length: 0
|
length: 0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -267,7 +232,7 @@ extension NvimView {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public func markedRange() -> NSRange {
|
func markedRange() -> NSRange {
|
||||||
guard let marked = self.markedText else {
|
guard let marked = self.markedText else {
|
||||||
self.log.debug("No marked text, returning not found")
|
self.log.debug("No marked text, returning not found")
|
||||||
return .notFound
|
return .notFound
|
||||||
@ -282,76 +247,56 @@ extension NvimView {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public func hasMarkedText() -> Bool {
|
func hasMarkedText() -> Bool { self.markedText != nil }
|
||||||
return self.markedText != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public func attributedSubstring(
|
func attributedSubstring(
|
||||||
forProposedRange aRange: NSRange,
|
forProposedRange aRange: NSRange,
|
||||||
actualRange: NSRangePointer?
|
actualRange _: NSRangePointer?
|
||||||
) -> NSAttributedString? {
|
) -> NSAttributedString? {
|
||||||
|
|
||||||
self.log.debug("\(aRange)")
|
self.log.debug("\(aRange)")
|
||||||
if aRange.location == NSNotFound {
|
if aRange.location == NSNotFound { return nil }
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard
|
guard
|
||||||
let position = self.ugrid.firstPosition(
|
let position = self.ugrid.firstPosition(fromFlatCharIndex: aRange.location),
|
||||||
fromFlatCharIndex: aRange.location
|
|
||||||
),
|
|
||||||
let inclusiveEndPosition = self.ugrid.lastPosition(
|
let inclusiveEndPosition = self.ugrid.lastPosition(
|
||||||
fromFlatCharIndex: aRange.location + aRange.length - 1
|
fromFlatCharIndex: aRange.location + aRange.length - 1
|
||||||
)
|
)
|
||||||
else {
|
else { return nil }
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
self.log.debug("\(position) ... \(inclusiveEndPosition)")
|
self.log.debug("\(position) ... \(inclusiveEndPosition)")
|
||||||
let string = self.ugrid.cells[position.row...inclusiveEndPosition.row]
|
let string = self.ugrid.cells[position.row...inclusiveEndPosition.row]
|
||||||
.map { row in
|
.map { row in
|
||||||
row.filter { cell in
|
row.filter { cell in
|
||||||
return aRange.location <= cell.flatCharIndex
|
aRange.location <= cell.flatCharIndex && cell.flatCharIndex <= aRange.inclusiveEndIndex
|
||||||
&& cell.flatCharIndex <= aRange.inclusiveEndIndex
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.flatMap { $0 }
|
.flatMap { $0 }
|
||||||
.map { $0.string }
|
.map(\.string)
|
||||||
.joined()
|
.joined()
|
||||||
|
|
||||||
let delta = aRange.length - string.utf16.count
|
let delta = aRange.length - string.utf16.count
|
||||||
if delta != 0 {
|
if delta != 0 { self.log.debug("delta = \(delta)!") }
|
||||||
self.log.debug("delta = \(delta)!")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.log.debug("returning '\(string)'")
|
self.log.debug("returning '\(string)'")
|
||||||
return NSAttributedString(string: string)
|
return NSAttributedString(string: string)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func validAttributesForMarkedText() -> [NSAttributedString.Key] {
|
func validAttributesForMarkedText() -> [NSAttributedString.Key] { [] }
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
public func firstRect(
|
func firstRect(forCharacterRange aRange: NSRange, actualRange _: NSRangePointer?) -> NSRect {
|
||||||
forCharacterRange aRange: NSRange, actualRange: NSRangePointer?
|
guard let position = self.ugrid.firstPosition(fromFlatCharIndex: aRange.location) else {
|
||||||
) -> NSRect {
|
|
||||||
guard let position = self.ugrid.firstPosition(
|
|
||||||
fromFlatCharIndex: aRange.location
|
|
||||||
) else {
|
|
||||||
return CGRect.zero
|
return CGRect.zero
|
||||||
}
|
}
|
||||||
|
|
||||||
self.log.debug("\(aRange)-> \(position.row):\(position.column)")
|
self.log.debug("\(aRange)-> \(position.row):\(position.column)")
|
||||||
|
|
||||||
let resultInSelf = self.rect(forRow: position.row, column: position.column)
|
let resultInSelf = self.rect(forRow: position.row, column: position.column)
|
||||||
let result = self.window?.convertToScreen(
|
let result = self.window?.convertToScreen(self.convert(resultInSelf, to: nil))
|
||||||
self.convert(resultInSelf, to: nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
return result!
|
return result!
|
||||||
}
|
}
|
||||||
|
|
||||||
public func characterIndex(for aPoint: NSPoint) -> Int {
|
func characterIndex(for aPoint: NSPoint) -> Int {
|
||||||
let position = self.position(at: aPoint)
|
let position = self.position(at: aPoint)
|
||||||
let result = self.ugrid.flatCharIndex(forPosition: position)
|
let result = self.ugrid.flatCharIndex(forPosition: position)
|
||||||
|
|
||||||
@ -360,7 +305,7 @@ extension NvimView {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func vimModifierFlags(_ modifierFlags: NSEvent.ModifierFlags) -> String? {
|
internal func vimModifierFlags(_ modifierFlags: NSEvent.ModifierFlags) -> String? {
|
||||||
var result = ""
|
var result = ""
|
||||||
|
|
||||||
let control = modifierFlags.contains(.control)
|
let control = modifierFlags.contains(.control)
|
||||||
@ -368,34 +313,19 @@ extension NvimView {
|
|||||||
let command = modifierFlags.contains(.command)
|
let command = modifierFlags.contains(.command)
|
||||||
let shift = modifierFlags.contains(.shift)
|
let shift = modifierFlags.contains(.shift)
|
||||||
|
|
||||||
if control {
|
if control { result += "C-" }
|
||||||
result += "C-"
|
if option { result += "M-" }
|
||||||
}
|
if command { result += "D-" }
|
||||||
|
if shift { result += "S-" }
|
||||||
|
|
||||||
if option {
|
if result.count > 0 { return result }
|
||||||
result += "M-"
|
|
||||||
}
|
|
||||||
|
|
||||||
if command {
|
|
||||||
result += "D-"
|
|
||||||
}
|
|
||||||
|
|
||||||
if shift {
|
|
||||||
result += "S-"
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.count > 0 {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapNamedKeys(_ string: String) -> String {
|
internal func wrapNamedKeys(_ string: String) -> String { "<\(string)>" }
|
||||||
return "<\(string)>"
|
|
||||||
}
|
|
||||||
|
|
||||||
func vimPlainString(_ string: String) -> String {
|
internal func vimPlainString(_ string: String) -> String {
|
||||||
return string.replacingOccurrences(of: "<", with: self.wrapNamedKeys("lt"))
|
string.replacingOccurrences(of: "<", with: self.wrapNamedKeys("lt"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user