Skip to content

Commit

Permalink
Use Highlightr as syntax highlighter
Browse files Browse the repository at this point in the history
  • Loading branch information
ColdGrub1384 committed Sep 16, 2020
1 parent 61af033 commit 66f62dd
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 198 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
[submodule "InputAssistant"]
path = InputAssistant
url = https://github.com/ColdGrub1384/InputAssistant.git
[submodule "TextKit_LineNumbers"]
path = TextKit_LineNumbers
url = https://github.com/ColdGrub1384/TextKit_LineNumbers.git
88 changes: 0 additions & 88 deletions Pyto/Model/Extensions/EditorViewController+highlighting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,94 +57,6 @@ extension EditorViewController {

let errorColor = #colorLiteral(red: 0.6743632277, green: 0.1917540668, blue: 0.1914597603, alpha: 1)

guard self.parent?.presentedViewController == nil, self.view.window != nil else {
self.lineNumberError = lineNumber
return
}

guard lineNumber > 0 else {
return
}

var lines = [String]()
let allLines = self.textView.text.components(separatedBy: "\n")

for (i, line) in allLines.enumerated() {
let currentLineNumber = i+1

guard currentLineNumber <= lineNumber else {
break
}

lines.append(line)
}

let errorRange = NSRange(location: lines.joined(separator: "\n").count, length: 0)

self.textView.contentTextView.selectedRange = errorRange

let errorView = UITextView()
errorView.textColor = .white
errorView.isEditable = false
errorView.backgroundColor = errorColor

let title = NSAttributedString(string: "\n"+(Python.shared.errorType ?? ""), attributes: [
.font : UIFont(name: "Menlo-Bold", size: UIFont.systemFontSize) ?? UIFont.systemFont(ofSize: UIFont.systemFontSize),
.foregroundColor: UIColor.white
])

let message = NSAttributedString(string: Python.shared.errorReason ?? "", attributes: [
.font : UIFont(name: "Menlo", size: UIFont.systemFontSize) ?? UIFont.systemFont(ofSize: UIFont.systemFontSize),
.foregroundColor: UIColor.white
])

let attributedText = NSMutableAttributedString(attributedString: title)
attributedText.append(NSAttributedString(string: "\n\n"))
attributedText.append(message)
errorView.attributedText = attributedText

class ErrorViewController: UIViewController, UIAdaptivePresentationControllerDelegate {

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

if UIDevice.current.userInterfaceIdiom != .pad && traitCollection.horizontalSizeClass == .regular {
dismiss(animated: true, completion: nil)
}
}

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
}

let errorVC = ErrorViewController()
errorView.backgroundColor = errorColor
errorVC.view = errorView
errorVC.preferredContentSize = CGSize(width: 300, height: 100)
errorVC.modalPresentationStyle = .popover
errorVC.presentationController?.delegate = errorVC
errorVC.popoverPresentationController?.backgroundColor = errorColor

if let selectedTextRange = self.textView.contentTextView.selectedTextRange {
errorVC.popoverPresentationController?.sourceView = self.textView.contentTextView
errorVC.popoverPresentationController?.sourceRect = self.textView.contentTextView.caretRect(for: selectedTextRange.end)
} else {
errorVC.popoverPresentationController?.sourceView = self.textView.contentTextView
errorVC.popoverPresentationController?.sourceRect = self.textView.contentTextView.bounds
}

if self.view.frame.height > 0 {

if UIDevice.current.userInterfaceIdiom != .pad && self.traitCollection.horizontalSizeClass == .regular {
// My brain isn't able to invert this boolean lol I'm dumb
print("Nein")
} else {
self.textView.contentTextView.becomeFirstResponder()
self.present(errorVC, animated: true, completion: nil)
}
}

self.highlight(at: lineNumber-1, with: errorColor.withAlphaComponent(0.5))
}
}
Expand Down
18 changes: 18 additions & 0 deletions Pyto/Model/Extensions/UITextView+contentTextView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// UITextView+contentTextView.swift
// Pyto
//
// Created by Adrian Labbé on 31-07-20.
// Copyright © 2020 Adrian Labbé. All rights reserved.
//

import UIKit

// Because I replaced `SyntaxTextView` to `UITextView`

extension UITextView {

var contentTextView: UITextView {
return self
}
}
129 changes: 76 additions & 53 deletions Pyto/UI/View Controllers/ConsoleViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,8 @@ import SwiftUI
DispatchQueue.main.async {
for scene in UIApplication.shared.connectedScenes {
if let window = (scene as? UIWindowScene)?.windows.first {
if let vc = window.topViewController as? EditorSplitViewController {
vc.console.suggestions = self.suggestions as? [String] ?? []
if let vc = editor(in: window) {
vc.console?.suggestions = self.suggestions as? [String] ?? []
}
}
}
Expand Down Expand Up @@ -766,13 +766,23 @@ import SwiftUI
}
#endif

private var isCompleting = false

private var codeCompletionTimer: Timer?

private let codeCompletionQueue = DispatchQueue.global()

// MARK: - View controller

override open func viewDidLoad() {
super.viewDidLoad()

#if MAIN
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange(_:)), name: ThemeDidChangeNotification, object: nil)

NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { [weak self] (notif) in
self?.themeDidChange(notif)
}
#endif

edgesForExtendedLayout = []
Expand Down Expand Up @@ -802,32 +812,27 @@ import SwiftUI
#if MAIN
override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

if #available(iOS 13.0, *) {
guard view.window?.windowScene?.activationState != .background else {
themeDidChange(nil)
return
}
}

themeDidChange(nil)

