SwiftUI code editor view for iOS and macOS

Related tags

editor macos ios swiftui
Overview

SwiftUI code editor view for iOS and macOS

The CodeEditorView Swift package provides a SwiftUI view implementing a rich code editor for iOS and macOS whose visual style is inspired by Xcode. The currently supported functionality includes syntax highlighting with configurable themes, inline message (warnings, errors, etc) reporting, bracket matching, matching bracket insertion, current line highlighting, and a minimap (only on macOS).

Screenshots of the demo app

This is the default dark theme on macOS. Like in Xcode, messages have got an inline view on the right hand side of the screen, which pops up into a larger overlay to display more information. The minimap on the right provides an outline of the edited text.

The following is the default light theme on iOS. Both line highlighting and the minimap are currently not supported on iOS due to limitations in the iOS version of TextKit. Instead of the line highlight, both the current line (or the current selection range) and lines with messages are indicated with differently coloured line numbers in the gutter.

How to use it

Typical usage of the view is as follows.

> = Set () @Environment(\.colorScheme) private var colorScheme: ColorScheme var body: some View { CodeEditor(text: $text, messages: $messages, language: .swift) .environment(\.codeEditorTheme, colorScheme == .dark ? Theme.defaultDark : Theme.defaultLight) } } ">
struct ContentView: View {
  @State private var text:     String                = "My awesome code..."
  @State private var messages: Set> = Set ()

  @Environment(\.colorScheme) private var colorScheme: ColorScheme

  var body: some View {
    CodeEditor(text: $text, messages: $messages, language: .swift)
      .environment(\.codeEditorTheme,
                   colorScheme == .dark ? Theme.defaultDark : Theme.defaultLight)
  }
}

Demo app

To see the CodeEditorView in action, have a look at the repo with a cross-platform demo app.

Documentation

For more information, see the package documentation.

Status

I consider this to be pre-release quality. It is sufficient to start building something on it, but it is not yet ready for production. While the CodeEditor view already supports quite a bit of advanced functionality (such as the inline messages and minimap), other components are still quite simple, such as the range of tokens covered by the language configuration. Moreover, performance is still an issue that needs to be addressed. The core archtecture, such as the incremental tokenisation for syntax highlighting, is designed to handle larger files smoothly, but the overall implementation still needs some performance debugging.

License

Copyright 2021 Manuel M. T. Chakravarty.

Distributed under the Apache-2.0 license — see the license file for details.

