{"id":13872254,"url":"https://github.com/ZeeZide/CodeEditor","last_synced_at":"2025-07-16T02:30:29.172Z","repository":{"id":37448287,"uuid":"366728308","full_name":"ZeeZide/CodeEditor","owner":"ZeeZide","description":"A SwiftUI TextEditor with syntax highlighting using Highlight.js","archived":false,"fork":false,"pushed_at":"2024-07-02T15:27:27.000Z","size":74,"stargazers_count":435,"open_issues_count":13,"forks_count":54,"subscribers_count":9,"default_branch":"develop","last_synced_at":"2024-08-04T15:48:02.184Z","etag":null,"topics":["editor","highlight","highlightjs","swift","swiftui"],"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/ZeeZide.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":"2021-05-12T13:38:33.000Z","updated_at":"2024-07-30T22:16:01.000Z","dependencies_parsed_at":"2024-01-16T10:09:28.662Z","dependency_job_id":null,"html_url":"https://github.com/ZeeZide/CodeEditor","commit_stats":{"total_commits":36,"total_committers":8,"mean_commits":4.5,"dds":0.5277777777777778,"last_synced_commit":"180bde07b44dea839b32873bd8586ba146fa9106"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZeeZide%2FCodeEditor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZeeZide%2FCodeEditor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZeeZide%2FCodeEditor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZeeZide%2FCodeEditor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZeeZide","download_url":"https://codeload.github.com/ZeeZide/CodeEditor/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":214112023,"owners_count":15685280,"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":["editor","highlight","highlightjs","swift","swiftui"],"created_at":"2024-08-05T23:00:37.961Z","updated_at":"2024-08-05T23:01:43.039Z","avatar_url":"https://github.com/ZeeZide.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"\u003ch2\u003e\n  CodeEditor\n  \u003cimg src=\"https://zeezide.de/img/svgshaper/SVGShaper512.png\"\n       align=\"right\" width=\"128\" height=\"128\" /\u003e\n\u003c/h2\u003e\n\n![SwiftUI](https://img.shields.io/badge/SwiftUI-orange.svg)\n![Swift5](https://img.shields.io/badge/swift-5-blue.svg)\n![macOS](https://img.shields.io/badge/os-macOS-green.svg?style=flat)\n![iOS](https://img.shields.io/badge/os-iOS-green.svg?style=flat)\n![visionOS](https://img.shields.io/badge/os-visionOS-green.svg?style=flat)\n[![Build and Test](https://github.com/ZeeZide/CodeEditor/actions/workflows/swift.yml/badge.svg?branch=main)](https://github.com/ZeeZide/CodeEditor/actions/workflows/swift.yml)\n\nA [SwiftUI](https://developer.apple.com/xcode/swiftui/)\nTextEditor View with syntax highlighting using\n[Highlight.js](https://highlightjs.org).\n\nIt builds on top of\n[Highlightr](https://github.com/raspu/Highlightr)\nwhich does the wrapping of Highlight.js.\nCodeEditor then packages things up for SwiftUI.\n\nExample usage in \n[SVG Shaper for SwiftUI](https://zeezide.de/en/products/svgshaper/)\n(used for editing SVG and Swift source):\n\n![SVG Shaper Screenshot](https://pbs.twimg.com/media/E0ydNH9XEAQ-USY?format=png)\n\n(Shaper is not actually using Highlightr, but is otherwise quite similar).\n\nHighlightr example:\n\n![Highlight Example](https://raw.githubusercontent.com/raspu/Highlightr/master/coding.gif)\n\n\n## Usage\n\n### Adding the Package\n\nThe Swift package URL is: `https://github.com/ZeeZide/CodeEditor.git`\n\n### Using it in a SwiftUI App\n\nTo use `CodeEditor` as a source code viewer, simply pass the source code\nas a string:\n```swift\nstruct ContentView: View {\n\n    var body: some View {\n        CodeEditor(source: \"let a = 42\")\n    }\n}\n```\n\nIf it should act as an actual editor, pass in a string `Binding`:\n\n```swift\nstruct ContentView: View {\n\n    @State private var source = \"let a = 42\\n\"\n    \n    var body: some View {\n        CodeEditor(source: $source, language: .swift, theme: .ocean)\n    }\n}\n```\n\n### Languages and Themes\n\n[Highlight.js](https://highlightjs.org).\nsupports more than 180 languages and over 80 different themes.\n\nThe available languages and themes can be accessed using:\n```swift\nCodeEditor.availableLanguages\nCodeEditor.availableThemes\n```\n\nThey can be used in a SwiftUI `Picker` like so:\n\n```swift\nstruct MyEditor: View {\n  \n    @State private var source   = \"let it = be\"\n    @State private var language = CodeEditor.Language.swift\n\n    var body: some View {\n        Picker(\"Language\", selection: $language) {\n            ForEach(CodeEditor.availableLanguages) { language in\n                Text(\"\\(language.rawValue.capitalized)\")\n                    .tag(language)\n            }\n        }\n    \n        CodeEditor(source: $source, language: language)\n    }\n}\n```\n\nNote: The `CodeEditor` doesn't do automatic theme changes if the appearance\n     changes.\n\n\n### Smart Indent and Open/Close Pairing\n\nInspired by [NTYSmartTextView](https://github.com/naoty/NTYSmartTextView),\n`CodeEditor` now also supports (on macOS):\n- smarter indents (preserving the indent of the previous line)\n- soft indents (insert a configurable amount of spaces if the user presses tabs)\n- auto character pairing, e.g. when entering `{`, the matching `}` will be auto-added\n\nTo enable smart indents, add the `smartIndent` flag, e.g.:\n```swift\nCodeEditor(source: $source, language: language, \n           flags: [ .selectable, .editable, .smartIndent ])\n```\nIt is enabled for editors by default.\n\nTo configure soft indents, use the `indentStyle` parameter, e.g.\n```swift\nCodeEditor(source: $source, language: language,\n           indentStyle: .softTab(width: 2))\n```\nIt defaults to tabs, as per system settings.\n\nAuto character pairing is automatic based on the language. E.g. there is a set of \ndefaults for C like languages (e.g. Swift), Python or XML. The defaults can be overridden\nusing the respective static variable in `CodeEditor`,\nor the desired pairing can be set explicitly:\n```swift\nCodeEditor(source: $source, language: language,\n           autoPairs: [ \"{\": \"}\", \"\u003c\": \"\u003e\", \"'\": \"'\" ])\n```\n\n\n### Font Sizing\n\nOn macOS the editor supports sizing of the font (using Cmd +/Cmd - and the\nfont panel).\nTo enable sizing commands, the WindowScene needs to have the proper commands\napplied, e.g.:\n\n```swift\nWindowGroup {\n    ContentView()\n}\n.commands {\n    TextFormattingCommands()\n}\n```\nTo persist the size, the `fontSize` binding is available.\n\n\n ### Selection and Scrolling\n \n The selected text can be observed and modified via another `Binding`:\n \n ```swift\n  struct ContentView: View {\n     static private let initialSource = \"let a = 42\\n\"\n\n     @State private var source = Self.initialSource\n     @State private var selection = Self.initialSource.endIndex..\u003cSelf.initialSource.endIndex\n\n     var body: some View {\n         CodeEditor(source: $source,\n                    selection: $selection,\n                    language: .swift,\n                    theme: .ocean,\n                    autoscroll: false)\n         Button(\"Select All\") {\n             selection = source.startIndex..\u003csource.endIndex\n         }\n     }\n }\n ```\n When `autoscroll` is `true`, the editor automatically scrolls to the respective\n cursor position when `selection` is modfied from the outside, i.e. programatically.\n\n### Highlightr and Shaper\n\nBased on the excellent [Highlightr](https://github.com/raspu/Highlightr).\nThis means that it is using JavaScriptCore as the actual driver. As\nHighlightr says:\n\n\u003e It will never be as fast as a native solution, but it's fast enough to be\n\u003e used on a real time editor.\n\nThe editor is similar to (but not exactly the same) the one used by\n[SVG Shaper for SwiftUI](https://zeezide.de/en/products/svgshaper/),\nfor its SVG and Swift editor parts.\n\n\n### Complete Example\n\n```swift\nimport SwiftUI\nimport CodeEditor\n\nstruct ContentView: View {\n  \n  #if os(macOS)\n    @AppStorage(\"fontsize\") var fontSize = Int(NSFont.systemFontSize)\n  #endif\n  @State private var source = \"let a = 42\"\n  @State private var language = CodeEditor.Language.swift\n  @State private var theme    = CodeEditor.ThemeName.pojoaque\n\n  var body: some View {\n    VStack(spacing: 0) {\n      HStack {\n        Picker(\"Language\", selection: $language) {\n          ForEach(CodeEditor.availableLanguages) { language in\n            Text(\"\\(language.rawValue.capitalized)\")\n              .tag(language)\n          }\n        }\n        Picker(\"Theme\", selection: $theme) {\n          ForEach(CodeEditor.availableThemes) { theme in\n            Text(\"\\(theme.rawValue.capitalized)\")\n              .tag(theme)\n          }\n        }\n      }\n      .padding()\n    \n      Divider()\n    \n      #if os(macOS)\n        CodeEditor(source: $source, language: language, theme: theme,\n                   fontSize: .init(get: { CGFloat(fontSize)  },\n                                   set: { fontSize = Int($0) }))\n          .frame(minWidth: 640, minHeight: 480)\n      #else\n        CodeEditor(source: $source, language: language, theme: theme)\n      #endif\n    }\n  }\n}\n\nstruct ContentView_Previews: PreviewProvider {\n  static var previews: some View {\n    ContentView()\n  }\n}\n```\n\n\n### Who\n\nCodeEditor is brought to you by [ZeeZide](https://zeezide.de).\nWe like feedback, GitHub stars, cool contract work, \npresumably any form of praise you can think of.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZeeZide%2FCodeEditor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FZeeZide%2FCodeEditor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZeeZide%2FCodeEditor/lists"}