A few weeks ago, I ended up writing a text editor. I named it edit9, and I am happily using it still. The source code can be found here:
Edit9 is the result of two experiments. I wanted to see if artificially limiting the lines of code used to implement a program would have a beneficial effect on the quality of the implementation. I also wanted to see what a simpler, more spartan text editing experience was like compared to Emacs, the editor I previously used for programming.
Limiting the lines of code I could use resulted in stopping the cancerous growth that can occur with software projects. Proof: edit9 is actually, for the most part, complete, which is a very comforting feeling. Usually, when I program, my projects grow and grow and grow until suddenly I become disenfranchised and I lose motivation. As I've become more seasoned, I can venture farther into the tangle of unrestricted growth. I've come to believe that this kind of personal "progress" is relatively uninteresting; there will always be a limit to one's endurance, especially when working alone. I am happy to report that limiting the lines of code has had a very positive effect on the project.
Only the truly important features are implemented, weighted by their complexity. This is a very important point. Edit9 does not have undo/redo simply because I could not figure out a sufficiently elegant way of implementing it. On the other hand, visualizing whitespace only costs a few lines (define the whitespace color, add a global flag for whitespace mode, add a line for converting whitespace to visual characters, and add an inline modification to the text style selection logic). Implementing whitespace mode for ~3 lines of code is a bargain!
I found that I stayed away from abstract data types as much as I could. Instead, I judiciously used global variables with simple primitive types. There are a few well-placed abstractions (such as an iterator for moving through the gap buffer while _minding the gap_ and being UTF-8 aware), but those abstractions must actually result in simplifying the code. When limiting the lines of code that we can use, it becomes more apparent that overusing abstract data types produces fluffy code.
The main implementation effort took 7 days. Meaning, after the 7th day, it was complete enough to use. The only work left to do on it is the occasional tweak. I have 12 lines left in my budget, so I may want to try to squeeze in one more feature for a pain point later on. Who knows? The point is that it is done; a permanent mark has been made on the computing landscape, no matter how small. It is also much easier to reflect on a finished project rather than an unfinished one.
Has all this attention on making the implementation more manageable had a negative effect on the program produced at the end? That depends on your viewpoint. I value predictability in my text editing environment, which means I am naturally more bearish on adding features like undo/redo than is likely common. I'm happy to use a text editor where I have to manually format and indent code, since one inevitably butts heads against automated indentation. Sometimes I miss search/replace, but we already have tools like grep and sed for accomplishing those tasks. I'm not a whiz at using those tools, but that's likely because I was insulated from them by being an Emacs user. Using a more spartan tool means that you rely more on the programming environment as a whole, which is one of the things that makes Unix(-likes) special.
It is refreshing to finish a program so completely. Even a polished ~= 512 line program is far from perfect, so it is imperative that we set hard limits on our endeavors in order to have a chance at producing work that meets our ideals. This is something that I've always believed, but it has become even more clear to me now that I have tested it in such a bare way. Further work will include attempting to use this style of programming in future projects and applying it in other domains.