Git Product home page Git Product logo

codeeditorview's Introduction

SwiftUI code editor view for iOS, visionOS, and macOS

The CodeEditorView Swift package provides a SwiftUI view implementing a rich code editor for iOS, visionOS, 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.

Update:

  • CodeEditorView is now based on TextKit 2.
  • The TextKit 2 implementation requires the latest versions of macOS (14) and iOS (17). If you want to use CodeEditorView on earlier version of macOS or iOS, you need to use release 0.12.0 or the textkit1 branch of this repository. (I don't have the bandwidth to support TextKit 2 on earlier OS versions, but I am happy to accept PRs that add support for it. They need to use Swift 5.9, though.)
  • On macOS, CodeEditorView also supports (1) displaying information about identifiers (such as type information and documentation provided in Markdown) as well as (2) code completion. This will eventually also be supported on iOS.

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.

How to use it

Typical usage of the view is as follows.

struct ContentView: View {
  @State private var text:     String                    = "My awesome code..."
  @State private var position: CodeEditor.Position       = CodeEditor.Position()
  @State private var messages: Set<TextLocated<Message>> = Set()

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

  var body: some View {
    CodeEditor(text: $text, position: $position, 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 build something with it, but it is not yet ready for production. The CodeEditor view already supports quite a bit of advanced functionality (such as the inline messages, a minimap, and (on macOS) code completion). Other components are still quite simple, such as the range of tokens covered by the language configuration, but that is also something that is easily extended. Performance is still an issue for larger files.

License

Copyright [2021..2024] Manuel M. T. Chakravarty.

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

codeeditorview's People

Contributors

christopherweems avatar itsliamdowd avatar kkebo avatar mchakravarty avatar ronyfadel avatar rustle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codeeditorview's Issues

Highlight current line on iOS

UIKit (as of iOS 14.4) lacks a configuration point comparable to NSTextView.drawBackground(in:), and that makes it hard to highlight the current line reliably and efficiently.

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.

Fix end of buffer line deletion

Deleting multiple lines at the bottom seems to lead to leftovers in the line map. (Line numbers of non-existing lines are drawn.)

Selection highlighting around message views

When selecting the lines including and around a message view (inline and the expanded view), we get a few visual artefacts:

  • Line selection (on the right hand side) doesn't extend to the divider (due to the excess width added to line line wrapping up with the minimap). [macOS]
  • The initial part of the inline view gets "highlighted", but not the rest — due to the line fragment being shortened by the minimum inline message width.
  • When the message view is expanded, part of the space occupied by the inline view still isn't highlighted (essentially due to the same reason as the point above).

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.

Code Review (Diff)

In CodeEdit, our goal is to reach editor feature parity with Xcode. We'd like to use CodeEditorView as opposed to rolling our own editor view. That considered the question arises, what is the responsibility of the editor and what is the responsibility of the application built around it?

01-macOS-code-edit-source-control

I am thinking the Code Review might be the responsibility of the editor as it is the editor that draws the new lines, line highlights etc. What are your thoughts here? If it is not the responsibility of the editor, without looking into it too much, is CodeEditor extensible enough to build this on top of it outside the editor?

Advanced rendering in minimap

  • Render documentation headings in small letters, but legible
  • Highlight declarations and display a label with their name when mousing over or when CMD is pressed á la Xcode

Unable to position the cursor accurately

Tested on real iphone devices and simulator. Simulator works fine with the mouse.

However in real devices, when trying to position the cursor position between semi quote text by touching the screen with hand, the cursor position appear at the wrong side.

Animate message view animations

  • Animate the appearance and disappearance of the short version (sliding in from the right, while fading in).
  • Animate the transition from inline to popup version and back.

CodeEditor: minimap for UIKit

Our current implementation of the minimap doesn't work for UIKit as it doesn't support subclassing NSTypeSetter. Even writing a new typesetter from scratch seems hard, as it is unclear how to slot it into a subclassed layout manager.

Demo app

  • Load and save Swift files
  • At the bottom form to add messages

Initial stab at external language support

To make use of syntactic and semantic information provided by external tools, such as an LSP server, we need infrastructure to query the external information provider and to receive updates from the external information providers (such as new diagnostic messages).

  • There needs to be a way to indicate which functions a LanguageService actually implements. Extracted as #76

Horizontal scrolling on iOS

Currently, word wrapping can be disabled on iOS, but that doesn't enable horizontal scrolling. This seems inherent in the UITextView subclass of UIScrollView. Maybe this is easier with TextKit 2.

colorScheme needs to follow the theme

The colour scheme of all 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. (Color directly based on the theme.)
  • 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!)

Eager location reading in some cases

Using the exact sample code as shown in the readme:

struct ContentView: View {
  @State private var text:     String                = "My awesome code..."
  @State private var messages: Set<Located<Message>> = 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)
  }
}

Pressing the backspace key to delete one character causes an immediate crash. Inputting more text is not affected, crash seems to only occur when deleting any character.

Here's a screen recording of the crash (window does not close since Xcode is attached to the app). Xcode printed out the stack trace (which is included below) immediately after I backspaced the 'd' character.

Screen.Recording.2022-02-04.at.1.58.57.PM.mov

Here's the stack trace of the crash:

022-02-04 13:59:11.334073+0800 CPEdit[90289:4724934] [General] An uncaught exception was raised
2022-02-04 13:59:11.334204+0800 CPEdit[90289:4724934] [General] -[__NSCFString getLineStart:end:contentsEnd:forRange:]: Range {60, 0} out of bounds; string length 59
2022-02-04 13:59:11.339149+0800 CPEdit[90289:4724934] [General] (
	0   CoreFoundation                      0x00000001bccd01cc __exceptionPreprocess + 240
	1   libobjc.A.dylib                     0x00000001bca217b8 objc_exception_throw + 60
	2   CoreFoundation                      0x00000001bcda0488 -[__NSCFString characterAtIndex:].cold.1 + 0
	3   CoreFoundation                      0x00000001bccb4750 CFStringGetLineBounds + 0
	4   Foundation                          0x00000001bdcef0cc -[NSString lineRangeForRange:] + 64
	5   CPEdit                              0x0000000100f329d8 $s14CodeEditorView0aC0C17setSelectedRanges_8affinity14stillSelectingySaySo7NSValueCG_So19NSSelectionAffinityVSbtFSo8_NSRangeVSgSiXEfU_ + 392
	6   CPEdit                              0x0000000100f32a54 $sSiSo8_NSRangeVSgs5Error_pIgydzo_SiACsAD_pIegnrzo_TR + 32
	7   CPEdit                              0x0000000100f3da80 $sSiSo8_NSRangeVSgs5Error_pIgydzo_SiACsAD_pIegnrzo_TRTA + 28
	8   libswiftCore.dylib                  0x00000001c9c02c44 $sSq7flatMapyqd__SgABxKXEKlF + 448
	9   CPEdit                              0x0000000100f32210 $s14CodeEditorView0aC0C17setSelectedRanges_8affinity14stillSelectingySaySo7NSValueCG_So19NSSelectionAffinityVSbtF + 1016
	10  CPEdit                              0x0000000100f33aa0 $s14CodeEditorView0aC0C17setSelectedRanges_8affinity14stillSelectingySaySo7NSValueCG_So19NSSelectionAffinityVSbtFTo + 108
	11  UIFoundation                        0x00000001c063ba6c -[NSLayoutManager textStorage:edited:range:changeInLength:invalidatedRange:] + 372
	12  CPEdit                              0x0000000100f3c510 $s14CodeEditorView0A13LayoutManagerC14processEditing3for6edited5range14changeInLength16invalidatedRangeySo13NSTextStorageC_So0pQ11EditActionsVSo8_NSRangeVSiAOtF + 544
	13  CPEdit                              0x0000000100f3cad4 $s14CodeEditorView0A13LayoutManagerC14processEditing3for6edited5range14changeInLength16invalidatedRangeySo13NSTextStorageC_So0pQ11EditActionsVSo8_NSRangeVSiAOtFTo + 140
	14  UIFoundation                        0x00000001c0662934 -[NSTextStorage _notifyEdited:range:changeInLength:invalidatedRange:] + 188
	15  UIFoundation                        0x00000001c066e3b4 -[NSTextStorage endEditing] + 116
	16  CPEdit                              0x0000000100f18374 $s14CodeEditorView0A7StorageC17replaceCharacters2in4withySo8_NSRangeV_SStF + 3220
	17  CPEdit                              0x0000000100f18ec4 $s14CodeEditorView0A7StorageC17replaceCharacters2in4withySo8_NSRangeV_SStFTo + 100
	18  AppKit                              0x00000001bfb19fbc -[NSTextView(NSPrivate) _userReplaceRange:withString:] + 260
	19  AppKit                              0x00000001bfb19a40 _NSDoUserReplaceForCharRange + 480
	20  AppKit                              0x00000001bfb6511c -[NSTextView(NSKeyBindingCommands) deleteBackward:] + 824
	21  AppKit                              0x00000001bfa86e60 -[NSTextView doCommandBySelector:] + 216
	22  AppKit                              0x00000001bfa86d48 -[NSTextInputContext(NSInputContext_WithCompletion) doCommandBySelector:completionHandler:] + 264
	23  AppKit                              0x00000001bf9b0f6c -[NSKeyBindingManager(NSKeyBindingManager_MultiClients) interpretEventAsCommand:forClient:] + 2008
	24  AppKit                              0x00000001bf9b9c9c __84-[NSTextInputContext _handleEvent:options:allowingSyntheticEvent:completionHandler:]_block_invoke_5 + 376
	25  AppKit                              0x00000001c01845d8 __84-[NSTextInputContext _handleEvent:options:allowingSyntheticEvent:completionHandler:]_block_invoke_3.1027 + 108
	26  AppKit                              0x00000001bf9b9ae0 -[NSTextInputContext tryHandleEvent_HasMarkedText_withDispatchCondition:dispatchWork:continuation:] + 148
	27  AppKit                              0x00000001c0184530 __84-[NSTextInputContext _handleEvent:options:allowingSyntheticEvent:completionHandler:]_block_invoke.1024 + 324
	28  HIToolbox                           0x00000001c58207dc __TSMProcessRawKeyEventWithOptionsAndCompletionHandler_block_invoke_5 + 96
	29  HIToolbox                           0x00000001c5831c3c ___ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec_block_invoke + 148
	30  AppKit                              0x00000001c017f11c __55-[NSTextInputContext handleTSMEvent:completionHandler:]_block_invoke.341 + 592
	31  AppKit                              0x00000001bf9b2fb0 __55-[NSTextInputContext handleTSMEvent:completionHandler:]_block_invoke_2 + 108
	32  AppKit                              0x00000001bf9b2ef4 -[NSTextInputContext tryHandleTSMEvent_HasMarkedText_withDispatchCondition:dispatchWork:continuation:] + 148
	33  AppKit                              0x00000001bf9b23a0 -[NSTextInputContext handleTSMEvent:completionHandler:] + 2004
	34  AppKit                              0x00000001bf9b1b50 _NSTSMEventHandler + 340
	35  HIToolbox                           0x00000001c57bf418 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1116
	36  HIToolbox                           0x00000001c57be884 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 356
	37  HIToolbox                           0x00000001c57be714 SendEventToEventTargetWithOptions + 44
	38  HIToolbox                           0x00000001c581cd54 SendTSMEvent_WithCompletionHandler + 432
	39  HIToolbox                           0x00000001c581d298 __SendUnicodeTextAEToUnicodeDoc_WithCompletionHandler_block_invoke + 440
	40  HIToolbox                           0x00000001c581d0b4 __SendFilterTextEvent_WithCompletionHandler_block_invoke + 224
	41  HIToolbox                           0x00000001c581cdac SendTSMEvent_WithCompletionHandler + 520
	42  HIToolbox                           0x00000001c581cb5c SendFilterTextEvent_WithCompletionHandler + 256
	43  HIToolbox                           0x00000001c581c788 SendUnicodeTextAEToUnicodeDoc_WithCompletionHandler + 292
	44  HIToolbox                           0x00000001c581c524 __utDeliverTSMEvent_WithCompletionHandler_block_invoke_2 + 320
	45  HIToolbox                           0x00000001c581c2a8 __utDeliverTSMEvent_WithCompletionHandler_block_invoke + 284
	46  HIToolbox                           0x00000001c581c10c TSMKeyEvent_WithCompletionHandler + 600
	47  HIToolbox                           0x00000001c581be94 __TSMProcessRawKeyEventWithOptionsAndCompletionHandler_block_invoke_4 + 320
	48  HIToolbox                           0x00000001c581bca4 __TSMProcessRawKeyEventWithOptionsAndCompletionHandler_block_invoke_3 + 352
	49  HIToolbox                           0x00000001c581b9a0 __TSMProcessRawKeyEventWithOptionsAndCompletionHandler_block_invoke_2 + 352
	50  HIToolbox                           0x00000001c581b69c __TSMProcessRawKeyEventWithOptionsAndCompletionHandler_block_invoke + 344
	51  HIToolbox                           0x00000001c5809b84 TSMProcessRawKeyEventWithOptionsAndCompletionHandler + 3372
	52  AppKit                              0x00000001c01843dc __84-[NSTextInputContext _handleEvent:options:allowingSyntheticEvent:completionHandler:]_block_invoke_3.1020 + 148
	53  AppKit                              0x00000001c018408c __204-[NSTextInputContext tryTSMProcessRawKeyEvent_orSubstitution:dispatchCondition:setupForDispatch:furtherCondition:doubleSpaceSubstitutionCondition:doubleSpaceSubstitutionWork:dispatchTSMWork:continuation:]_block_invoke.971 + 192
	54  AppKit                              0x00000001bf9b0620 -[NSTextInputContext tryTSMProcessRawKeyEvent_orSubstitution:dispatchCondition:setupForDispatch:furtherCondition:doubleSpaceSubstitutionCondition:doubleSpaceSubstitutionWork:dispatchTSMWork:continuation:] + 344
	55  AppKit                              0x00000001bf9aff20 -[NSTextInputContext _handleEvent:options:allowingSyntheticEvent:completionHandler:] + 1528
	56  AppKit                              0x00000001bf9af8e8 -[NSTextInputContext _handleEvent:allowingSyntheticEvent:] + 136
	57  AppKit                              0x00000001bf9af708 -[NSView interpretKeyEvents:] + 196
	58  AppKit                              0x00000001bf9af518 -[NSTextView keyDown:] + 712
	59  AppKit                              0x00000001bf916d98 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 5920
	60  AppKit                              0x00000001bf91540c -[NSWindow(NSEventRouting) sendEvent:] + 348
	61  AppKit                              0x00000001bf914878 -[NSApplication(NSEvent) sendEvent:] + 4064
	62  AppKit                              0x00000001bfbcd010 -[NSApplication _handleEvent:] + 76
	63  AppKit                              0x00000001bf7959dc -[NSApplication run] + 636
	64  AppKit                              0x00000001bf767088 NSApplicationMain + 1064
	65  SwiftUI                             0x00000001e16b14c4 $s7SwiftUI6runAppys5NeverOSo21NSApplicationDelegate_So11NSResponderCXcFTf4e_nAA07TestingdG0C_Tg5 + 148
	66  SwiftUI                             0x00000001e21dba40 $s7SwiftUI6runAppys5NeverOxAA0D0RzlF + 260
	67  SwiftUI                             0x00000001e1c6b658 $s7SwiftUI3AppPAAE4mainyyFZ + 128
	68  CPEdit                              0x0000000100f0f6c0 $s6CPEdit0A3AppV5$mainyyFZ + 40
	69  CPEdit                              0x0000000100f0f778 main + 12
	70  dyld                                0x00000001014590f4 start + 520
)

If relevant, I'm including some information about my machine and environment:

  • Model: 2021 14" MBP
  • macOS version: 12.2 RC
  • Xcode version: 13.2.1
  • Swift version: 5
  • App was running in debug mode and Xcode was attached to it
  • CodeEditorView version 0.9.0 was installed thru SPM

Flexible configuration for the minimap

  • Enable toggling the minimap on or off (i.e., hiding it).
  • Enable the mini editor view as a floating view over the right hand side of the main editor. This should be such that, on narrow devices, we can bring it up, scroll with the broader overview, and hide it again. (Only interesting with iOS support.)

Clean up work after new on-the-fly attribute generation

  • Bracket matching with new architecture
  • Automatic bracket insertion/deletion with new architecture
  • In some cases, there still seems to be a line map update problem (e.g., when deleting and re-inserting a line or so)
  • Gutter redraw needs to be triggered by actual layout change and not whenever layout() is called
  • Minimap is not drawn before scrolling a bit
  • Scroll to bottom after (some) character insertion or deletion
  • Scroll jumps on redraw
  • Initial drawing of the gutter and minimap has a delay on larger files
  • Scroll position is incorrect on restore (restart) — at least for long files

Handle NSAttributedString in MessageInlineView

Currently, MessageInlineView merely uses the string component from the attributed string specifying a message description. We need to take at least the most important attributes into account.

There are two options:

  1. We could render the attributed string using UIKit/AppKit and wrap the resulting view into UIKit.
  2. We could enumerate the attributes in the attributed string and simply handle the most important ones with modifiers on Text() in SwiftUI and concatenate the Text() views.

Multimedia insertions

Ability to insert entire paragraphs of multimedia results into a code view — for example, for results of code execution.

  • How should those insertions be specified? As attributes of the preceding paragraph? Or as a completely separate data structure (like error messages and other notifications etc)?
  • Option 1: with NSTextAttachments, it is possible to to embed arbitrary objects in the text. Attachments don't have to be stored in the text storage. They can also be on-the-fly generated (it seems).
  • Option 2: we can dynamically create vertical space in the layout of a text view by using the NSLayoutManagerDelegate using layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:) or layoutManager(_:paragraphSpacingAfterGlyphAt:withProposedLineFragmentRect:) (see also WWDC 2012 Session 220).

