CodeEditApp / CodeEditSourceEditor

A code editor view written in Swift powered by tree-sitter.
https://codeeditapp.github.io/CodeEditSourceEditor/documentation/codeeditsourceeditor
MIT License
510 stars 78 forks source link

Abstract Highlighter Object #139

Closed thecoolwinter closed 1 year ago

thecoolwinter commented 1 year ago

Description

This PR adds an abstraction layer to the Highlighter object. Currently, our TreeSitterClient is tightly integrated with our highlighter, which works great. However, it limits our ability to easily use multiple highlighter providers (eg: tree-sitter, and LSP). To fix this, I've added a HighlightProvider protocol that CETV can interrogate for syntax information to use for highlighting.

This is the first step towards using more than one highlighter. A future PR will need to add the ability for our highlighter to manage highlights from two or more providers. Once that is done #40 can be started.

Related Issues

Detailed Implementation

For the abstraction layer, I've added a HighlightProviding protocol, and an accompanying HighlighterTextView protocol. Classes conforming to the HighlightProviding protocol have a hook to change the language, update text, and return highlights for a text range.

The HighlighterTextView protocol exists so that highlight providers aren't given complete access to the text view. This is done to encourage providers to do as little string copying as possible by providing methods for getting substrings and the document range in the text view.

Because of these changes, the TreeSitterClient class was heavily modified. It was mostly changed to use a ReadBlock while applying changes, and no longer needs to have the text "set" before doing any work. I benchmarked editing and highlighting before and after making these changes, and saw a negligible change in performance between them.

matthijseikelenboom commented 1 year ago

Just a question: How should these abstractions also be implemented in CodeEditKit?

thecoolwinter commented 1 year ago

@matthijseikelenboom since all of the API calls are async through completion handlers, we could have a GenericHighlightProvider or something similar that communicates between an extension and towards stuff to the editor.