#if Xcode11
guard view.window?.windowScene?.activationState != .background else {
return
}
#endif

let attrString = NSMutableAttributedString(attributedString: textView.attributedText)
attrString.removeAttribute(.backgroundColor, range: NSRange(location: 0, length: attrString.length))
textView.attributedText = attrString
}
#endif

open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

if !ConsoleViewController.visibles.contains(self) {
ConsoleViewController.visibles.append(self)
}
}

override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

textView.frame = view.safeAreaLayoutGuide.layoutFrame
textView.frame.size.height -= 44
Expand All @@ -837,7 +842,7 @@ import SwiftUI

if movableTextField == nil {
movableTextField = MovableTextField(console: self)
movableTextField?.placeholder = prompt ?? ""
movableTextField?.setPrompt(prompt ?? "")
}
movableTextField?.show()
#if MAIN
Expand All @@ -849,25 +854,49 @@ import SwiftUI
return
}

Python.shared.run(code: """
try:
import jedi
import console
import pyto
namespace = console.__repl_namespace__['\((self.parent as! EditorSplitViewController).editor?.document!.fileURL.lastPathComponent.replacingOccurrences(of: "'", with: "\\'") ?? "")']
script = jedi.Interpreter('\(text.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "'", with: "\\'"))', [namespace])
let code =
"""
try:
import jedi
import console
import pyto
namespace = console.__repl_namespace__['\((self.parent as! EditorSplitViewController).editor?.document!.fileURL.lastPathComponent.replacingOccurrences(of: "'", with: "\\'") ?? "")']
script = jedi.Interpreter('\(text.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "'", with: "\\'"))', [namespace])
suggestions = []
completions = []
for completion in script.complete():
suggestions.append(completion.name)
completions.append(completion.complete)
suggestions = []
completions = []
for completion in script.complete():
suggestions.append(completion.name)
completions.append(completion.complete)
pyto.ConsoleViewController.suggestions = suggestions
pyto.ConsoleViewController.completions = completions
except Exception as e:
pass
"""

func complete() {
DispatchQueue.global().async {
self.isCompleting = true

pyto.ConsoleViewController.suggestions = suggestions
pyto.ConsoleViewController.completions = completions
except Exception as e:
pass
""")
self.codeCompletionQueue.async {
Python.pythonShared?.perform(#selector(PythonRuntime.runCode(_:)), with: code)
self.isCompleting = false
}
}
}

if self.isCompleting { // A timer so it doesn't block the main thread
self.codeCompletionTimer?.invalidate()
self.codeCompletionTimer = Timer.scheduledTimer(withTimeInterval: 0.001, repeats: true, block: { (timer) in
if !self.isCompleting && timer.isValid {
complete()
timer.invalidate()
}
})
} else {
complete()
}
}
#endif
movableTextField?.handler = { text in
Expand All @@ -880,7 +909,7 @@ import SwiftUI
#endif

self.movableTextField?.currentInput = nil
self.movableTextField?.placeholder = ""
self.movableTextField?.setPrompt("")

#if MAIN

Expand All @@ -890,10 +919,6 @@ import SwiftUI
self.movableTextField?.history.insert(text, at: 0)
self.movableTextField?.historyIndex = -1

if !self.highlightInput {
self.movableTextField?.textField.resignFirstResponder()
}

self.completions = []
#endif

Expand Down Expand Up @@ -978,17 +1003,6 @@ import SwiftUI
#endif
}

open override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)

if let i = ConsoleViewController.visibles.firstIndex(of: self) {
ConsoleViewController.visibles.remove(at: i)
}

movableTextField?.toolbar.removeFromSuperview()
movableTextField = nil
}

override open func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
super.dismiss(animated: flag, completion: completion)

Expand All @@ -1006,16 +1020,25 @@ import SwiftUI
super.viewDidLayoutSubviews()

let wasFirstResponder = movableTextField?.textField.isFirstResponder ?? false
movableTextField?.textField.resignFirstResponder()
let isREPL = !(!(editorSplitViewController is REPLViewController) && !(editorSplitViewController is RunModuleViewController))

if #available(iOS 14.0, *), isREPL {
} else {
movableTextField?.textField.resignFirstResponder()
}

movableTextField?.toolbar.frame.size.width = view.safeAreaLayoutGuide.layoutFrame.width
movableTextField?.toolbar.frame.origin.x = view.safeAreaInsets.left
textView.frame = view.safeAreaLayoutGuide.layoutFrame
textView.frame.size.height = view.safeAreaLayoutGuide.layoutFrame.height-44
textView.frame.origin.y = view.safeAreaLayoutGuide.layoutFrame.origin.y
if wasFirstResponder {

if #available(iOS 14.0, *), isREPL {
} else if wasFirstResponder {
movableTextField?.textField.becomeFirstResponder()
}
movableTextField?.toolbar.isHidden = (view.frame.size.height == 0 )

movableTextField?.toolbar.isHidden = (view.frame.size.height == 0)
#if MAIN
movableTextField?.applyTheme()
#endif
Expand All @@ -1030,7 +1053,7 @@ import SwiftUI

#if MAIN
if numberOfSuggestionsInInputAssistantView() != 0 {
commands.append(UIKeyCommand(input: "\t", modifierFlags: [], action: #selector(nextSuggestion), discoverabilityTitle: Localizable.nextSuggestion))
commands.append(UIKeyCommand.command(input: "\t", modifierFlags: [], action: #selector(nextSuggestion), discoverabilityTitle: Localizable.nextSuggestion))
}
#endif

Expand Down
Loading

0 comments on commit 66f62dd

Please sign in to comment.