Austin Rude's Blog

Introducing Zeal: Devlog #01

Zeal is my closed-source Zig IDE written entirely in Swift and Zig. I'm at about 21,000 lines of code, and while I've just gotten started, I'm excited about how things are shaping up.

Main IDE Window
This is the main IDE window. Don't get too excited, most of it doesn't work yet!

Today I want to share the design decisions, my reasons for using Swift instead of going all-in on Zig, and what I want Zeal to be able to do when it's ready for primetime.

The Vision

Articulating (or even knowing) the roadmap/features this early is difficult! Instead, I want to share some of the goals or themes of the IDE:

Everything should be available in the IDE

Leaving the IDE to go check documentation often ends up consuming a lot of time. Instead, I would like my IDE to have a powerful documentation viewer and code browser so I don't have to switch to my browser and start searching GitHub or docs.

I also want to explore displaying type-specific information in the popups that appear when you click on built-in types. As an example, clicking the i16 keyword would display the min/max values for the integer sizes. I haven't memorized them, and I don't like having to open a calculator every time I need to know. If you notice when looking at the table that a different integer size suits you better, just click it and it's replaced.

Spark joy

It's a bit of a meme at this point, but Software doesn't have to be boring. I want to build something that is fun to use – so fun that users will want to explore it. I'm talking tons of little tools, cheatsheets, and interactive UIs that are ready to help you write Zig code.

Use font/color to reflect actual code semantics

I think there's a general lack of consistency in most developer tools. Especially when it comes to font and color.

I want to explore heavily using the semantics of the code to drive the font/color choices in syntax highlighting, etc. I think this will help users understand the codebases they work in. I spent quite a bit of time several years ago implementing a perceptually uniform color space from a paper, which I plan to use for this.

Developer tools don't have to be restrictive

Sometimes when I start working in an IDE, I feel like I am trapped in a sort of container. I want to avoid that. Jotting down a quick note, or testing out some syntax should be care-free. I shouldn't have to create a new file, add it to .gitignore, etc. just to take some notes or maintain a to-do list. Same for trying out some code – I want to just click "New Playground", and get thrown into a temporary sandbox so I can experiment.

It's a Graphical User Interface, NOT Text!

Gone are the days of being limited to 80 characters of text on a line. A modern IDE should make use of that extra space and help me do my job of writing software. This means providing context when editing code, adjusting settings, and wherever else it is useful.

Don't make the user remember every damn thing

Most editors have plenty of hotkeys, the problem is remembering them! Command palettes have helped a great deal with this, but I want to explore taking this further and making other parts of the IDE "interactive". For instance, what if when a build fails, the hotkeys to navigate backward/forward between build errors appear in the text editor? What if we did this for everything. The fewer hotkeys I have to remember, the better.

Customizable

Since we live in our tools, we should be able to make them our own. Zeal already has the most fun theming system I've ever used.

P.S. Yes, there will be Vim-style hotkeys.

Why Swift and not Zig?

This was a tough decision, and I'd be lying if I said I don't second guess it frequently and investigate re-writing everything in Zig. But, I've written quite a bit of code at this point and have some reasons I think Swift is a better choice for my goals:

  • I'm trying to build the best IDE possible. That means I want to have every platform idiom and quirk working – no surprises or inconsistencies. I don't think that's achievable today unless you build a native application.
  • It's easier for me to leverage the frameworks Apple provides. The scope of the IDE I want to build is huge, so being able to throw a PDF viewer together in a week using PDFKit is a major benefit.
  • I have a lot of experience working on macOS software with Swift. I feel like the stars have aligned with SwiftUI being released since I love making UIs too.
  • When I started, Zig didn't have a library I liked for doing vector graphics. Now we have nanovg-zig, and more are in the works.

As an aside, I started learning about 2D rendering to make the entire IDE in Zig. I got scared of the added scope of something like that plus an IDE. But I hope someone does it – a 2D graphics framework built on WebGPU/mach could be the future of desktop applications.

Anyway, software development is full of trade-offs, and the path I've chosen has many I like.

Architecture

As mentioned, the IDE will be a native macOS app, built with Apple's blessed tech stack: Swift/SwiftUI. I am also using TextKit 2 which is a recently released, more performant text engine.

No Language Server Protocol

I'm going off the beaten path here, and choosing not to use the Language Server Protocol (LSP) to do the IDE bits. I plan to write all the syntax highlighting, code completion, and other IDE things myself in Zig. Communication between Zig and Swift will be done with the C FFI.

This is in contrast to most tools today, which are embracing the LSP. While I think the LSP is great, and personally benefit (and appreciate) that we now have editor/IDE support for so many languages, I do think there is still room for focused tools. I know that not using the LSP will be very difficult, but I think a custom solution will help me deliver an IDE with better performance and more Zig-specific features.


Status Update/Recent Progress

What I've been working on

Most of my time so far has been spent probing how to design different systems and make them flexible. This has been tricky with SwiftUI being relatively new. Figuring out how to make the Preferences window searchable/filterable, and list rows/Views of different types took some time. SwiftUI in general has been pretty difficult to figure out when going beyond basic examples – but I feel like designing things is coming easier for me the more I use it.

Here's a quick overview of what things look like currently:

