Firefly
Firefly copied to clipboard
An iOS syntax highlighter based on Savanna Kit, Sourceful and originally Highlightr
Firefly
Firefly is a pure swift iOS & macOS syntax highlighter based of off Sourceful, SavannaKit, SyntaxKit, and previously Highlightr. Highlighter has since been remove from the project in favor of a pure swift solution.
Get in contact
If you want to get in contact about Firefly, the Jellycuts Discord is the best place to talk.
Issues
Issues are hosted on both this repo and the Jellycuts Issue Repo. This is done because a lot of issues that occur with Firefly are reported through Jellycuts and it does not make sense to mirror them across to this repo.
How does Firefly Work?
Firefly is written in pure swift, and uses NSRegularExpressions for detecting tokens to highlight. Once tokens are detected they are colored based on the current theme.
Using Firefly in your project
If you are going to use Firefly in your project, I request that you include a link back to this github page somewhere. If you would like to you can also email me and I will add you into the list of apps that use Firefly on this page.
About this project
This project was inspired by Paul Hudson’s (@twostraws) Sourceful syntax highlighter and Highlightr by J.P Illanes (@raspu). Sourceful is a project combining Louis D’hauwe's SavannaKit and Source Editor. Highlightr merges Highlight.js with swift.
Features
- Line Numbers
- Changeable Themes
- Changeable Languages
- Basic String, Parentheses, and Bracket completion
Supports
- 2 Languages
- 61 Themes
How To Use
To start using you can either create a UIView in storyboards and assign it the class SyntaxTextView, or by creating a SyntaxTextView programmatically. You can then assign the editors language inside your View Controller. Firefly also supports setting up with Swift UI.
Sample Code
UI Kit
A basic setup for a Firefly View
import UIKit
import Firefly
class ViewController: UIViewController {
@IBOutlet weak var fireflyView: FireflySyntaxView!
override func viewDidLoad() {
super.viewDidLoad()
// Use the setup function
fireflyView.setup(theme: themeName, language: "jelly", font: "system", offsetKeyboard: true, keyboardOffset: 10, dynamicGutter: true, gutterWidth: 20, placeholdersAllowed: true, linkPlaceholders: false)
}
}
Using the .setup function is the same on macOS as it is on iOS.
Set everything at once
This allows you to set almost all ascpets of the view at once so you do not accidently cause extra highlight calls.
fireflyView.setup(theme: themeName, language: "jelly", font: "system", offsetKeyboard: true, keyboardOffset: 10, dynamicGutter: true, gutterWidth: 20, placeholdersAllowed: true, linkPlaceholders: false)
Set individual parts about the view
Set the text in the Firefly View
fireflyView.text = “My code string”
Set the Firefly View's Theme
fireflyView.setTheme(name: "Basic")
Set the Firefly View's Language
fireflyView.setLanguage(nLanguage: "default")
Set the Firefly View's Gutter Width
fireView.setGutterWidth(width: 20)
Set the Firefly View’s Keyboard Offset
The keyboard offset is the space between the bottom of firefly view and the keyboard frame. You should use this to make space for any keyboard input views.
fireflyView.setKeyboardOffset(offset: 85)
Tell the view if it should dynamically adjust for the keyboard
fireView.setShouldOffsetKeyboard(bool: true)
Set the Firefly View’s Font
fireflyView.setFont(font: "Source Code Pro")
Tell the view if it should dynamically update the gutter width
fireflyView.setDynamicGutter(bool: true)
Tell the view if it should show placeholders or not
A placeholder can be used to deeplink to a different part of your app or open a link. Used for documentation in Jellycuts.
fireView.setPlaceholdersAllowed(bool: true)
Tell the view if it placeholders should also be links
fireView.setLinkPlaceholders(bool: true)
Get the current theme set for the Firefly View
This returns the value for the current theme. You can use this to get details about what the View looks like and color other parts of your app accordingly.
let theme = fireflyView.getCurrentTheme()
List all supported languages
fireflyView().availableLanguages()
List all supported themes
fireflyView().availableThemes()
Swift UI
Swift UI is not fully supported but it is still supported. An example view for Swift UI is below. This will set you up with a basic swift UI Fiefly view.
struct ContentView: View {
@State var text = """
if(x == 3) {
quickLook()
}
import Shortcuts 1090.2
#Color: red, #Icon: shortcuts
Function()
functionWithParams(test: test)
// This is a comment
/*
This is a multi line comment
*/
"String"
\"""
Multi Line Text
More Text
\"""
"""
@State var theme: String = "Xcode Dark"
@State var fontName: String = "system"
@State var update: Bool = false
@State var dynamicGutter: Bool = false
@State var gutterWidth: CGFloat = 40
@State var placeholdersAllowed: Bool = true
@State var linkPlaceholders: Bool = false
@State var lineNumbers: Bool = true
@State var fontSize: CGFloat = 14
var body: some View {
FireflySyntaxEditor(text: $text, language: .constant("Jelly"), theme: $theme, fontName: $fontName, fontSize: $fontSize, dynamicGutter: $dynamicGutter, gutterWidth: $gutterWidth, placeholdersAllowed: $placeholdersAllowed, linkPlaceholders: $linkPlaceholders, lineNumbers: $lineNumbers, cursorPosition: $cursorPosition) { editor in
print("Did change text")
} didChangeSelectedRange: { editor, range in
print("Did change selected range")
} textViewDidBeginEditing: { editor in
print("Did begin editing")
}
}
}
Adding your own content
Adding your own language
Languages are a dictionary of definitions that tell the syntax highlighter how to detect a token.
Example of a language definition:
let defaultLanguage: [String: Any] = [
"comment": [
"regex": "//.*?(\\n|$)", // The regex used for highlighting
"group": 0, // The regex group that should be highlighted
"relevance": 5, // The releavance over other tokens
"options": [], // Regular expression options
"multiline": false // If the token is multiline
],
"multi_comment": [
"regex": "/\\*.*?\\*/", // The regex used for highlighting
"group": 0, // The regex group that should be highlighted
"relevance": 5, // The releavance over other tokens
"options": [NSRegularExpression.Options.dotMatchesLineSeparators], // Regular expression options
"multiline": true // If the token is multiline
],
]
Adding your language
To add your own language to the languages array within the languages dictionary.
let languages: [String: [String: Any]] = [
"default": defaultLanguage,
"jelly": jellyLanguage,
"swift": swiftLanguage
]
Adding a Theme
Themes are a dictionary with color values telling the highlighter what color to highlight different tokens.
Example of a theme definition:
"Basic": [
"default": "#000000", // The default font color
"background": "#FFFFFF", // The background color
"currentLine": "#F3F3F4", // Color of the current line
"selection": "#A4CDFF", // The selection color of the text view
"cursor": "#000000", // The cursor color of the text view
"definitions": [ // These are the definitions that tell the highlighter what color to highlight different types of definitions.
"function": "#2B839F",
"keyword": "#0000FF",
"identifier": "#2B839F",
"string": "#A31515",
"mult_string": "#A31515",
"comment": "#008000",
"multi_comment": "#008000",
"numbers": "#000000",
"url": "#0000FF"
]
]
Apps that use Firefly
To-Do
-
[x] Support for Theme Changing
-
[x] Support for Language Changing
-
[x] Dynmaically creating Gutter and Line styles
-
[x] Fix issues with themes not showing the correct colors when the token has a font weight modifier - Not really fixed, just a workaround currently.
-
[x] Modify, update and implement SavannaKit / SyntaxKit LineNumberLayoutManager for better and faster line numbers
-
[x] Speed increasments for loading larger files
-
[x] Multi-line string support
-
[x] Swift UI support
-
[x] Placeholders
-
[ ] Collapsable lines
-
[ ] More languages
-
[ ] Rewrite the NSTextStorage subclass in obj-c. This will bring speed improvments.
-
[ ] Support VSCode Themes or a converter for VSCode -> Firefly theme
-
[ ] Highlight current line with tinting of line number and line fragmenet
Credits
Sourceful is a project merging together SavannaKit and SourceEditor, and then udpdated too a modern version of Swift. It is maintained by Paul Hudson. This project was used as a starting ground for Firefly but has been largely removed from the working copy. Sourceful is licensed under the MIT license; see Sourceful LICENSE for more information.
Highlightr is a project taking Highlight.js and allowing it to interact with Swift. Highlighter has been removed from the working copy in favor of a full swift approach. Highlightr is licensed under the MIT license; see Highlightr LICENSE for more information.
SyntaxKit is a project created by Palle Klewitz for iOS syntax highlighting. This project was used as a reference for issues in code. SyntaxKit is licensed under the MIT license; see SyntaxKit LICENSE for more information.
SavannaKit is a project created by Louis D'hauwe. Firefly uses a modified version of LineNumberLayoutManager. SavannaKit is licensed under the MIT license; see SavannaKit LICENSE for more information.