Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ShingoFukuyama/d6a3c33a1de33ff77d8233952d412879 to your computer and use it in GitHub Desktop.
Save ShingoFukuyama/d6a3c33a1de33ff77d8233952d412879 to your computer and use it in GitHub Desktop.
WIP: iOS Keyboard Shortcut for Emacs
//
// 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