Theme Switching
The theme switching functionality is roughed out, and fun to play with. I wrote a Zig program to parse a bunch of terminal color schemes, and output them to a Swift source file. I have some ideas for improving the themes, especially the contrast/readability of some – which I think I'll probably put behind an "Automatically Adjust Theme for Readability" toggle or something. I also need to add credits/repo links for the themes.
Preferences
Preferences Window
Right now it's not very pretty, I've just dumped the settings here. I plan to hide most of the granular theming options under an "Advanced" toggle. I also want to do a nice graphical font picker.
Build Options
Build Settings Popover Window
I'm a little scared to share this one. I have some blind spots around manual memory management and systems programming. But I think these "prototype" options make sense and are possible. I also plan to add a "Force evaluation of all code paths" toggle. This would insert hidden comptime blocks to force everything to be evaluated by the compiler for prototyping/learning purposes.
Command Palette
Command Palette Popover Window
This is pretty basic currently. It is at least displaying different things sourced from different parts of the IDE. I still need to figure out how exactly I'll execute things from the menu. That will have some influence on how undo/redo works.
Source Screenshot
Source Code Screenshot Window
Forgive me for this awful UI. It really should have a vertical split, with a sidebar for configuration instead. But the idea is to be able to highlight some code in the editor –> right/alt-click, and pull that code into this UI. I also want to integrate with the wonderful zigbin.io, which could be cool for alt text on code screenshots.
Playground/Sandbox
Playground Window
This is pretty basic as of now, but I do have it set up to run whatever you put in the text editor through the Zig compiler and dump the output.
Ziglings
Ziglings Window
I want to make it possible to learn the language without leaving the IDE. I Need to ask ratfactor if this is okay and include a link to the Ziglings repo encouraging people to sponsor.

Metrics

Some useless but fun stats:

  • Days since the first commit: 546
  • Lines of code: ~21,000

Work hasn't been consistent the entire project duration. SwiftUI was much less capable last year, so I would run into issues and shelve the project


Designing the Theme Switcher

I feel like in some IDEs the OOP architecture of the settings is pretty transparent. Every setting is either a string, double, or bool. And the UI is a text input, slider, or checkbox. That is boring and no different than editing a text file. We can do better than that in a GUI! Some controls deserve extra attention, and the theme picker is one of those.

Sketch of how the theme selection UI should look
I started with this sketch. I wanted a nice picker where the user can see a little preview of the theme to get an idea of whether the theme matches their preferences and is worth trying at a glance. If you're curious, here's the full sketch

Screenshot of how the theme selection UI currently looks
Here's what I ended up with. You'll notice little squares are showing the different colors rather than a miniature IDE/editor. I'd like to try implementing something closer to the sketch – a simplified editor – including a cursor, text, etc., instead.

Creating this UI was pretty fun. I like the structure of my sketch more than what I made. Showing a mini text editor seems like it is a better preview than the little rectangles demoing the theme colors. I plan to make this look more like my sketch in the future. I'll probably need to use SwiftUIs Canvas to make it performant enough. Scrolling was pretty janky since there are over 200 themes – but using .drawingGroup() fixed that.

I think with the number of themes, I need to have good filtering capabilities. The fancy color library I mentioned earlier should let me have a color wheel where the user picks a color, and the themes are then sorted by how well they match the selected color. Also, a filter for dark/light themes would be a nice addition.


What's Next?

My usual strategy is just to run the IDE, poke around a bit, and pick something to work on. But some things I want to do next are:

Syntax Highlighting

I'm slowly working through "Crafting Interpreters" and the awesome Zig Compiler Internals posts to try and learn. As mentioned, I plan to use Zig directly to get syntax highlighting, rather than regular expressions. I think this will be a big step towards the IDE feeling more real.

I also want to experiment with using variable fonts to structure things.

Welcome Window

I've got a nice sketch, and am looking forward to making a Welcome Window/Screen, that will be displayed when you load the IDE and haven't selected a project.

Splitviews

I spent quite a bit of time working on the splitviews, but there are a lot of bugs, missing features, and other issues. I think I designed this part of the IDE a few times and left pieces of each design scattered throughout the UI code. I need to go through it and clean everything up. I also have some neat UI ideas for managing splitviews that I want to implement.

Make Theming stuff beta release ready

The theming stuff is pretty close, and it would be nice to have a feature fully implemented. I'll probably hold off until after WWDC 2022. I have a hunch that Apple will change things related to SwiftUIs data management which will make the theme code a lot less verbose.

Zig specific stuff

I want to get to more Zig-specific things, like displaying compile errors in the IDE, and parsing build.zig options, etc. But I think those won't for a few more months. I just have too many general IDE things left to do.

Cleanup

I've got a lot of code already (~20K LoC), most of which I'd call "prototype" quality. A pass cleaning things up would be beneficial. Every old piece of SwiftUI code I look at has some issues I now know how to fix.

What's the endgame?

I plan to keep it closed-source and sell it. To be able to provide consistent updates, and keep up with Zig/macOS changes it will probably be a subscription. I've thought a lot about it and think this approach will allow me to work on it full-time and flesh out all the ideas I've accumulated.

If I was building a cross-platform IDE, or one targeting multiple languages I think I'd try and do it all open-source and funded with sponsors instead. But that's not the direction I'm going. The goal is to build the best IDE ever, crafted to help you write Zig. Not something that supports every language, with compromises.


This is my first devlog, so bear with me while I figure out the format.

My original plan was to try and do an update at the end of each month. But after writing this post, I am worried about the time commitment and may aim for publishing a post every other month instead. We'll see!

Thank you to the Zig community for being so helpful, and thank you to my friend @TankorSmash for helping me improve this post.

Thank you for reading!

-- Austin (twitter)


Tagged Zig IDE , Zig , macOS , devlog and Zeal