{"id":15048700,"url":"https://github.com/kyle-n/highlightedtexteditor","last_synced_at":"2025-04-12T18:49:43.473Z","repository":{"id":37449543,"uuid":"291742973","full_name":"kyle-n/HighlightedTextEditor","owner":"kyle-n","description":"A SwiftUI view for dynamically highlighting user input","archived":false,"fork":false,"pushed_at":"2024-06-13T22:29:58.000Z","size":6485,"stargazers_count":724,"open_issues_count":5,"forks_count":68,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-10-30T02:36:30.358Z","etag":null,"topics":["ios","macos","markdown","markdown-editor","swift","swiftui","xcode"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kyle-n.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-31T14:48:48.000Z","updated_at":"2024-10-28T08:27:44.000Z","dependencies_parsed_at":"2024-11-12T21:00:30.769Z","dependency_job_id":"746c500f-068b-4dc5-926b-11593f84df86","html_url":"https://github.com/kyle-n/HighlightedTextEditor","commit_stats":{"total_commits":170,"total_committers":8,"mean_commits":21.25,"dds":"0.18823529411764706","last_synced_commit":"759d7b4bd2c10d0bbe93bc62d68572a3702049e3"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-n%2FHighlightedTextEditor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-n%2FHighlightedTextEditor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-n%2FHighlightedTextEditor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-n%2FHighlightedTextEditor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kyle-n","download_url":"https://codeload.github.com/kyle-n/HighlightedTextEditor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248618218,"owners_count":21134199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","macos","markdown","markdown-editor","swift","swiftui","xcode"],"created_at":"2024-09-24T21:15:27.265Z","updated_at":"2025-04-12T18:49:43.450Z","avatar_url":"https://github.com/kyle-n.png","language":"Swift","readme":"# HighlightedTextEditor\n\nA simple, powerful SwiftUI text editor for iOS and macOS with live syntax highlighting.\n\nHighlight what's important as your users type. \n\n![HighlightedTextEditor demo](https://raw.githubusercontent.com/kyle-n/kyle-n.github.io/master/static/img/hte-demo.gif)\n\n## Installation\n\nSupports iOS 13.0+ and macOS 10.15+.\n\n### Swift Package Manager\n\nFile -\u003e Swift Packages -\u003e Add Package Dependency and use the URL `https://github.com/kyle-n/HighlightedTextEditor`.\n\n### CocoaPods\n\nAdd `pod 'HighlightedTextEditor'` to your `Podfile` and run `pod install`. \n\n## Usage\n\nHighlightedTextEditor applies styles to text matching regex patterns you provide. You can apply multiple styles to each regex pattern, as shown in the example below. \n\n```swift\nimport HighlightedTextEditor\n\n// matches text between underscores\nlet betweenUnderscores = try! NSRegularExpression(pattern: \"_[^_]+_\", options: [])\n\nstruct ContentView: View {\n    \n    @State private var text: String = \"\"\n    \n    private let rules: [HighlightRule] = [\n        HighlightRule(pattern: betweenUnderscores, formattingRules: [\n            TextFormattingRule(fontTraits: [.traitItalic, .traitBold]),\n            TextFormattingRule(key: .foregroundColor, value: UIColor.red),\n            TextFormattingRule(key: .underlineStyle) { content, range in\n                if content.count \u003e 10 { return NSUnderlineStyle.double.rawValue }\n                else { return NSUnderlineStyle.single.rawValue }\n            }\n        ])\n    ]\n    \n    var body: some View {\n        VStack {\n            HighlightedTextEditor(text: $text, highlightRules: rules)\n                // optional modifiers\n                .onCommit { print(\"commited\") }\n                .onEditingChanged { print(\"editing changed\") }\n                .onTextChange { print(\"latest text value\", $0) }\n                .onSelectionChange { (range: NSRange) in\n                    print(range)\n                }\n                .introspect { editor in\n                    // access underlying UITextView or NSTextView\n                    editor.textView.backgroundColor = .green\n                }\n        }\n    }\n}\n```\n\nNotice the NSRegularExpression is instantiated **once**. It should not be recreated every time the view is redrawn. This [helps performance](https://stackoverflow.com/questions/41705728/optimize-nsregularexpression-performance). \n\n## Presets\n\nI've included a few useful presets for syntax highlighting as static vars on `[HighlightRule]`. If you have ideas for other useful presets, please feel free to [open a pull request](https://github.com/kyle-n/HighlightedTextEditor/pulls) with your preset code.\n\nCurrent presets include:\n\n- `markdown`\n- `url` \n\nExample of using a preset:\n\n```swift\nHighlightedTextEditor(text: $text, highlightRules: .markdown)\n```\n\n### Regex Presets\n\nI've also added a preset variable, `NSRegularExpression.all`, for easily selecting a whole string.\n\nExample of using it:\n\n```swift\nHighlightedTextEditor(text: $text, highlightRules: [\n    HighlightRule(pattern: .all, formattingRule: TextFormattingRule(key: .underlineStyle, value: NSUnderlineStyle.single.rawValue))\n])\n```\n\n## API\n\n### HighlightedTextEditor\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `text` | Binding\u0026lt;String\\\u003e | Text content of the field |\n| `highlightRules` | [HighlightRule] | Patterns and formatting for those patterns |\n\n#### Modifiers\n\n- `.introspect(callback: (_ editor: HighlightedTextEditorInternals) -\u003e Void)`: Allows you the developer to access the underlying UIKit or AppKit objects used by HighlightedTextEditor\n- `.onCommit(_ callback: @escaping () -\u003e Void)`: Called when the user stops editing\n- `.onEditingChanged(_ callback: @escaping () -\u003e Void)`: Called when the user begins editing\n- `.onTextChange(_ callback: @escaping (_ editorContent: String) -\u003e Void)`: Called whenever `text` changes\n- `.onSelectionChange(_ callback: @escaping (_ selectedRange: NSRange) -\u003e Void)`\n- `.onSelectionChange(_ callback: @escaping (_ selectedRanges: [NSRange]) -\u003e Void)` (AppKit only)\n\n### HighlightedTextEditorInternals\n\nPassed as a parameter to `.introspect()` callbacks. Useful for customizing editor behavior in some way not supported by the HLTE API.\n\n| Property | Type | Description |\n| --- | --- | --- |\n| `textView` | UITextView or NSTextView | For customizing the UIKit/AppKit text editor |\n| `scrollView` | NSScrollView? | For customizing the NSScrollView wrapper. Returns `nil` in UIKit |\n\n### HighlightRule\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `pattern` | NSRegularExpression | The content you want to highlight. Should be instantiated **once** for performance. |\n| `formattingRule` | TextFormattingRule | Style applying to all text matching the `pattern` |\n| `formattingRules` | [TextFormattingRule] | Array of styles applying to all text matching the `pattern` |\n\n### TextFormattingRule\n\nTextFormattingRule offers three different initializers that each set one style. To set multiple styles, use multiple TextFormattingRules.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `key` | [NSAttributedString.Key](2) | The style to set (e.x. `.foregroundColor`, `.underlineStyle`) |\n| `value` | Any | The actual style applied to the `key` (e.x. for `key = .foregroundColor`, `value` is `UIColor.red` or `NSColor.red`) |\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `key` | [NSAttributedString.Key](2) | The style to set (e.x. `.foregroundColor`, `.underlineStyle`) |\n| `calculateValue` | (String, Range\u003cString.Index\u003e) -\u003e Any | A callback that calculates the value for `key`. First parameter is the text content matched by the regex, second is the match's range in the overall string. |\n\n`value` uses an older, untyped API so you'll have to check the [documentation](2) for what type can be passed in for a given `key`.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `fontTraits` | [UIFontDescriptor.SymbolicTraits](3) or [NSFontDescriptor.SymbolicTraits](4) | Text formatting attributes (e.x. `[.traitBold]` in UIKit and `.bold` in AppKit) |\n\n[2]: https://developer.apple.com/documentation/foundation/nsattributedstring/key\n\n[3]: https://developer.apple.com/documentation/uikit/uifontdescriptor/symbolictraits\n\n[4]: https://developer.apple.com/documentation/appkit/nsfontdescriptor/symbolictraits\n\nIf you are targeting iOS 14 / macOS 11, you can use a convenience initializer taking advantage of new SwiftUI APIs for converting Colors to UIColors or NSColors. \n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `foregroundColor` | Color | Color of the text |\n| `fontTraits` | [UIFontDescriptor.SymbolicTraits](3) or [NSFontDescriptor.SymbolicTraits](4) | Text formatting attributes (e.x. `[.traitBold]` in UIKit and `.bold` in AppKit) |\n\nApple, in its wisdom, has not enabled these features for the XCode 12 GM. If you are using the XCode beta and want to enable this initializer, go to project_name -\u003e Targets -\u003e specified platform -\u003e Build Settings -\u003e Swift Compiler - Custom Flags and add flag `-DBETA`.\n\u0026lt;\n## Featured apps\n\nAre you using HighlightedTextEditor in your app? I would love to feature you here! Please [open a pull request](https://github.com/kyle-n/HighlightedTextEditor/pulls) that adds a new bullet to the list below with your app's name and a link to its TestFlight or App Store page.\n\n- [MongoKitten](https://apps.apple.com/us/app/id1484086700)\n\n## Credits\n\nAppKit text editor code based on [MacEditorTextView](https://gist.github.com/unnamedd/6e8c3fbc806b8deb60fa65d6b9affab0) by [Thiago Holanda](https://twitter.com/tholanda).\n\nCreated by [Kyle Nazario](https://twitter.com/kbn_au).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyle-n%2Fhighlightedtexteditor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkyle-n%2Fhighlightedtexteditor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyle-n%2Fhighlightedtexteditor/lists"}