From a142572b5445ff42601c43dc8c83b2eb13cd18a3 Mon Sep 17 00:00:00 2001 From: Jeremy Ruten Date: Tue, 4 Apr 2017 12:41:12 -0600 Subject: [PATCH] =?UTF-8?q?=E2=9C=93=E2=9C=93=E2=9C=93=E2=9C=93=E2=9C=93?= =?UTF-8?q?=E2=9C=93=E2=9C=93=E2=9C=93=E2=9C=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/00.index.md | 2 +- doc/01.setup.md | 12 ++++----- doc/02.enteringRawMode.md | 24 ++++++++--------- doc/03.rawInputAndOutput.md | 52 ++++++++++++++++++------------------ doc/04.aTextViewer.md | 50 +++++++++++++++++----------------- doc/05.aTextEditor.md | 3 ++- doc/06.search.md | 9 ++++--- doc/07.syntaxHighlighting.md | 10 +++---- doc/08.appendices.md | 4 +-- 9 files changed, 83 insertions(+), 83 deletions(-) diff --git a/doc/00.index.md b/doc/00.index.md index 2d34229..df832b5 100644 --- a/doc/00.index.md +++ b/doc/00.index.md @@ -22,7 +22,7 @@ observing the results. See the [appendices](08.appendices.html) for more information on the tutorial itself (including what to do if you get stuck, and where to get help). -If you're ready to begin, head on to [chapter 1](01.setup.html)! +If you're ready to begin, then go to [chapter 1](01.setup.html)! ## Table of Contents diff --git a/doc/01.setup.md b/doc/01.setup.md index c6823cb..177f317 100644 --- a/doc/01.setup.md +++ b/doc/01.setup.md @@ -79,9 +79,9 @@ To compile `kilo.c`, run `cc kilo.c -o kilo` in your shell. If no errors occur, this will produce an executable named `kilo`. `-o` stands for "output", and specifies that the output executable should be named `kilo`. -To run `kilo`, type `./kilo` in your shell and press enter. The program doesn't -print any output, but you can check its exit status (the value `main()` -returns) by running `echo $?`, which should print `0`. +To run `kilo`, type `./kilo` in your shell and press Enter. The +program doesn't print any output, but you can check its exit status (the value +`main()` returns) by running `echo $?`, which should print `0`. ## Compiling with `make` @@ -105,7 +105,7 @@ We have added a few things to the compilation command: * `$(CC)` is a variable that `make` expands to `cc` by default. * `-Wall` stands for "**all** **W**arnings", and gets the compiler to warn you when it sees code in your program that might not technically be wrong, but is - considered bad or questionable usage of the C language, e.g. using variables + considered bad or questionable usage of the C language, like using variables before initializing them. * `-Wextra` and `-pedantic` turn on even more warnings. For each step in this tutorial, if your program compiles, it shouldn't produce any warnings except @@ -140,6 +140,6 @@ to recompile, and just run `./kilo`, and wonder why your changes to `kilo.c` don't seem to have any effect. You must recompile in order for changes in `kilo.c` to be reflected in `kilo`. -In the [next chapter](02.enteringRawMode.html), we'll learn how to get the -terminal into *raw mode*, and read individual keypresses from the user. +In the [next chapter](02.enteringRawMode.html), we'll work on getting the +terminal into *raw mode*, and reading individual keypresses from the user. diff --git a/doc/02.enteringRawMode.md b/doc/02.enteringRawMode.md index a20ce51..de377be 100644 --- a/doc/02.enteringRawMode.md +++ b/doc/02.enteringRawMode.md @@ -43,15 +43,14 @@ in it, and then press enter. The program will quickly read the line of text one character at a time until it reads the `q`, at which point the `while` loop will stop and the program will exit. Any characters after the `q` will be left unread on the input queue, and you may see that input being fed into your shell -after your program exits. What's happening is your shell is calling `read()` -and getting your program's unread input as its input. +after your program exits. ## Turn off echoing -We can set a terminal's attributes by using `tcgetattr()` to read them into a -struct, then modifying the struct ourselves, and finally passing the modified -struct to `tcsetattr()` to write the new terminal attributes back out. We'll -start by turning off the `ECHO` feature. +We can set a terminal's attributes by (1) using `tcgetattr()` to read the +current attributes into a struct, (2) modifying the struct by hand, and +(3) passing the modified struct to `tcsetattr()` to write the new terminal +attributes back out. Let's try turning off the `ECHO` feature this way. {{echo}} @@ -107,10 +106,9 @@ whether it exits by returning from `main()`, or by calling the `exit()` function. This way we can ensure we'll leave the terminal attributes the way we found them when our program exits. -We store the original terminal attributes in a global variable, `orig_termios`, -since there is no other way for `disableRawMode()` to access them. We assign -the `orig_termios` struct to the `raw` struct in order to make a copy of it -before we start making our changes. +We store the original terminal attributes in a global variable, `orig_termios`. +We assign the `orig_termios` struct to the `raw` struct in order to make a copy +of it before we start making our changes. You may notice that leftover input is no longer fed into your shell after the program quits. This is because of the `TCSAFLUSH` option being passed to @@ -347,7 +345,7 @@ type really fast, you can see that `read()` returns right away after each keypress, so it's not like you can only read one keypress every tenth of a second. -If you're using Bash for Windows, you'll see that `read()` still blocks for +If you're using **Bash on Windows**, you may see that `read()` still blocks for input. It doesn't seem to care about the `VTIME` value. Fortunately, this won't make too big a difference in our text editor, as we'll be basically blocking for input anyways. @@ -367,8 +365,8 @@ program. Most C library functions that fail will set the global `errno` variable to indicate what the error was. `perror()` looks at the global `errno` variable and prints a descriptive error message for it. It also prints the string given -to it before the error message, which is meant to provide context about what -part of your code caused the error. +to it before it prints the error message, which is meant to provide context +about what part of your code caused the error. After printing out the error message, we exit the program with an exit status of `1`, which indicates failure (as would any non-zero value). diff --git a/doc/03.rawInputAndOutput.md b/doc/03.rawInputAndOutput.md index 36bd46e..998f3a6 100644 --- a/doc/03.rawInputAndOutput.md +++ b/doc/03.rawInputAndOutput.md @@ -3,7 +3,7 @@ ## Press Ctrl-Q to quit Last chapter we saw that the Ctrl key combined with the alphabetic -keys seemed to map to the bytes 1–26. We can use this to detect +keys seemed to map to bytes 1–26. We can use this to detect Ctrl key combinations and map them to different operations in our editor. We'll start by mapping Ctrl-Q to the quit operation. @@ -112,17 +112,17 @@ wherever the cursor happens to be at that point. {{clean-exit}} We have two exit points we want to clear the screen at: `die()`, and when the -user presses `Ctrl-Q` to quit. +user presses Ctrl-Q to quit. We could use `atexit()` to clear the screen when our program exits, but then the error message printed by `die()` would get erased right after printing it. ## Tildes -It's time to start drawing. Let's start by drawing a column of tildes (`~`) on -the left hand side of the screen, like [vim](http://www.vim.org/) does. In our -text editor, we'll draw a tilde at the beginning of any lines that come after -the end of the file being edited. +It's time to start drawing. Let's draw a column of tildes (`~`) on the left +hand side of the screen, like [vim](http://www.vim.org/) does. In our text +editor, we'll draw a tilde at the beginning of any lines that come after the +end of the file being edited. {{tildes}} @@ -184,8 +184,7 @@ Now we're ready to display the proper number of tildes on the screen: `ioctl()` isn't guaranteed to be able to request the window size on all systems, so we are going to provide a fallback method of getting the window -size. Unfortunately, it's a complex procedure, but it's pretty much guaranteed -to work on any system. +size. The strategy is to position the cursor at the bottom-right of the screen, then use escape sequences that let us query the position of the cursor. That tells @@ -227,8 +226,8 @@ Next we need to get the cursor position. The `n` command ([Device Status Report](http://vt100.net/docs/vt100-ug/chapter3.html#DSR)) can be used to query the terminal for status information. We want to give it an argument of `6` to ask for the cursor position. Then we can read the reply from -standard input. Let's print out each character from standard input to see what -the reply looks like. +the standard input. Let's print out each character from the standard input to +see what the reply looks like. {{cursor-query}} @@ -296,9 +295,9 @@ unpredictable pauses between `write()`'s, which would cause an annoying flicker effect. We want to replace all our `write()` calls with code that appends the string to -a buffer, and then `write()` this buffer at the end. Unfortunately, C doesn't -have dynamic strings, so we'll create our own dynamic string type that supports -one operation: appending. +a buffer, and then `write()` this buffer out at the end. Unfortunately, C +doesn't have dynamic strings, so we'll create our own dynamic string type that +supports one operation: appending. Let's start by making a new `/*** append buffer ***/` section, and defining the `abuf` struct under it. @@ -310,7 +309,7 @@ We define an `ABUF_INIT` constant which represents an empty buffer. This acts as a constructor for our `abuf` type. Next, let's define the `abAppend()` operation, as well as the `abFree()` -operation. +destructor. {{abuf-append}} @@ -453,11 +452,12 @@ Now you should be able to move the cursor around with those keys. Now that we have a way of mapping keypresses to move the cursor, let's replace the wasd keys with the arrow keys. -Last chapter we saw that pressing an arrow key sends multiple bytes as input to -our program. These bytes are in the form of an escape sequence that starts with -`'\x1b'`, `'['`, followed by an `'A'`, `'B'`, `'C'`, or `'D'` depending on -which of the four arrow keys was pressed. Let's modify `editorReadKey()` to -read escape sequences of this form as a single keypress. +Last chapter we [saw](02.enteringRawMode.html#display-keypresses) that pressing +an arrow key sends multiple bytes as input to our program. These bytes are in +the form of an escape sequence that starts with `'\x1b'`, `'['`, followed by an +`'A'`, `'B'`, `'C'`, or `'D'` depending on which of the four arrow keys was +pressed. Let's modify `editorReadKey()` to read escape sequences of this form +as a single keypress. {{detect-arrow-keys}} @@ -531,9 +531,9 @@ Now you see why we declared `seq` to be able to store 3 bytes. If the byte after `[` is a digit, we read another byte expecting it to be a `~`. Then we test the digit byte to see if it's a `5` or a `6`. -Okay, let's make Page Up and Page Down do something now. -For now, we'll have them move the cursor to the top of the screen or the bottom -of the screen. +Let's make Page Up and Page Down do something. For now, +we'll have them move the cursor to the top of the screen or the bottom of the +screen. {{page-up-down-simple}} @@ -553,10 +553,10 @@ pressing the Page Up and Page Down keys. Now let's implement the Home and End keys. Like the previous keys, these keys also send escape sequences. Unlike the previous keys, there are many different escape sequences that could be sent by these keys, -depending on your OS, or your terminal emulator, or who knows what. The -Home key could be sent as `[1~`, `[7~`, `[H`, or -`OH`. Similarly, the End key could be sent as `[4~`, -`[8~`, `[F`, or `OF`. Let's handle all of these cases. +depending on your OS, or your terminal emulator. The Home key could +be sent as `[1~`, `[7~`, `[H`, or `OH`. Similarly, the +End key could be sent as `[4~`, `[8~`, `[F`, or +`OF`. Let's handle all of these cases. {{detect-home-end}} diff --git a/doc/04.aTextViewer.md b/doc/04.aTextViewer.md index 2a82fe2..1f391e7 100644 --- a/doc/04.aTextViewer.md +++ b/doc/04.aTextViewer.md @@ -19,7 +19,7 @@ file just yet. Instead, we'll hardcode a "Hello, world" string into it. {{hello-world}} -`ssize_t` comes from ``. +`malloc()` comes from ``. `ssize_t` comes from ``. `editorOpen()` will eventually be for opening and reading a file from disk, so we put it in a new `/*** file i/o ***/` section. To load our "Hello, world" @@ -59,17 +59,17 @@ arguments, `editorOpen()` will not be called and they'll start with a blank file. `getline()` is useful for reading lines from a file when we don't know how much -memory to allocate for each line. `getline()` takes care of memory management -for you. First, we pass it a null `line` pointer and a `linecap` (line -capacity) of `0`. That makes it allocate new memory for the next line it reads, -and set `line` to point to the memory, and set `linecap` to let you know how -much memory it allocated. Its return value is the length of the line it read, -or `-1` if it's at the end of the file and there are no more lines to read. -Later, when we have `editorOpen()` read multiple lines of a file, we will be -able to feed the new `line` and `linecap` values back into `getline()` over and -over, and it will try and reuse the memory that `line` points to as long as the -`linecap` is enough to fit the next line it reads. For now, we just copy the -one line it reads into `E.row.chars`, and `free()` the `line` that `getline()` +memory to allocate for each line. It takes care of memory management for you. +First, we pass it a null `line` pointer and a `linecap` (line capacity) of `0`. +That makes it allocate new memory for the next line it reads, and set `line` to +point to the memory, and set `linecap` to let you know how much memory it +allocated. Its return value is the length of the line it read, or `-1` if it's +at the end of the file and there are no more lines to read. Later, when we have +`editorOpen()` read multiple lines of a file, we will be able to feed the new +`line` and `linecap` values back into `getline()` over and over, and it will +try and reuse the memory that `line` points to as long as the `linecap` is big +enough to fit the next line it reads. For now, we just copy the one line it +reads into `E.row.chars`, and then `free()` the `line` that `getline()` allocated. We also strip off the newline or carriage return at the end of the line before @@ -83,8 +83,8 @@ our code more portable. {{feature-test-macros}} -We add them above our includes, because the header files use the macros to -decide what features to expose when we include them. +We add them above our includes, because the header files we're including use +the macros to decide what features to expose. Now let's fix a quick bug. We want the welcome message to only display when the user starts the program with no arguments, and not when they open a file, as @@ -197,9 +197,9 @@ offset) variable to the global editor state. {{coloff}} -Now to display each row at the column offset, we'll use `E.coloff` as an index -into the `chars` of each `erow` we display, and subtract the number of -characters that are to the left of the offset from the length of the row. +To display each row at the column offset, we'll use `E.coloff` as an index into +the `chars` of each `erow` we display, and subtract the number of characters +that are to the left of the offset from the length of the row. {{use-coloff}} @@ -269,8 +269,8 @@ of length `0`, which works for our purposes here. ## Moving left at the start of a line -Let's allow the user to press the left arrow key at the beginning of the line -to move to the end of the previous line. +Let's allow the user to press at the beginning of the line to +move to the end of the previous line. {{moving-left}} @@ -278,8 +278,8 @@ We make sure they aren't on the very first line before we move them up a line. ## Moving right at the end of a line -Similarly, let's allow the user to press the right arrow key at the end of a -line to go to the beginning of the next line. +Similarly, let's allow the user to press at the end of a line +to go to the beginning of the next line. {{moving-right}} @@ -299,8 +299,8 @@ the future it could be used to render nonprintable control characters as a `^` character followed by another character, such as `^A` for the Ctrl-A character (this is a common way to display control characters in the terminal). -You may also notice that when the tab character in the Makefile is displayed by -the terminal, it doesn't erase any characters on the screen within that tab. +You may also notice that when the tab character in the `Makefile` is displayed +by the terminal, it doesn't erase any characters on the screen within that tab. All a tab does is move the cursor forward to the next tab stop, similar to a carriage return or newline. This is another reason why we want to render tabs as multiple spaces, since spaces erase whatever character was there before. @@ -486,8 +486,8 @@ We make sure to cut the status string short in case it doesn't fit inside the width of the window. Notice how we still use the code that draws spaces up to the end of the screen, so that the entire status bar has a white background. -Now let's show the current line number, and have it aligned to the right edge -of the screen. +Now let's show the current line number, and align it to the right edge of the +screen. {{status-bar-right}} diff --git a/doc/05.aTextEditor.md b/doc/05.aTextEditor.md index a53d77c..c28262d 100644 --- a/doc/05.aTextEditor.md +++ b/doc/05.aTextEditor.md @@ -79,7 +79,8 @@ character would send back in the day. If you look at the named `BS` for "backspace", and ASCII code `127` is named `DEL` for "delete". But for whatever reason, in modern computers the Backspace key is mapped to `127` and the Delete key is mapped to the escape sequence -`[3~`, as we saw at the end of [chapter 3](03.rawInputAndOutput.html). +`[3~`, as we saw at the end of +[chapter 3](03.rawInputAndOutput.html#the-delete-key). Lastly, we handle Ctrl-L and Escape by not doing anything when those keys are pressed. Ctrl-L is traditionally used to refresh diff --git a/doc/06.search.md b/doc/06.search.md index ae45aa7..08ce7b5 100644 --- a/doc/06.search.md +++ b/doc/06.search.md @@ -28,16 +28,17 @@ There's one problem here. Did you notice what we just did wrong? We assigned a tabs to the left of the match, the cursor is going to be in the wrong position. We need to convert the `render` index into a `chars` index before assigning it to `E.cx`. Let's create an `editorRowRxToCx()` function, which is the opposite -of the `editorRowCxToRx()` function we wrote in chapter 4, but contains a lot -of the same code. +of the `editorRowCxToRx()` function we wrote in +[chapter 4](04.aTextViewer.html#tabs-and-the-cursor), but contains a lot of the +same code. {{rx-to-cx}} To convert an `rx` into a `cx`, we do pretty much the same thing when converting the other way: loop through the `chars` string, calculating the current `rx` value (`cur_rx`) as we go. But instead of stopping when we hit a -particular `cx` value and returning `rx`, we want to stop when we hit the -given `rx` value and return `cx`. +particular `cx` value and returning `cur_rx`, we want to stop when `cur_rx` +hits the given `rx` value and return `cx`. The `return` statement at the very end is just in case the caller provided an `rx` that's out of range, which shouldn't happen. The `return` statement inside diff --git a/doc/07.syntaxHighlighting.md b/doc/07.syntaxHighlighting.md index f4f74b2..e5c76a8 100644 --- a/doc/07.syntaxHighlighting.md +++ b/doc/07.syntaxHighlighting.md @@ -46,7 +46,7 @@ array. Let's add an array to the `erow` struct named `hl`, which stands for {{syntax-refactoring}} `hl` is an array of `unsigned char` values, meaning integers in the range of -`0` to `255`. Each value in the array will correspond with a character in +`0` to `255`. Each value in the array will correspond to a character in `render`, and will tell you whether that character is part of a string, or a comment, or a number, and so on. Let's create an `enum` containing the possible values that the `hl` array can contain. @@ -59,7 +59,7 @@ array, and we want every other value in `hl` to be `HL_NORMAL`. Let's create a new `/*** syntax highlighting ***/` section, and create an `editorUpdateSyntax()` function in it. This function will go through the -contents of an `erow` and highlight them by setting each value in the `hl` +characters of an `erow` and highlight them by setting each value in the `hl` array. {{editor-update-syntax}} @@ -266,7 +266,7 @@ editor state, and initialize it to `NULL`. {{e-syntax}} When `E.syntax` is `NULL`, that means there is no filetype for the current -file, and no syntax highlighting will be done. +file, and no syntax highlighting should be done. Let's show the current filetype in the status bar. If `E.syntax` is `NULL`, then we'll display `no ft` ("no filetype") instead. @@ -295,8 +295,8 @@ filename, then there is no filetype. Then we loop through each `editorSyntax` struct in the `HLDB` array, and for each one of those, we loop through each pattern in its `filematch` array. We use `strstr()` to check if the filename contains the current pattern. If so, -then our next check depends on whether the pattern started with a dot (`.`). If -it did, then we assume it's a file extension, and so we make sure the matched +then our next check depends on whether the pattern started with a dot. If it +did, then we assume it's a file extension, and so we make sure the matched string is at the end of the filename instead of somewhere in the middle. If the pattern doesn't start with a dot, then the match can be anywhere in the filename. If the filename matched according to those rules, then we set diff --git a/doc/08.appendices.md b/doc/08.appendices.md index bb28567..0afc4d3 100644 --- a/doc/08.appendices.md +++ b/doc/08.appendices.md @@ -73,7 +73,7 @@ a different indent style than the one in the tutorial. If you are having trouble, feel free to create an [issue](https://github.com/snaptoken/kilo-tutorial/issues) on the tutorial's -[GitHub repo](https://github.com/snaptoken/kilo-tutorial), and ask for help. +[GitHub repo](https://github.com/snaptoken/kilo-tutorial), and ask a question. You can also [email me](mailto:jeremy.ruten@gmail.com) directly if you'd rather not use GitHub. @@ -161,7 +161,7 @@ file, soon. Changes to the code will cause problems for everyone who is currently part of the way through the tutorial, so these changes should probably be kept in a separate branch until a new, `1.0.0` version of the tutorial is released or -something. +something. Changes to the code should be bugfixes only, not new features. To use `leg` to generate the final static HTML files: