top | item 12065217

Writing an editor in less than 1000 lines of code, just for fun

535 points| dwaxe | 9 years ago |antirez.com

139 comments

order
[+] SwellJoe|9 years ago|reply
Awesome. When I saw all the things it could do in so little code, I assumed a higher level language would be used. But, nope...plain old C with the usual standard libraries.

The parser for the syntax highlighting is super cool. Concise and declarative definition of the syntax (well, the keywords, anyway), in HL_keywords, and then maybe 150 lines of code for the parser. I doubt it would work well for a much more complex language than C (say, JavaScript, or Perl), without a lot more smarts. But, it works really well on the C I looked at. Colors are handled in a cute way, too.

All around, I'm just astounded at how concise this is, while still being entirely readable and comprehensible. This isn't clever/tricky golfing code, this is actually human-readable C code.

Edit: Also, I'm struck by how nice/simple the editorProcessKeypress handling is. Trying to do something like this in JavaScript/HTML5 is crazily more complex and verbose. Seeing something like this reminds me how messy user interaction still is in the browser, compared to old CLI and desktop paradigms.

[+] groovy2shoes|9 years ago|reply
The syntax highlighter isn't really a parser, per se. It's just a lexer / tokenizer / scanner / what-have-you, which tend to be fairly compact state machines.

