Deci
- 8 Devlogs
- 17 Total hours
A text editor like nano. My first project using Go.
A text editor like nano. My first project using Go.
I published some binaries on GitHub releases and also made a webpage.
The webpage is live at https://ethmarks.github.io/deci/. I made it using the Lume Tufte theme that I made on Stardance back in June: https://stardance.hackclub.com/projects/18206. It’s still a WIP, but it doesn’t need to be complicated. I don’t think that I really need to put anything on the website other than installation instructions and some screenshots.
I just used the GOOS and GOARCH flags of go build to make the binaries. For the v0.1.0 release, I published binaries for x86 Linux, ARM MacOS, and x86 Windows. I might add support for more platforms later. Meanwhile, if I didn’t make a binary for your platform, you can always just build it from source:
git clone https://github.com/ethmarks/deci.git
cd deci
go build
I do all of my developing work on Linux, so I’ve tested deci pretty thoroughly on Linux. I do have a Windows laptop, but I’ve misplaced the charging cable for it and it’s out of battery, so I can’t test it on Windows right now. I don’t even own an Apple device, so there’s no way I can test on MacOS.
There’s a pretty good chance that you’re reading this devlog on Windows or MacOS right now. If you are, I’d really appreciate it if you could try out deci and let me know if it works.
Scrolling! If you move the cursor all the way to the bottom of the screen, it’ll shift the viewport down. And the opposite if you move the cursor to the top.
This took forever to get right. I kept breaking other things because I had juggle three different “perspectives”: the grid of characters output to the screen, the slice of the grid that’s the viewport, and the actual lines of the file. But it all works now.
I think next I might work on getting a demo set up. Most of the CLI binaries that I’ve downloaded before have used GitHub Releases, so I guess I should figure out how to make those work.
Line numbers! Yay! It took a few attempts to get the Lipgloss structure right. For a while, it either wouldn’t highlight the line number of the active line, or it would only highlight the line number of the active line. But I got it working in the end.
So Lipgloss is like powerful. Wow.
I was using Lipgloss to style the status bar (more on that in a bit), and I took some time to actually read through the docs.
I’d used the picocolors before, which is a JS package that makes working with ANSI codes easier. I had assumed that Lipgloss was kind of like that: you just type lipgloss.Blue rather than \x1b[34m. But it can do all sorts of stuff like borders and padding and centering and compositing and enumeration and like a bajillion other things. I don’t understand how the Lipgloss codebase is only ~12,000 lines; based on how powerful it is, it feels like it should be much bigger.
Anyways, I added active line highlighting and a status bar. Right now, I’ve just made the status bar barf out info about the most recent keypress. For example:
I might decide to make the status bar a bit less talkative later, but for now it’s useful for debugging.
Next, I’m going to work on adding line numbers. I also might decide to refactor the text rendering to use Lipgloss layers.
I’ve found something that I really like about Go compared to TypeScript: you don’t need to import identifiers (e.g. functions) from other files if they’re all part of the some package.
I did a big refactor to split the 400-line behemoth main.go into a handful of smaller files. I was fully expecting to have to import each and every constant, type, and function between files. But I didn’t have to! Because every file is part of the main package, they all use the same namespace or something. I defined the statusMsg struct in update.go, but I can just instantiate a statusMsg literal in file.go without any imports or anything! This is a really cool language feature. 10/10.
Anyways, apart from the big refactor, I did the following:
deci operates on a strict “1 character = 1 byte = 1 column’ basis because I don’t wanna deal with Unicode, so properly implementing tabs was out of the question. Instead, I just made the tab key instantly insert 4 spaces.None of this stuff was on last devlog’s list of features to implement. I just kept noticing that these behaviors were missing while playtesting, so I implemented them. Next up is the aesthetic stuff like the status bar that I promised last devlog.
Hi again! The past three hours have been a manic frenzy of adding features. I’m starting to get the hang of Go. I’m not used to working so quickly, but working on this project is surprisingly exciting.
New features:
nano-style header that currently says deci 0.0.1 on the left and by @ethmarks on the right.Features I want to add next:
Oh, and I’ve decided that deci is ASCII-only. Go is weird about counting characters if they occupy more than one byte, so it would be a huge pain to add support for Unicode and would probably lead to a bajillion bugs.
To make sure you understand what I mean about the ASCII thing, I’ll provide an example: the hamster emoji is 1 character, it occupies 2 columns in the terminal, and it’s made of 4 bytes. Because of the last part, len("🐹") returns 4 in Go, so any string with a hamster emoji in it will appear to have 3 more characters and occupy 2 more columns than it actually does.
Making sure that the code reliably distinguishes between those three very similar concepts would be really challenging, and the only benefit would be that you could use emojis and non-Latin characters in deci. I don’t really think that it’s worth it.
deci is shaping up shockingly quickly. I almost could have written this devlog in deci, though the lack of horizontal or vertical scrolling would probably prevent me from actually writing the full thing.
I stayed up late into the night yesterday reading docs for Go and Bubble Tea. Here are the ones I read:
So far, my overall impressions are “wow, Go kinda sucks compared to TypeScript”. Maybe it’s just that I’m only scratching the surface and I’ve yet to see the true advantages of Go, but so far I am unimpressed. It’s just much more restrictive and much less expressive than TypeScript while simultaneously somehow being more prone to runtime panics, at least from my small amount of experience.
Anyways, I’ve also gotten a decent amount of work done. deci can now kind of edit files. Watch the video below for a demonstration.
Things that work:
Things that might seem like they would work based on the list above, but actually don’t:
There’s still a lot to do. It might seem like I’ve made a lot of progress but I doubt that I’m even 10% of the way done.
Are you tired of using actual editors, but nano is still too feature-rich and stable for you?
Introducing
deci, your second-to-last next editor
I’m making this because I want to learn the Go lang. I’ve heard that Bubble Tea is the best of the best for making TUIs, but I’ve never used it because it requires using Go. Since I want to learn Go anyways, I figured that I’d give Bubble Tea a shot. I was trying to think of what kind of TUI to make, and a nano/vim/helix style text editor was the first thing that sprang to my mind.
Obviously, my editor won’t have as many features as even nano (which is quite a low bar). I intend to have text rendering, file reading and writing, character insertion and deletion, an undo buffer, and maybe some other stuff.
Don’t hold me to this, but I might even implement markdown previewing via wrapping the Glamour utility.
The goal that I’m setting for myself is to write my final devlog for
deciusingdeciitself.
Anyways, the name deci comes from the Metric prefix Deci, meaning 10^-1. nano comes from Nano, meaning 10^-9. It’s a bit of wordplay:
deci binary will be much heavier than the nano binary because it has to bundle the Go runtime which is like 3-10 MB.deci editor, but tons of people know about nano.Anyways, all that I’ve done so far is come up with a plan, write the stub README, and make the terrible banner that you see below.
Next, I’m going to install Go and start reading the Bubble Tea docs.