Creating a code editor in WinUI 3 for fun #1 - FireCubeStudios/Mica-Studio GitHub Wiki

This is the first of hopefully many "blog posts" detailing the journey of creating this code editor. This post covers why I am doing this project, how it will work and on initial features.

Why I am making this project?

I have several reasons for making this code editor project. One of the reasons is that making a code editor quite a challenging project which I hope will become a useful learning journey to improve my own knowledge on algorhtms, coding, documenting and managing a large project. I also think this could be a useful project to put in my CV and use in interviews and possibly even for my bachelor thesis next year.

Secondly a major reason I wanted to make this code editor is that there is no Windows-native experience code editor not limited to Microsoft platforms. Visual Studio is great but it is an IDE and is heavy while mostly targeting .NET developers. VSCode and a lot of editors use electron or other cross-platform frameworks which don't provide a truly native experience. Meanwhile MacOS has several editors designed to be mac-native like CodeEdit, Nova by Panic. This CodeEdit blog post provides great reasons for why they decided to create a new native MacOS code editor. Now take those reasons from the post and replace MacOS for Windows and you can see why I think this is a good project worth pursuing.

Furthermore, a few more reasons are that I actually tried making a code editor during my first years of programming and it did not go well yet the urge to try again has been lingering for these years and I feel like I have suitable experience by now to make a usable code editor which past me would have been proud about. Finally this project is a great excuse to utilise and learn multiple programming languages. I have always wanted to use languages like rust, python, elixir etc but I can't get myself to make a project unless it is actually used in something other people will use. In this project I plan to utilise several languages, some because they are the best tool for the job and others just for learning. Some examples are using python for a code language detection capability, rust for faster file search and elixir for realtime multiplayer collaborative editing. Ofcourse these are all just ideas for the far future.

My final goal for this code editor is to be vscode-like including support for extensions, debugging, terminal etc. This is probably not a feasible goal to reach by myself but I like to aim high. In the worst case if this project gets abandoned down the line then I hope these blog posts will at least provide useful insights for someone else to continue it. A reasonable goal for v0 is to be able to open a folder, display the folder contents in a treeview, open a file in a new tab, sync the tabs and treeview selection, display a code file with syntax highlighting and some other commands.

Text editing component

For this project I will be using a scintilla wrapper called WinUIEdit by the excellent developer BreeceW WinUIEdit repository. Scintilla is a powerful text editing component which allows for very fine tuned control which can be built upon to implement a wide variety of features. The full documentation is here. In the future I may implement my own text editing component instead of using Scintilla but makign a solid text editor component is an even bigger challenge.

Loading files

For this initial version I implemented loading folders and displaying the folder contents in a TreeView. Initially I used the WinRT Storage APIs for this but it turns out WinUI 3 with CSWinRT interop and marshalling and other stuff makes this a really slow process. It took a couple of seconds to load several files. To fix this I switched to the Win32 File APIs and this had a huge speedup. Unfortunately I do not have benchmarks as I am writing this after I finished implementing this feature. Another optimisation I did was lazy loading so I only display surface level files and folders whiel elaving loading of files within deeper folders for only when the folder node is expanded on the TreeView.

The nodes are abstracted so that there is an IExplorerNode and IExplorerParentNode which can have children. The FolderNode can have child nodes so it implements IExplorerParentNode. In the future there may be a need for adding nodes with children that are not folders so this interface provides a good way of implementing that.

Message based architecture

This project will make heavy use of the CommunityToolkit.MVVM Messengers which allows for loosely coupled code. I foresee this will be especially useful when implementing extensibility as I can have an event stream of "messages" for various functions. As of now the implementations are very basic. There is a message for when a file has been selected in the TreeView and another message for when a File has been opened. I will eventually need to properly document and unit test these as there is a chance this can quickly become messy. A future blog post will detail more about these messages once a more concrete implementation has been designed.

Syntax highlighting

Scintilla uses Lexilla which are lexers for Scintilla to support syntax highlighting and code folding. There are quite a few lexers available for several languages implemented by various authors. The WinUIEdit Scintilla library contains a bunch of these lexers to support several languages by default with all you need to do is specifying the language like so for c#:

<editor:CodeEditorControl x:Name="ScintillaEditor" HighlightingLanguage="csharp"/>

However I do want to support a wider range of languages and one way I could do this by writing a lexer for each language however that is simply not feasible for me to do. Instead after some consideration I have opted to try to implement support for "textmate" grammars and themes for syntax highlighting. VSCode uses textmate too which means essentially if I can implement this then I can support syntax highlighting for any language VSCode supports. Moreover I can support any editor theme which VSCode uses for syntax highlighting. The process of implementing support for textmate is very interesting and will be covered in an upcoming blog post. However for now here is an image of a python file which was syntax highlighted with the python textmate grammar and uses the VSCode DarkPlus theme.