As an aside, I agree with your edit. As someone who started programming back in the DOS days, whenever I do Web development, I'm always floored by how much it feels like one step forward and two steps back. So many simple things just aren't simple when it comes to the browser, and even certain protocols on the backend like FastCGI seem way more complicated than they need to be (SCGI seems pretty nice, though I feel it's missing a way to signal out-of-band information to the Web server, the way you'd use stderr in CGI, for example (though perhaps I'm missing something there)).

As much as I love the idea of sending semantic markup over the wire for document transfer, I can't help but wonder if a more terminal-like protocol would be better for application "delivery", the way we used to do with telnet and BBSs in the 90s, with an upgrade for multimedia. But I digress...

[+] erlehmann_|9 years ago|reply
> I doubt it would work well for a much more complex language than C (say, JavaScript, or Perl), without a lot more smarts.

Perl can not be parsed, making accurate synthax highlighting impossible: http://www.perlmonks.org/?node_id=663393

[+] sudhirj|9 years ago|reply
Off topic, but my biggest takeaway was that I could aspire to be someone who isn't a twenty something, with a family, with superb work life balance, not living in the valley, sitting in a garden without three 27 inch monitors, not using the latest programming language or fad and still writing beautiful code that a lot of the world runs on.
[+] zaif|9 years ago|reply
I agree. I LOVE how his post weaves in his normal life, having time for doing things he actually loves outside of work, while still continuing to work on passion projects. It just goes to show you that you don't need to always buy into the cowboy coding hype that is often on display here.
[+] cantrevealname|9 years ago|reply
> Let’s say this again, “email client”. The notion of email client itself is gone at this point.

Really? Is it lame to be using an email clients these days?

I still use an email client (Thunderbird) because I can't stand the thought of all my mail sitting forever on Goggle's or whoever's servers. Yes, I know that they could have secretly archived all of my email the moment it was sent or received, and that my privacy is not necessarily enhanced by downloading and storing my mail offline.

That's my main reason, but I can think of many other reasons to prefer email clients to a web interface.

I'm surprised by the sentiment that email clients are passé.

[+] matejn|9 years ago|reply
Gmail's web client also non-optionally auto-wraps text before sending, which is very annoying when you're trying to send a patch or part of a log file.
[+] thope|9 years ago|reply
> Really? Is it lame to be using an email clients these days?

I think he means that wether nano is derived from an email client or not is not important

[+] bbcbasic|9 years ago|reply
Also my android phone has an email client. It's pretty nice to be able to view offline.
[+] petercooper|9 years ago|reply
And yet I read, on Hacker News, a number of people writing how they were often saved by the availability of nano on random systems

All the time, but I even use nano all the time on OS X for full on programming, mostly for quick edits or starting things off before I can be bothered opening a full project in Sublime. (Sure, I can 'get around' in vi, but I just don't seem to have the brain for it and nano is 90% fine. I grew up on GWBASIC so anything is an improvement ;-))

That aside, this feels like it could be a kinda cool command line level equivalent of ToDoMVC. Port this simple editor into Go, Rust, and a few similar languages - see what the differences are, etc.

[+] elsurudo|9 years ago|reply
Nice thing about Nano is that they arrow keys always seem to do what they are supposed to, no matter the system, shell, TTY, etc. Vi seems to have issues sometimes, and needs extra config
[+] alien3d|9 years ago|reply
I also use nano for my alternative notepad++ in windows. If normal ide i only use vscode in osx.
[+] emilong|9 years ago|reply
This is the kind of magic that got me excited about programming in the first place.

I remember being in high school and one day, after class, a friend of mine mentioned that the best programmer we knew had once written a breakout clone with ANSI "graphics." We found him and he said he didn't have the source any more, but we asked him how he did it. He then proceeded to rewrite the whole thing, in Pascal, in about an hour, this time adding animations. Thanks antirez for bringing back that feeling (and, oh yeah, for redis too ;))

PS. the "Low level terminal handling" is gold here.

[+] Chris_Newton|9 years ago|reply
I love seeing little projects like this, and I wish I were better at finding time to do them myself. It’s all too easy when you’ve been programming professionally for a long time, often working on the same projects every day for months or years, to lose that sense of wonder at what we can achieve in a few hours with a modest amount of code. Sometimes it’s good to just sit down for a day or two and hack together a kind of program you’ve never written before, whether that’s a text editor or a puzzle game or rendering a pretty 3D fractal landscape or an IRC chat bot. It’s always nice to see someone else who’s created something that way too, so thanks for sharing.
[+] _vya7|9 years ago|reply
Honestly, this is the most exciting and inspiring project I've seen on HN in years, by far. I love that it's a fully usable terminal-based text editor that has zero dependencies. Just perusing the source code has been extremely interesting and educational for me already, and it's only been 5 minutes. Definitely gonna bookmark this project and hack on it! The TODO list looks like a good start, especially the xterm-based feature.
[+] oneeyedpigeon|9 years ago|reply
You can tell it's going to be good when, on a Mac, you download the source and compile it, and a) it compiles b) it doesn't give a single warning. It's nice when portability actually works.
[+] marssaxman|9 years ago|reply
Yay, this is delightful.

I wrote a nano-inspired TTY-based editor, too, and have used it to do virtually all of my coding work for the last couple of years. There's nothing particularly noteworthy about it, technologically, but it does exactly what I want in exactly the way I want it to, and that was enough to make the time spent feel worth my while.

There's something really satisfying about the exercise of creating one's tools. I think there is a lot of value in projects like this whether anyone else ever uses them or not, as an exercise in software craftsmanship.

Looking at this project, I am inspired to see if I could simplify my editor's codebase. I was never fully convinced that ncurses did enough good to justify its complexity; it might be interesting to adopt this author's approach instead.

[+] Smerity|9 years ago|reply
When I started programming, the basic digital world already existed for me. I never had the experience of typing in a program from a magazine. This is one of those odd experiences where you remember that self-hosting[1] can involve far more components than just the compiler, spiraling an unexpectedly deep path into the development stack.

I just used @antirez's 1k LOC kilo editor to edit his 1K LOC editor and it was an oddly pleasurable experience :)

[1]: https://en.wikipedia.org/wiki/Self-hosting

[+] voltagex_|9 years ago|reply
This is the programming equivalent of a food blog post (technical details interspersed with what's happening in the author's life). It's great and I think there should be more of it!
[+] _pmf_|9 years ago|reply
Cool; now embed it into a 150 MB Electon app and you have a state of the art editor (maybe introduce several arbitrary delays in the range 300 ms - 2 sec for the authentic Atom feeling)!
[+] fitzwatermellow|9 years ago|reply
Wow! I love this!! Thanks for the post antirez, if just for introducing me to this now indispensable tool ;)

asciinema - Record and share your term sessions

https://asciinema.org/

[+] piokuc|9 years ago|reply
Yes, asciinema is a wonderful thing I learned about from this blogpost too. And another one from the asciinema.org: lolcat! Command line forever!
[+] mej10|9 years ago|reply
This is great! I love seeing how experienced programmers write small programs like this, especially "from scratch".
[+] gnuvince|9 years ago|reply
Can anyone explain how to do a full-screen UI using only VT100 codes? If I had to write a small editor, I'd probably reach for something like Termbox for display.
[+] destructionator|9 years ago|reply
First, switch it to alternative screen mode... printf("\033?1047h"); then clear and move and such with other similar prints. See the list here : http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

It really is pretty simple. The big benefit of ncurses is if you want to target terminals other than xterm compatible ones, and they are so rare nowadays that you can really just ignore them....

Input is quite a pain though (however, ncurses sometimes get it wrong too), but the same thing applies, you just need to switch to raw mode with tcsetattr and then have some kind of select() loop or something to watch for escape sequences then translate them into interesting key presses.

Mouse events are the same btw: you write out a sequence to turn them on, then the terminal sends them as sequences to stdin.

I wrote a terminal library myself for the D programming language (and a terminal emulator too!), it is kinda ugly code but it isn't hard.

[+] spc476|9 years ago|reply
You could look at the code to see how it's done, but basically, you send a special sequence of characters that update the screen.

The VT100 (and a lot of terminal emulators these days) use what are called ANSI escape sequences. For instance, to move the cursor, the CUP (CUrsor Position) sequence is used, which is "<ESC> [ <row> ; <col> H" where <ESC> is the ESCAPE ASCII character, <row> is the row number (as ASCII, so for row 12, it's the string "12"), <col> is the column number ("40" for column 40) and the rest are the literal characters. So, in hex, it's 1B 5B 31 32 3B 34 30 48 (<ESC>[12;40H).

There are more sequences (move the cursor up, down, left, right, clear various portions of the screen, change colors, etc).

Conversely, the terminal will send ANSI escape sequences representing certain keys, such as "<ESC>[A" for the up arrow key, "<ESC>[D" for the left arrow key and such. It's then just a matter of recognizing these sequences and doing the appropriate thing ("I received <ESC>[A so the user is moving the cursor up. Update my internal structure to represent that, and send to the terminal <ESC>[A so it moves the cursor on the screen up").

[+] ag_47|9 years ago|reply
Pretty cool. Something like this would make for a nice school project, I would have loved being assigned to write a simple editor back in uni
[+] sscarduzio|9 years ago|reply
@Antirez please please please let this thing have a future: there is a great need for a modern, simple and usabile CLI editor.
[+] technomancy|9 years ago|reply
I think the whole point of this post was that it's a lot of fun to write code if you know it's not going to be taken seriously or used in the long-term, so what you're asking seems to be the exact opposite of why this was created.
[+] masukomi|9 years ago|reply
Neovim https://neovim.io/ is a modern, simple, usable, and powerful CLI editor.

anyone who thinks vim isn't simple just hasn't had a good instructor / tutorial.

[+] wumpus|9 years ago|reply
It would be fun to see this project replicated using some other underlying data structures, e.g. the buffer-gap data structure used by emacs.[0] Does the code become shorter/prettier? etc.

0: https://en.wikipedia.org/wiki/Gap_buffer

[+] Dagwoodie|9 years ago|reply
What challenges might you have if you wanted to implement something like this inside a game framework like Unity or MonoGame with C#, where it renders everything via DirectX or OpenGL?
[+] moron4hire|9 years ago|reply
The main challenge is that, even now, in the year 2016, there is no objectively good, fast, reliable way of rendering arbitrary text with formatting in a texture. Hell, even just plain text is kind of a pain in the ass.

And yes, I know about signed distance fields.

[+] opcon|9 years ago|reply
If you were looking to do this and wanted a text library that is more flexible than MonoGame's bitmap fonts, I maintain the QuickFont library for text rendering with OpenTK: https://github.com/opcon/quickfont. It doesn't have very good unicode support though.
[+] cyberferret|9 years ago|reply
Nice work. I clearly remember writing a full screen editor in a few hundred lines of Turbo Pascal back in '86 because I hated using EDLIN to edit .BAT files in DOS... :D
[+] Razengan|9 years ago|reply
Anyone up for converting it to Swift (3) or Rust?
[+] philippnagel|9 years ago|reply
I am currently learning Rust, would be happy to give it a shot! My email can be found in my profile