The First Year Working On Bold
One year ago today I started Bold and have been working on it full-time. When I started I thought I would write a debugger and stop there. I found that I really wanted to edit text while debugging. I already implemented text rendering and simple syntax highlighting, why not edit the text that is already on screen? I had previously written a compiler and knew how LSPs worked so I implemented that. As you can guess, if I had all that implemented why stop there. It didn't help that I was sufficiently annoyed at the IDE I was using.
I barely spoken about this project. Now that it's been a year I thought I ought to share some of the designs and talk about implementation. The very first commit I used SDL to draw a black box on the screen with the escape key closing the window and that was it. I didn't use a UI library, I didn't include code to talk to GDB, and I didn't want to use any code unless I absolutely needed to. I used SDL because that would insulate me from X11 (I originally wrote this on linux). For my sanity, I classified this as a need and it would also take care of other OSes and graphics API. Since I already was using SDL, I used SDL_ttf to load fonts but I didn't know that wouldn't last long. At the end of the first day, I rendered some text and had a keyword highlighted
I'm not a fan of dependencies and I'm very comfortable writing all sorts of code. I knew gdb --interpreter=mi
existed so I looked at the documentation. The idea is a process can control GDB by writing commands into standard input and reading the results from standard out. The example docs say to use -exec-run
to start the program but I found run
and other REPL commands to work so I ended up using a mix. I implemented gdb by writing unit tests so I wouldn't need to write the UI. I implemented run, changing stacks, and getting local variables. On the 14th I implemented UI and did a demo for friends on the 15th. The build seems to depend on my environment and I can't seem to reproduce it but I can show some screenshots from that demo.
The next big thing was text editing. Everyone told me handling undo and redo would be difficult but... it wasn't. I don't write much code in the OOP style, but I knew that I'd need to manage the state of the source file so I created a TextFile class and the only way to interact with the source file was to go through it. I created a few methods like insert, paste, indent, moveCursor, and such. When I did an action that modified the file I'd create a record of it in the history. It would contain text I insert (by typing or a paste), the cursor position so it'd know where to insert, if text was selected because that would cause a deletion and a few other things. I didn't want to create an entry for every key press so I buffered a word up before I insert it into the history.
One thing I didn't like about other IDEs is how the undo worked. If I type "first second third", press undo twice, and type in "data loss?", pressing undo will not restore "second" and "third". I didn't like that if I wanted to use many undo's I'd need to make a copy to prevent data loss. Since TextFile was my implementation, I was able to choose how I implemented the history. If you press undo it will restore "second" then "third" which matches what you saw when you pressed undo the first two times. It may be more clear if you try it yourself.
One mistake I made was when I turned off my unit test. I was redesigning thousands of lines of code and changed major data structures. I turned off unit testing because they ran every time and the redesign would take 2 weeks. I didn't immediately turn them on because I wanted to write more experimental code and this is where my mistake happened. I wrote experimental code for two weeks, had tons of bugs in the code I changed during the redesign, completely forgot what I changed, and had to jog my memory for multiple functions before I could fix my bugs. I thought a lot of the bugs were introduced in new code because I knew they didn't exist before the redesign, not realizing I touched certain functions during the redesign. Oh well. It was around this time I took a moment to get code coverage above 90% (for critical files).
There's a lot more I could say about writing a text editor and IDE. Some topics deserve their own article like how font files are crazy, their APIs annoying, and how monospace fonts aren't really monospaced. LSPs and DAPs both deserve their own article, as well as why I still have to write OS-specific code for a good experience. I prefer to write code over articles but I've been asked to write a few times now. I'll make an effort to write more this month and I'll try to write about new features as they come in the next few months.