Created
October 10, 2016 08:10
-
-
Save ShingoFukuyama/d6a3c33a1de33ff77d8233952d412879 to your computer and use it in GitHub Desktop.
WIP: iOS Keyboard Shortcut for Emacs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UITextView+Ext.swift | |
// BTKeyboardInputTest | |
// | |
// Created by Shingo Fukuyama on 10/10/16. | |
// Copyright © 2016 Shingo Fukuyama. All rights reserved. | |
// | |
import UIKit | |
extension UITextView { | |
func ext_caretTo(position: Int) { | |
guard self.isFirstResponder else { return } | |
if let newPosition = self.ext_position(fromInt: position) { | |
self.ext_caretTo(textPosition: newPosition) | |
} | |
} | |
func ext_caretTo(textPosition position: UITextPosition) { | |
guard self.isFirstResponder else { return } | |
self.selectedTextRange = self.textRange(from: position, to: position) | |
} | |
func ext_caretPosition() -> Int { | |
if let selectedTextRange = self.selectedTextRange { | |
let caretPosition = self.ext_beginningOffset(textPosition: selectedTextRange.start) | |
return caretPosition | |
} | |
return 0 | |
} | |
func ext_selectAll() { | |
self.selectedTextRange = self.textRange(from: self.beginningOfDocument, to: self.endOfDocument) | |
} | |
func ext_beginningOffset(textPosition: UITextPosition) -> Int { | |
return self.offset(from: self.beginningOfDocument, to: textPosition) | |
} | |
func ext_position(fromInt: Int) -> UITextPosition? { | |
return self.position(from: self.beginningOfDocument, in: UITextLayoutDirection.right, offset: fromInt) | |
} | |
func ext_select(from: Int, to: Int) { | |
if let start = self.ext_position(fromInt: from), | |
let end = self.ext_position(fromInt: to) { | |
self.selectedTextRange = self.textRange(from: start, to: end) | |
} | |
} | |
func ext_caretForward() { | |
guard self.isFirstResponder else { return } | |
guard let range = self.selectedTextRange else { return } | |
if let pos = self.position(from: range.start, offset: 1) { | |
self.ext_caretTo(textPosition: pos) | |
} | |
} | |
func ext_caretBackward() { | |
guard self.isFirstResponder else { return } | |
guard let range = self.selectedTextRange else { return } | |
if let pos = self.position(from: range.start, offset: -1) { | |
self.ext_caretTo(textPosition: pos) | |
} | |
} | |
func ext_caretUpward() { | |
guard let range = self.selectedTextRange else { return } | |
guard let lineHeight = self.font?.lineHeight else { return } | |
var caret = self.firstRect(for: range) | |
// At the end of the last line of the document | |
if caret.origin.y == CGFloat.infinity { | |
guard let rangeTo = self.position(from: range.start, offset: -1) else { return } | |
guard let newRange = self.textRange(from: range.start, to: rangeTo) else { return } | |
caret = self.firstRect(for: newRange) | |
caret.origin.y += lineHeight | |
} | |
caret.origin.y = max(caret.origin.y - lineHeight, 0) | |
caret.size.width = 1 | |
if let pos = self.closestPosition(to: caret.origin) { | |
self.selectedTextRange = self.textRange(from: pos, to: pos) | |
} | |
} | |
func ext_caretDownward() { | |
guard let range = self.selectedTextRange else { return } | |
guard let lineHeight = self.font?.lineHeight else { return } | |
var caret = self.firstRect(for: range) | |
// At the end of the last line of the document | |
if caret.origin.y == CGFloat.infinity { | |
return | |
} | |
caret.origin.y = max(caret.origin.y + lineHeight, 0) | |
caret.size.width = 1 | |
if let pos = self.closestPosition(to: caret.origin) { | |
self.selectedTextRange = self.textRange(from: pos, to: pos) | |
} | |
} | |
func ext_setupKeyboardShortcuts(controller: UIViewController) { | |
let cf = UIKeyCommand(input: "f", modifierFlags: .control, action: #selector(ext_caretForward)) | |
let cb = UIKeyCommand(input: "b", modifierFlags: .control, action: #selector(ext_caretBackward)) | |
let cp = UIKeyCommand(input: "p", modifierFlags: .control, action: #selector(ext_caretUpward)) | |
let cn = UIKeyCommand(input: "n", modifierFlags: .control, action: #selector(ext_caretDownward)) | |
controller.addKeyCommand(cf) | |
controller.addKeyCommand(cb) | |
controller.addKeyCommand(cp) | |
controller.addKeyCommand(cn) | |
let clf = UIKeyCommand(input: "f", modifierFlags: .alphaShift, action: #selector(ext_caretForward)) | |
let clb = UIKeyCommand(input: "b", modifierFlags: .alphaShift, action: #selector(ext_caretBackward)) | |
let clp = UIKeyCommand(input: "p", modifierFlags: .alphaShift, action: #selector(ext_caretUpward)) | |
let cln = UIKeyCommand(input: "n", modifierFlags: .alphaShift, action: #selector(ext_caretDownward)) | |
controller.addKeyCommand(clf) | |
controller.addKeyCommand(clb) | |
controller.addKeyCommand(clp) | |
controller.addKeyCommand(cln) | |
// Command+Space cannot override the default one | |
//let sSPC = UIKeyCommand(input: " ", modifierFlags: .command, action: #selector()) | |
//controller.addKeyCommand(sSPC) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment