Giter Club home page Giter Club logo

kilo-tutorial's Introduction

Build Your Own Text Editor

The tutorial is available here: http://viewsourcecode.org/snaptoken/kilo

It is a static HTML site, and you can download your own local copy from here: https://github.com/snaptoken/kilo-tutorial/releases

See the appendices for more information about the tutorial itself, including how to contribute.

License

The kilo source code contained in steps.diff was originally written by Salvatore Sanfilippo (aka antirez) and released under the BSD 2-clause license (see steps.diff.LICENSE). I've made a few minor changes to the original code.

All other files in this repository are licensed under CC BY 4.0.

kilo-tutorial's People

Contributors

fyce avatar kyletolle avatar mtn avatar mtr avatar nirs avatar osiyuk avatar paigeruten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kilo-tutorial's Issues

Can't understand this part! (Step 20)

I'm talking especifically about the bitwise operation:

The CTRL_KEY macro bitwise-ANDs a character with the value 00011111, in binary.

I'm confuse when it says :

in other words, it sets the upper 3 bits of the character to 0. This mirrors what the Ctrl key does in the terminal: it strips bits 5 and 6 from whatever key you press in combination with Ctrl, and sends that. The ASCII character set seems to be designed this way on purpose. (It is also similarly designed so that you can set and clear bit 5 to switch between lowercase and uppercase.)

If the ctrl key strips bit 5 and 6 then the bitwise binary operator should've been 01100000 (96) NOT 00011111 (31) am i right?

Step 5: cursor icon turns into a key

I'm on a Mac. I tried with iTerm2 and with the standard terminal application.
When I unset the ECHO c_lflag the cursor icon changes into a key.
This is the normal behaviour when a password is requested, but it makes no sense in a text editor application.
How could I fix it?

Thank you!

Segmentation fault on failing backwards search

Starting with step 140, if you search for something that doesn't exist and then hit the left arrow, the application segmentation faults. The problem is that current, last_match, and direction are all -1 so current becomes -2. The application only checks for current == -1 for wraparound.

"Patlen" suddenly shows up in the repo between steps 161 and 162

If you go to step 161 and search for "patlen" you get no results

If you go to step 162 and search for "patlen" you do get a result in editorSelectSyntaxHighlight.

(I made this discovery running a diff between step 184 and my own kilo.c file to see if I had any mistakes, then walking backwards. Thank you very much for making this step-by-step guide available, it's been a great time following along)

"&" glyphs being replaced by "|" in the code

A couple readers reported that the & symbols looks like | for them in the code. This seems to be a font issue (I use Fira Mono from Google Fonts for displaying code). One of the readers who reported the issue uses Arch Linux and the problem occurs in multiple browsers.

Save feature is bugged

Hello, I'm studying the tutorial and I arrived to step 130;
I have a big problem with the implementation of saving feature:
every time I save a file and reopen it, the first line of text is missing and the rest of the content goes up by one line.

Do you have the same experience? Do you have any ideas of what part of the program needs fixing?

Discrepancy between kilo-src and kilo-tutorial?

It's possible that I'm being really dumb (likely, even?) but I'm seeing a discrepancy between the final source code (propagate-highlight tag) and the code on the website. Here's the difference as it shows in my code:

@@ -388,14 +403,15 @@ void editorSelectSyntaxHighlight() {
   E.syntax = NULL;
   if (E.filename == NULL) return;
 
+  char *ext = strrchr(E.filename, '.');
+
   for (unsigned int j = 0; j < HLDB_ENTRIES; j++) {
     struct editorSyntax *s = &HLDB[j];
     unsigned int i = 0;
     while (s->filematch[i]) {
-      char *p = strstr(E.filename, s->filematch[i]);
-      if (p != NULL) {
-        int patlen = strlen(s->filematch[i]);
-        if (s->filematch[i][0] != '.' || p[patlen] == '\0') {
+      int is_ext = (s->filematch[i][0] == '.');
+      if ((is_ext && ext && !strcmp(ext, s->filematch[i])) ||
+          (!is_ext && strstr(E.filename, s->filematch[i]))) {
         E.syntax = s;

Note that kilo-src\kilo.c has a reference to an int variable patlen, which doesn't seem to show in the description of this function (contained in section 7).

Why am I entering the while loop straight away in main() ?

I have tried to add a printf() to main() in your code "parse-response" from github because it seemed to me that the while loop was executed right away and I also added a call to editorReadkey. The behavior is quite strange : The program does wait for a keypress but nothing is printed, then it gets into the rendering loop and and when I quit then printf is called ans prints to the terminal. I can't seem to get my head around this. Are while loops executed first by default in C ? I thought everything was linear.

int main() {
  enableRawMode();
  printf("Entering initEditor");
  editorReadKey();
  initEditor();

  while (1) {
    editorRefreshScreen();
    editorProcessKeypress();
  }

  return 0;
}

Is there a way to input character 30 with a Ctrl-<something>?

kinda dumb question here:

I just finished the part where you enter all the termios flags, and I see all the Ctrl- characters show up as 0 to 31

Ctrl-Space for 0,
Ctrl-a to Ctrl-z for 1 to 26,
Ctrl- [ \ ] for 27, 28, 29
Ctrl-<no idea> for 30
Ctrl-- for 31
Space for 32

However, nothing on my keyboard generates character 30. Is there a key combo for that?

Searching in the same row

First of all thank you for the amazing tutorial! I came across an issue in search feature. When we press the arrow keys to find the next match, we move to the next or previous rows. But, there might be matches in the same row. Also, when we search in the reverse direction the match in the last position must be found. I tried implementing this by adding a new function editorFindRowLastMatch( ) and making changes to editorFindCallback( ) and it seems to work.

/*** find ***/
int editorFindRowLastMatch(erow* row, int start, int end, char* query) //find position of last match in a row
{
    int qlen = strlen(query);
    while (end >= start)
    {
        if (row->render[end] == query[0])
        {
            if (!strncmp(&row->render[end], query, qlen))
                return end;
        }
        end--;
    }
    return -1;
}

void editorFindCallback(char* query, int key) {
    static int last_match = -1;
    static int direction = 1;

    static int saved_hl_line;
    static char* saved_hl = NULL;

    if (saved_hl) {
        memcpy(E.row[saved_hl_line].hl, saved_hl, E.row[saved_hl_line].rsize);
        free(saved_hl);
        saved_hl = NULL;
    }

    if (key == '\r' || key == '\x1b') {
        last_match = -1;
        direction = 1;
        return;
    }
    else if (key == ARROW_RIGHT || key == ARROW_DOWN) {
        direction = 1;
    }
    else if (key == ARROW_LEFT || key == ARROW_UP) {
        direction = -1;
    }
    else {
        last_match = -1;
        direction = 1;
    }

    if (last_match == -1) direction = 1;
    int current = last_match;

    int rx = -1; //this variable will contain the postion of the match
    int same_row = 0; //if the match is found in the same row

    if (current != -1) //we check in the same row if there was a previous match
    {
       erow* row = &E.row[current];

        if (direction == 1)
        {
          char* match = strstr(&row->render[E.rx + 1], query); //find a match after the previous match position(E.rx) in the same row 
            if (match)
            {
                rx = match - row->render;
                E.cx = editorRowRxToCx(row, rx);
                same_row = 1;
            }
        }
        else //if in reverse direction
        {
            int lfound = editorFindRowLastMatch(row, 0, E.rx - 1, query); //find the first match before previous match in the same row
            if (lfound != -1)
            {
                rx = lfound;
                E.cx = editorRowRxToCx(row, rx);
                same_row = 1;
            }
        }

    }

    if (!same_row) // if match was not found in the same_row
    {
        int i;
        for (i = 0; i < E.numrows; i++)
        {
            current += direction;
            if (current == -1) current = E.numrows - 1;
            else if (current == E.numrows) current = 0;

            erow* row = &E.row[current];
            char* match = strstr(row->render, query);
            if (match)
            {
                last_match = current;
                E.cy = current;
                rx = match - row->render;
                
                if (direction == -1) //if match found and the direction is reverse we find the last match in that row 
                {
                    int lfound = editorFindRowLastMatch(row, rx + 1, row->rsize - strlen(query), query);
                    if (lfound != -1)
                    {
                        rx = lfound;
                    }
                }
                E.cx = editorRowRxToCx(row, rx);
                E.rowoff = E.numrows;
                break;
            }
        }
    }

    if (rx != -1) // highlight only when match is found
    {
        erow* row = &E.row[current];
        saved_hl_line = current;
        saved_hl = malloc(row->rsize);
        memcpy(saved_hl, row->hl, row->rsize);
        memset(&row->hl[rx], HL_MATCH, strlen(query));
    }

}

WSL2 is better behaved that old "bash on windows" WSL

Working through this with WSL2 and various terminal and keyboard related behaviors just work right now. One specific instance, chapter 5 in the save as section:

"(Note: If you’re using Bash on Windows, you will have to press Escape 3 times to get one Escape keypress to register in our program, because the read() calls in editorReadKey() that look for an escape sequence never time out.)"

Works fine with a single keypress of ESC on my configuration. Suggest changing wording about Bash on Windows to "Bash on Windows prior to WSL2" or similar. Great job on the whole thing though. Appreciated.

Why do we need put back the cursor at origin with EscH after implementing editorMoveCursor ? ?

I am wondering why do we need put back the cursor at origin with the EscH command in the editorRefreshScreen() function after we have implemented editorMoveCursor() ?
Calling snprintf(buf, sizeof(buf), "\x1b[%d;%dH", E.cy + 1, E.cx + 1); should be enough to reposition the cursor and yet it is not :
I tried to erase abAppend(&ab, "\x1b[H", 3); from editorRefreshScreen() but then I noticed that the line which we happen to have the cursor on gets displayed on the first line.
Do you know the reason beahind this strange behaviour ?

Thanks in advance.

Issue in Chapter 3 "editorReadKey" function

I was walking through the following code diff

char editorReadKey() {
  int nread;
  char c;
  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
    if (nread == -1 && errno != EAGAIN) die("read");
  }
  return c;
}

And I have to change the while loop to an if condition to make it work. In fact, the while loop does not seem to break and proceed to the next return statement. I'm not sure if I'm missing something here. Also, before refactoring into this module, the code block was having a if condition as follows

char c = '\0';
if (read(STDIN_FILENO, &c, 1) == -1 && errno != EAGAIN) die("read");

PS: My C is very rusty. I just would like to know what is that I'm missing here.

Thanks.

Shortening of the title in readme file

Now the title in README.md is quite long, it's better to reduce it. As an example, make the current heading simple text, and use the "Build Your Own Text Editor" as a new title for example.

Step 37 suddenly has a ton of errors

I was originally doing the tutorial in C++ and had no issues until step 37, so I switched to C to see if that was the problem. However, even in C I am getting the following errors:

char *new = realloc(ab->b, ab->len + len);

expected unqualified-id [Parse Issue]Clang (c-cpp-flylint)

if (new == NULL) return;

expected a type [Parse Issue]Clang (c-cpp-flylint)

memcpy(&new[ab->len], s, len);

expected a type [Parse Issue]Clang (c-cpp-flylint)

ab->b = new;

expected a type [Parse Issue]Clang (c-cpp-flylint)

For reference, this is what I have, it should be identical to the source thus far but just formatted a little differently bc of my linter:

/*** append buffer ***/

struct abuf
{
    char *b;
    int len;
};

#define ABUF_INIT \
    {             \
        NULL, 0   \
    }

void abAppend(struct abuf *ab, const char *s, int len)
{
    char *new = realloc(ab->b, ab->len + len);
    if (new == NULL)
        return;
    memcpy(&new[ab->len], s, len);
    ab->b = new;
    ab->len += len;
}
void abFree(struct abuf *ab)
{
    free(ab->b);
}

I even tried to clone and run the completed source code, but the same errors popped up. I am new to C and C++, so I am assuming I am making some kind of goofy error, but I was having tons of fun, so I figured I might as well ask! Thanks :)

Windows translating \n to \r instead of \r to \n

See: https://www.reddit.com/r/programming/comments/63lssy/build_your_own_text_editor/dfvlcoc

I have some issues with "Entering raw mode" on Bash for windows.

The flags you provide dont "enable" Ctrl+M and Ctrl+J echoes 13 instead of 10.

raw.c_iflag &= ~(INLCR);

This lets Ctrl+J output the expected 10.

raw.c_iflag &= ~(IGNCR);

This unblocks Ctrl+M and outputs the expected 13.

I wasn't able to reproduce this behaviour and, for some reason, the reporter of the bug wasn't able to either.

Inconsistent Style

Great tutorial, however there are quite a few style issues I see.
For example:

On step 43, you add variables for the cursor's X and Y

struct editorConfig {
    int cx, cy;
    int screenrows;
    int screencols;
    . . .
}

If you put cx and cy on the same line for variable declaration, it's a good idea to also put screenrows and screencols on the same line, and you might even consider pulling all four of them on the same line.

Missing calls to comment VMIN and VTIME between steps 30 and 32

First off, thanks for a great tutorial!

During step 30 and until step 32 where you use editorReadKey in order to block so you can observe output before dying, you have forgotten to comment the lines in enableRawMode:

  /* raw.c_cc[VMIN] = 0; */
  /* raw.c_cc[VTIME] = 1; */

Otherwise, the output is only on the screen for 0.1s before the read call returns and the program returns.

How to deal with umlauts (utf8 / unicode)

Hey there,

first of all thank you for the great tutorial. I followed your steps and got a working editor, ( I skipped the search for now).

But I have one big problem:
When I type umlauts, I get a spacing error. I tried to play around with the output of the step "ctrl-q" but only got weird symbols as an output.

The problem with those chars is that they use 2 positions in the x variable of the cursor, but I fail to understand how I can determine when such a wide char is used.
Also, maybe char is the wrong type to read that kind of input?

Hope you can help me.

Resizing terminal window won't change E.screenrows and E.screencols

Hi,

Thanks for this amazing tutorial. I have been trying to use C in a meaningful way for the longest time and this is a perfect place to start. I am following the tutorial and currently I am on step 49. I have noticed the following issues so far:

  1. Whenever I resize the terminal window, the E.screenrows and E.screencols are not updated. This is because the initEditor() method is called only once before the while(1) loop. So while the screen does get refreshed, the "size of the canvas" doesn't change.

  2. Because of the while loop in editorReadKey(), while the read() method does time out after 0.1 seconds, it still doesn't break the loop unless a key is pressed. Because it is still stuck in a loop, the method call doesn't return anything, resulting in the screen also not being refreshed till a key is pressed.

  while ((nread = read(STDIN_FILENO, &c, 1)) != 1){
    if (nread == -1 && errno != EAGAIN){
      die("read");
    }
  }

I scrolled through the rest of the steps, and I didn't see this issue being addressed anywhere. This can be a bigger issue than flickering, which is addressed in the tutorial. I am new to using github, and to the open-source world, so apologies in advance if I am wrong here. Just trying to learn :)

Text reordering suggestion on step 30

In step 30 (getWindowSize fallback), we have the following:

Because we’re always returning -1 (meaning an error occurred) from getWindowSize() at this point, we make a call to editorReadKey() so we can observe the results of our escape sequences before the program calls die() and clears the screen. When you run the program, you should see the cursor is positioned at the bottom-right corner of the screen, and then when you press a key you’ll see the error message printed by die() after it clears the screen.

Also notice we are sticking a 1 || at the front of our if condition temporarily, so that we can test this fallback branch we are developing.

The opposite (paragraph) ordering reads more logically, in my opinion. We're always returning -1 at this point because we've stuck the 1 || at the front of our conditional. Any thoughts?

If you give the thumbs up, I'm happy to make a pull request. Thanks for putting all of this together! 🐢

Made a small mistake but don't really understand why it's mistake

Hi ! Not sure if this is the right place to post this but I don't understand why this code is correct and the one under is not (--> Ctrl + 'q' no longer works).
My rationale is the read() function reads one byte, puts it into the c variable, then if no error occurs read() is evaluated again (so the evaluation takes place before the assignment ?) . Since we only typed one character, it is the end of the stdin file, read() evaluates to 1, the while loop stops and the function returns c.
But with such a reasonning the second piece of code should not behave diferently. What have I wrong ?

I have tried to read the read() linux man page but it is too low-level for me to understand much of it.

Thanks in advance


char editorReadKey() {
  int nread;
  char c;
  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
    if (nread == -1 && errno != EAGAIN) die("read");
  }
  return c;
}

and


char editorReadKey() {
        int nread;
        char c;
        while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
                if (nread == -1 && errno != EAGAIN) die("read");
                return c;
  }
  
}

in editorReadKey, how to rewrite `while` statement ?

in editorReadKey function, there is a while statement

 while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
    if (nread == -1 && errno != EAGAIN) die("read");
  }

and when I transform it into

  while(true) {
    nread = read(STDIN_FILENO, &c, 1);
    if(nread != 1) {
      if(nread == -1 && errno != EAGAIN) {
	die("read");
      } else {
	break;
      }
    } else {
      break;
    }
  }

or

  nread = read(STDIN_FILENO, &c, 1);
  if(nread == -1 && errno != EAGAIN) {
    die("read");
  }

but I found that the cursor move too slow when press the arrow key one by one, here is the example using my while statement, comparing the origin while statement

2021-12-06.13-51-47.mp4

what is the wrong with my code ??

Searching forward and backward adds characters to the prompt buffer

At the end of chapter 6, searching forward and backward using arrow keys does not work. Instead, the arrows are appended to the prompt buffer.

One way to fix it in editorPrompt:

-    } else if (!iscntrl(c)) {
+    } else if (!iscntrl(c) && c < ARROW_LEFT) {
      if (buflen == bufsize - 1) {
        bufsize *= 2;
        buf = realloc(buf, bufsize);
      }
      buf[buflen++] = c;
      buf[buflen] = '\0';
    }
    if (callback) callback(buf, c);

Since we defined arrows to be values 1000..1003, presumably these values return false for iscntrl, and we add them to the prompt buf. The callback still runs, but since the text has changed, it doesn't move anywhere.

Question about step 101

Quick question... Why do we have to check if at is less than 0?
Under which condition does at become less than 0 and if at if less than 0, why do we set it to row.size and not 0?

extra tilde on zsh terminal on MacOS

the editorDrawRows function draws an extra tilde in front of the last one in the following manner "~~". changing "if (y < E.screenrows - 1)" to "if (y < E.screenrows)" fixes the issue

At the end of chapter 2, ctrl-J and ctrl-K are not shown

Hi,
I'm following the tutorial on osx 10.12.3

in the iterm2 terminal.
at the end of chapter-2 everything seems to work as desired, except the ctrl-J and ctrl-K characters aren't printed.

I have attached my version of kilo.c just to be sure i haven't made an obvious mistake.

I would also be interested on your approach to fix this issue. As of now I am clueless, maybe digging into termios.h could be one option

Code screenshot as github doesn't allow attaching *.c files. I will put it on a pastebin style website if required.
screen shot 2017-04-07 at 21 49 22

Thanks for the awesome tutorial btw. It's been nice to learn about canonical and noncanonical mode. never thought of it.

Can't write welcome text to screen (step 41 - 42)

I've been slowly following this tutorial for a few days. hadn't had at major problems until now: I can't get the welcome message (editor name and version) to show up. My editorDrawRows() function (named voided_draw_rows() in my code) and editorRefreshScreen() (voided_refresh_screen()) are pretty much exactly the same as in the tutorial, so I don't know what's causing this. My code is in my voided repo.

Raw mode bugfix

Hi!

Thanks for the tutorial! It's been handy refresher for my c skills.

Raw mode still blocks for me (Windows 10 / Bash on Ubuntu on Windows) because STDIN is set to block.

I was going to submit a pull request but then the steps.diff isn't really human editable. It's a 1 liner anyway!

~~~ step: vmin-vtime c2
diff --git a/kilo.c b/kilo.c
--- a/kilo.c
+++ b/kilo.c
@@ -19,6 +19,11 @@ void enableRawMode() {
   raw.c_oflag &= ~(OPOST);
   raw.c_cflag |= (CS8);
   raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;

   tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+
+  // Ensure STDIN is in non-blocking mode
+  fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
 }

error sorting after compilation

WHILE MAKING THE EDITOR KILO : ON COMPILING STEP-21 I GET THE ERROR OF THE TYPE "UNDEFINED REFERENCE TO 'editorReadKey' " AND ALSO OF THE TYPE "relocation truncated to fit". please tell me how to sort this error as i cannot move forward without getting this error sorted.

Possible Typo

Hello! Thank you for putting together this fantastic tutorial - I am really enjoying working my way through it.

I think I may have found a typo in step 132. Currently the line is if (cur_rx > rx) return cx; but I think it should be if (cur_rx > cx) return cx; instead. Does that sound right?

Thanks again!

Expand on Step 6 and Explain why the Order of Declaration is Important

I'm new to C and whenever I follow these tutorials I try different versions of the code to see if order matters. Here are two examples of code I tried which fail, but I'm not sure why they fail.

struct termios orig;

void DisableRawMode() {
	tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig);
}

void EnableRawMode() {
	struct termios raw = orig; /* Placing the struct declaration here breaks it */

	tcgetattr(STDIN_FILENO, &orig);
	atexit(DisableRawMode);

	raw.c_lflag &= ~(ECHO);

	tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}
struct termios orig;

void DisableRawMode() {
	tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig);
}

void EnableRawMode() {
	struct termios raw; /* Making a fresh copy works but causes odd behaviour in the shell after the program ends */

	tcgetattr(STDIN_FILENO, &orig);
	atexit(DisableRawMode);

	raw.c_lflag &= ~(ECHO);

	tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}

I'm curious about why this matters. My assumption is that in the second example, struct termios raw = orig; is actually making a pointer to the original and not a copy?

Step 62 and 63 don't compile

Nice guide so far.

A suggestion: these intermediate steps indicate in the code box that the program will fail to compile at these steps but the text doesn't make a clear indication that this is what we expect and will fix in the subsequent steps.

Could be helpful to mention that we're going to break the program for a few steps.

Step 20 - clarity needed, else statement removed.

For step 20, the else statement to print a carriage return and a newline is removed. This is before the refactor and may confuse some. Up until this point lines were edited and added to but not removed.

Suggestion: put "Move to the end of the line with End" to just after "Snap cursor to end of line"

In step 77, "Snap cursor to end of line", we add an invariant to the horizontal position of the cursor. At this point, one can still break it by pressing End. It's easy to discover this, since just 2 steps later we implement "Moving right at the end of a line".

I would consider "Move to the end of the line with End", currently step 91, an integral part of "Snap cursor to end of line", and I would like to suggest making the former immediately follow the latter at step 78.

Pressing Ctrl+Q show 31 instead of 17 in the console

Hi, thanks for the great tutorial!

I'm having this issue, maybe it is related to the fact that i'm using abnt-br keyboard layout? idk but it was supposed to show 17, i'll print the code since github doesn't allow to put c files here!
issueCtrlQ

Tabs versus spaces mess up vertical scrolling

I am using this project as a way to get more familiar with Vim. I found that when I implemented vertical scrolling, artifacts from neighboring lines were getting copied into the white spaces of other lines. I'm still looking into how exactly this happened. But I was about to fix the issue by changing my .vimrc file to redefine the tab key to insert spaces instead of inserting an actual tab symbol that appeared as multiple spaces.

SOLVED - Not Working on macOs in iTerm2

I'm on step 13, and the program doesn't work when I run it in iTerm 2. It compiles, and ./kilo runs and exits immediately, with no feedback. I tested it out in Terminal.app and it worked, so I figure it's some minor difference in the way iTerm handles the flags provided in enableRawMode?

I'm using a mid-2015 MacbookPro with macOs 10.12.4, and iTerm2 3.0.15 as my terminal.

Cheers

EDIT: Turns out it's tmux that's interfering. I'm used to working inside tmux sessions, and when I run it outside of tmux, everything is peachy. Feel free to delete this issue, or leave it up in case others run into the same issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.