Issues
  • Demo app

    Demo app

    • [x] Load and save Swift files
    • [x] At the bottom form to add messages
    documentation 
    opened by mchakravarty 1
  • Gutter invalidation is too generous

    Gutter invalidation is too generous

    Just moving the cursor one character seems to invalidate the entire visible gutter.

    There is also an interaction with gutter invalidation and change management or similar that can lead to an endless loop (or at least, extreme slowness) during start up if there is a window with a large file open. Gutter invalidation happens async on the main thread, but on a large file that may run too early after all. In any case, it is fragile.

    performance 
    opened by mchakravarty 0
  • Document basic usage

    Document basic usage

    documentation 
    opened by mchakravarty 0
  • Improved README including examples

    Improved README including examples

    documentation 
    opened by mchakravarty 0
  • Adding and removing messages via a binding

    Adding and removing messages via a binding

    enhancement 
    opened by mchakravarty 0
  • Release the package

    Release the package

    • [x] Release on GitHub
    • [x] List on https://swiftpackageindex.com
    • [x] Announce
    opened by mchakravarty 0
  • Layout configuration

    Layout configuration

    opened by mchakravarty 0
  • Layer backed gutter view

    Layer backed gutter view

    Currently the redrawing of the gutter view lacks behind resizing operations because it needs to wait until the layout manager has finished laying out the text. This can be clearly observed when switching between fullscreen and windowed mode.

    It should be possible to avoid this by using a CALayer appropriately. By continuing to use the last layer (in GutterView) until the recomputed layout allows us to draw a new layer, the gutter view ought to be able to handle animations, such as going into fullscreen, more elegantly.

    design enhancement 
    opened by mchakravarty 0
  • LanguageConfiguration: expose most helpers

    LanguageConfiguration: expose most helpers

    They get scoped and slightly more expressive names. (The names are still partially abbreviated; otherwise, the regular expressions just get too big, negatively affecting readability.)

    opened by mchakravarty 3
  • New Language Support

    New Language Support

    Is there an easy way of adding new language support? I am really interested in using this library to support another language. Right now, it looks like the only way to do so is to change the LanguageConfiguration file. If that is true, it would be nice to be able to create an external file for my own language support that gets added to the existing language support. That way, anybody can create and submit language configurations to the project.

    opened by frios 8
  • Selection highlighting around message views

    Selection highlighting around message views

    As we adapt the line fragment rectangles to allow for the minimal width of the inline message views, selection highlighting looks weird.

    bug design 
    opened by mchakravarty 0
  • Delay in message reporting

    Delay in message reporting

    In the demo app, when we add a message, it takes a moment for the message inline view to appear. This appears to only happen on macOS.

    bug macOS 
    opened by mchakravarty 0
  • SwiftUI Performance on Larger Files

    SwiftUI Performance on Larger Files

    I mostly opened this issue because I stumbled on to this project and wanted to tell you I think it's cool! I actually built a SwiftUI code viewer myself a few months ago, but your project is much more ambitious (with the language-specific syntax highlighting etc.).

    Anyways, one thing I noticed when running the demo app and opening even medium-size files (i.e. I tried a ~700 line Swift file) is that the view lags quite a bit when scrolling quickly. I haven't profiled the code or anything, so you'd probably know better than me why it might be sluggish, but one thing that helped me when working on my implementation was to avoid passing editable text as a binding property into SwiftUI views.

    So, in CodeEditor, instead of having @Binding var text: String?, you'd have let text: String?. Then you'd add a @State private var editableText: String = "" to CodeEditor and, in the .onAppear of that view, set editableText = text. That way the view maintains its own state when it comes to large chunks of text, which seems to significantly improve performance even on small (1-line) TextField views.

    Feel free to ping me on here (or I'm also on Twitter @justinmkaufman) if you ever want to talk shop, and good luck with the project!

    opened by JUSTINMKAUFMAN 1
  • colorScheme needs to follow the theme

    colorScheme needs to follow the theme

    The colour scheme of lll subviews of the code editor needs to be determined in dependence on the code editor theme and not the app's colour scheme. Probably just set EnvironmentValues.colorScheme on the CodeEditor appropriately (conditionally on .codeEditorTheme).

    • [ ] The separator between the code view and the minimap needs to get use a color scheme dependent on the code editor theme and not the app's colour scheme.
    • [ ] The inline view needs to get its text colour from the theme used for the code (and not from the light/dark appearance of the app!)
    bug design 
    opened by mchakravarty 0
  • Test current performance with larger files

    Test current performance with larger files

    performance 
    opened by mchakravarty 0
  • Option to show invisible characters

    Option to show invisible characters

    Themes already define an appropriate colour.

    enhancement 
    opened by mchakravarty 0
  • Initial drawing and drawing during resizing of background highlights

    Initial drawing and drawing during resizing of background highlights

    • [x] When a highlighting background of a notification is initially drawn, it immediately gets removed again (drawn over again).
    • [ ] When resizing a window, background highlights (associated with message views, but also the current line highlight) flicker and sometimes the current line highlight is missing in the code view (it is fine in the gutter). It seems that CodeView.drawBackground(in:) sometimes get's called in a way/context, where the computation of charRange from the rect results in a zero range although the rect encompasses the entire visible part of the view. (Is the layout information maybe not up to date?)
      • [x] One problem is that the gutter drawing gets delayed when the text layout hasn't finished — and then it get's delayed too long. See GutterView.draw(rect:). Maybe we can improve the timing by using the layout methods of the NSLayoutManagerDelegate.
      • [ ] The other problem is that the view layout computed by CodeView.tile() leads to erratic changes during resizing.
    • [x] When a window is not immediately becoming main, the current line highlight doesn't drawn before the selection moves (or it gets drawn and removed straight away).
    bug 
    opened by mchakravarty 1
Releases(0.9.0)
  • 0.9.0(Jun 3, 2021)

    This is the initial release of this new package. It is not production ready yet, but already includes a substantial amount of advanced and solid functionality.

    Source code(tar.gz)
    Source code(zip)
Owner
Manuel M T Chakravarty
Lambda Scientist
Manuel M T Chakravarty
Fully hackable text editor developed for exact sciences with built-in KaTeX and AsciiMath support. Extensible via plugins and themes. Exportable as HTML, PDF and GFM.

Qilin Editor Qilin is a free, open-source and fully hackable text editor developed for exact sciences in mind. It fully supports KaTeX and AsciiMath.

Qilin 352 Jul 25, 2021
Next-gen, highly customizable content editor for the browser - based on React and Redux and written in TypeScript. WYSIWYG on steroids.

ReactPage ReactPage is a smart, extensible and modern editor ("WYSIWYG") for the web written in React. If you are fed up with the limitations of conte

null 8.6k Jul 24, 2021
📝A simple and elegant markdown editor, available for Linux, macOS and Windows.

Mark Text ?? Next generation markdown editor ?? A simple and elegant open-source markdown editor that focused on speed and usability. Available for Li

Mark Text 19.1k Aug 2, 2021
Dead simple JSON editor using josdejong/jsoneditor

English | 日本語 JSON Editor Simple JSON Editor for Win & Mac! This app is just a thin wrapper of josdejong/jsoneditor. Thanks @josdejong! Install Downlo

Takayosi Amagi 34 Jun 13, 2021
An open source code editor for the web, written in JavaScript, HTML and CSS.

⚠️ On September 1, 2021, Adobe will end support for Brackets. If you would like to continue using, maintaining, and improving Brackets, you may fork t

Adobe, Inc. 33.7k Aug 1, 2021
Oni: Modern Modal Editing - powered by Neovim

NOTE: This repository is unmaintained - we are focusing on Onivim 2 and libvim. Modern Modal Editing Introduction Oni is a new kind of editor, focused

onivim 11.5k Aug 3, 2021
Open source Markdown editor for macOS.

MacDown MacDown is an open source Markdown editor for OS X, released under the MIT License. The author stole the idea from Chen Luo’s Mou so that peop

MacDown 8.7k Aug 4, 2021
A modern, native macOS markdown editor

Pine 简体中文 Pine is lightweight macOS markdown editor. It's currently a work in progress. It is a document based application, and aims to follow Apple's

Luka Kerr 2.7k Aug 2, 2021
Vim is a greatly improved version of the good old UNIX editor Vi

Vim is a greatly improved version of the good old UNIX editor Vi. Many new features have been added: multi-level undo, syntax highlighting, command line history, on-line help, spell checking, filename completion, block operations, script language, etc. There is also a Graphical User Interface (GUI) available. Still, Vi compatibility is maintained, those who have Vi "in the fingers" will feel at home. See runtime/doc/vi_diff.txt for differences with Vi.

Vim - the text editor 24.4k Aug 1, 2021
GUI for editing, visualizing, and manipulating JSON data

JSON-Splora JSON-Splora is a GUI for editing, visualizing, and manipulating JSON data with jq or JavaScript. Design Built with Electron Editor and out

Wells Johnston 1.8k Jul 28, 2021
A simple CSV editor for the Mac

Table Tool A simple CSV editor for OS X. Download on the Mac App Store. The CSV format is a common used file format to store and exchange tabular data

Jakob Egger 1k Jul 27, 2021
General purpose plain text editor for macOS. Widely known for its live collaboration feature.

SubEthaEdit General purpose plain-text editor for macOS. Widely known for its live collaboration feature. github.com/subethaedit/SubEthaEdit is the ma

SubEthaEdit Contributors 1.2k Jul 22, 2021
The Light Table IDE ⛺

Light Table Light Table is a next generation code editor that connects you to your creation with instant feedback. Light Table is very customizable an

Light Table 11.6k Jul 26, 2021
:atom: The hackable text editor

Atom Atom is a hackable text editor for the 21st century, built on Electron, and based on everything we love about our favorite editors. We designed i

Atom 55.8k Aug 2, 2021