Showing posts with label Unix. Show all posts
Showing posts with label Unix. Show all posts

Friday, April 21, 2017

kilo: I've started my own version of kilo

Based on the comments I've made so far, I've started my own version of kilo, which you can find here if you are interested.

I've chosen to make some different design and stylistic choices from the previous versions. Most notably, I just can't restrict myself to a single source file. Even for a relatively small project like this, it's just too claustrophobic. I've also chosen the Unix style of underscores in identifiers (editor_process_keypress) rather than camel case (editorProcessKeypress), which feels anachronistic to me in the C/Unix environment.

I've also created a simple Perl script to help deal with the string constant issue I've mentioned previously. This allows arcane terminal escape sequences to be named symbolically, with their length computed at compile time. I expect a decent C optimizer will generate very similar code to the original inline versions.

I've also renamed struct abuf to the typedef-ed term_buffer, so the erstwhile editorRefreshScreen looks like this in my implementation:

void editor_refresh_screen()
{
    term_buffer tb;
    tb_init(&tb);
    
    string_const home_cursor = get_home_cursor_str();

    tb_append_str(&tb, get_cursor_off_str());
    tb_append_str(&tb, home_cursor);

    editor_draw_rows(&tb);

    tb_append_str(&tb, home_cursor);
    tb_append_str(&tb, get_cursor_on_str());
    
    tb_write(&tb);
    tb_free(&tb);
}

The functions get_home_cursor_str(), get_cursor_off_str(), and so on are automatically generated by my Perl script linked above. Notice how much nicer this is than the version shown in step 40:

void editorRefreshScreen() {
  struct abuf ab = ABUF_INIT;

  abAppend(&ab, "\x1b[?25l", 6);
  abAppend(&ab, "\x1b[2J", 4);
  abAppend(&ab, "\x1b[H", 3);

  editorDrawRows(&ab);

  abAppend(&ab, "\x1b[H", 3);
  abAppend(&ab, "\x1b[?25h", 6);

  write(STDOUT_FILENO, ab.b, ab.len);
  abFree(&ab);
}

Saturday, April 8, 2017

Build Your Own Text Editor!

I was reading Hacker News a while back, and came across this link on how to code a simple text editor. This seemed pretty interesting, so I clicked over, spun up an Ubuntu VM, and started following along.

Almost immediately I noticed the coding style was somewhat problematic (at least to my eye), and so one of the things I want to do in this blog is document my thoughts about how the could can be made better.

Perhaps the first question I had was why the ncurses library was not used for terminal I/O. The author does mention this briefly in the third section of the article:

If we wanted to support the maximum number of terminals out there, we could use the ncurses library, which uses the terminfo database to figure out the capabilities of a terminal and what escape sequences to use for that particular terminal.

He doesn't offer any justification for avoiding ncurses, and we are instead simply plunged headlong into the rather arcane world of ioctl and terminal escape sequences. antirez, the original author, does say that his goal was to write:

...a text editor in less than 1000 lines of code that does not depend on ncurses...

Avoiding dependencies to third party libraries is a reasonable enough goal, I suppose. But I think it's at least worth mentioning the fact that avoiding ncurses adds extra inertia to the project.

I should also add by way of disclaimer, that this (as well as future posts about kilo or other software) is not meant as criticism on the various authors involved. They had their own goals in mind when they wrote their code, and I'll let them speak for themselves as to how well they achieved them.

My purpose is to work out my own thoughts on how best to write code that is clear, correct, and easy to modify. If you get something out of it too, that's on the bonus side.