You are browsing as a guest. Sign up (or log in) to start making projects!

Deci

  • 8 Devlogs
  • 17 Total hours

A text editor like nano. My first project using Go.

Open comments for this post

1h 7m 46s logged

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.

0
0
12
Open comments for this post

2h 12m 17s logged

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.

0
0
6
Open comments for this post

1h 8m 38s logged

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.

0
0
6
Open comments for this post

2h 19m 10s logged

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:

  • “inserted ‘a’ at 4:2”
  • “split line 4 to line 5”
  • “merged line 5 with 4”
  • …et cetera

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.

1
0
45
Open comments for this post

1h 45m 42s logged

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:

  • the cursor is now the actual terminal cursor rather than a fake drawn-on cursor.
  • if you use left arrow at the start of a line, the cursor moves to the end of the line above.
  • if you use right arrow at the end of a line, the cursor moves to the start of the line below.
  • delete! It’s exactly like backspace but in the opposite direction.
  • tab! As mentioned, 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.

1
0
9
Open comments for this post

3h 20m 22s logged

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:

  • backspace! If you press backspace, it’ll either delete the character immediately before your cursor, or if you’re at the beginning of a line, it’ll merge current line with the previous one and then shift all other lines upwards.
  • enter! If you press enter, it’ll bifurcate the current line and split the right half onto a new line.
  • the cursor will now stop going out of bounds. It automatically clamps the mouse X position to the max length of the current line.
  • the top row is now reserved for a nano-style header that currently says deci 0.0.1 on the left and by @ethmarks on the right.
  • the cursor now highlights the character under it rather than replacing it with a solid white square.
  • plus lots of bugfixes, mainly fixing bugs that I added while adding the other features mentioned in this list.

Features I want to add next:

  • highlighting the active line by lightening the background color
  • a status bar
  • line numbers
  • a keybind info bar

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.

0
0
7
Open comments for this post

4h 2m 55s logged

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:

  • reading files
  • creating files if they don’t exist
  • transforming the lines of a file into a slice (Go’s version of dynamic-length arrays) of strings
  • displaying the lines on screen
  • moving the cursor around
  • displaying the cursor
  • preventing the cursor from going out of bounds
  • inserting characters onto the current line at the cursor position
  • displaying a line of status text
  • writing lines to the file

Things that might seem like they would work based on the list above, but actually don’t:

  • backspaces
  • creating new lines (aka enter)
  • scrolling through a file
  • displaying the cursor when it isn’t directly over an existing character
  • preventing the cursor from going out of bounds when it goes above or below a line that’s longer than its neighbors
  • other subtle cursor behaviors that are difficult to describe that we take for granted in editors but are surprisingly difficult to implement

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.

2
0
22
Open comments for this post

46m 4s logged

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 deci using deci itself.

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:

  • The Deci prefix is far larger than Nano, and I expect that the 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 is not a very commonly used prefix. There’s basically nothing that uses Deci other than decibels and deciliters, and the “deci” in both of those terms is easy to miss (did you know that decibels are based on Bels? Also, the wikipedia page for Bel redirects to decibel). Nano, on the other hand is extremely common; everybody knows about nanobots and that “nano” means “very small”. Likewise, nobody except you, me, and a handful of other people know about 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.

0
0
9

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…