No such module 'Rearrange'

Latest commit that use Rearrange package will throw this error during compile.
Try to add Rearrange to Build Phase -> Target Dependencies doesn't solve the issue.

Steps:

  1. Clean Build Folder (we need to run this, then it will show Rearrange not found)
  2. Build the app

image

Automatically insert closing "

Automatically insert closing double quotes like with brackets, but don't auto-erase them in pairs like brackets. NB: Don't do this for single quotes, because it'll mess up using single quotes in identifiers.

Questions

Hi,

thank you very much for this. A good code editor is urgently needed for SwiftUI! This really fills a void. Would be so cool not to have to use Ace in a WebView anymore.

Some questions:

  1. Will it be possible to have sessions, i.e. when you have several source files to switch between source sessions which restores the cursor / scroll location for that session (and the messages if possible) ?
  2. Will it be possible to to provide custom syntax highlighting for custom languages from the outside ? I have my own scripting language.

IMHO focus on making the core usable for a v1 and add all the options / features later ...

Thanks

Initial drawing and drawing during resizing of background highlights

  • 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?)
    • 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.
  • 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).

Changing font size

If I want to change the default font size, what is the best way to do that? I tried to create a new theme with a different font size to pass into the CodeEditor call, but I get

'Theme' initializer is inaccessible due to 'internal' protection level

I don't see any other obvious way to make that change.

Thanks

More Overall Visual Consistency with Xcode

We seem to generally be following the editor visual style of Xcode. There are a few things that need to be addressed to get be more visually consistent. (left - Xcode, right - CodeEditorView)

image

  • Better syntax highlighting
  • Increased line height
  • Smaller and more narrow line number font.
  • General editor font styling is off (maybe smaller font size by 1px and increased font weight?).

image

image

  • General message styling (typography, iconography, colors, animation, dismiss popover button, etc) needs work

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!

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.

NB: Might not be necessary anymore with TextKit 2.

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.