diff --git a/kilo.c b/kilo.c index 7b569a9..4012d9f 100644 --- a/kilo.c +++ b/kilo.c @@ -1,10 +1,16 @@ /*** includes ***/ + +#define _DEFAULT_SOURCE +#define _BSD_SOURCE +#define _GNU_SOURCE + #include #include #include #include #include #include +#include #include #include @@ -28,10 +34,18 @@ enum editorKey { /*** data ***/ +typedef struct erow { + int size; + char *chars; +} erow; + struct editorConfig { int cx, cy; + int rowoff; int screenrows; int screencols; + int numrows; + erow *row; struct termios orig_termios; }; @@ -216,6 +230,46 @@ int getWindowSize(int *rows, int *cols) return 0; } +/*** row operations ***/ +void editorAppendRow(char *s, size_t len) +{ + E.row = realloc(E.row, sizeof(erow) * (E.numrows + 1)); + + int at = E.numrows; + E.row[at].size = len; + E.row[at].chars = malloc(len + 1); + memcpy(E.row[at].chars, s, len); + E.row[at].chars[len] = '\0'; + E.numrows++; +} + +/*** file i/o ***/ +void editorOpen(char *filename) +{ + FILE *fp = fopen(filename, "r"); + if ( ! fp) + { + die("fopen"); + } + + char *line = NULL; + size_t linecap = 0; + ssize_t linelen; + while ((linelen = getline(&line, &linecap, fp)) != -1) + { + while (linelen > 0 && ( + line[linelen - 1] == '\n' || + line[linelen - 1] == '\r')) + { + linelen--; + } + editorAppendRow(line, linelen); + } + + free(line); + fclose(fp); +} + /*** append buffer ***/ struct abuf { @@ -246,39 +300,66 @@ void abFree(struct abuf *ab) /*** output ***/ +void editorScroll() +{ + if (E.cy < E.rowoff) + { + E.rowoff = E.cy; + } + + if (E.cy >= E.rowoff + E.screenrows) + { + E.rowoff = E.cy - E.screenrows + 1; + } +} + void editorDrawRows(struct abuf *ab) { int y; for (y = 0; y < E.screenrows; y++) { - if (y == E.screenrows / 3) + int filerow = y + E.rowoff; + if (filerow >= E.numrows) { - char welcome[80]; - int welcomelen = snprintf(welcome, sizeof(welcome), - "Kilo editor -- version %s", KILO_VERSION); - - if (welcomelen > E.screencols) + if (E.numrows == 0 && y == E.screenrows / 3) { - welcomelen = E.screencols; - } + char welcome[80]; + int welcomelen = snprintf(welcome, sizeof(welcome), + "Kilo editor -- version %s", KILO_VERSION); - int padding = (E.screencols - welcomelen) / 2; - if (padding) + if (welcomelen > E.screencols) + { + welcomelen = E.screencols; + } + + int padding = (E.screencols - welcomelen) / 2; + if (padding) + { + abAppend(ab, "~", 1); + padding--; + } + + while (padding--) + { + abAppend(ab, " ", 1); + } + + abAppend(ab, welcome, welcomelen); + } + else { abAppend(ab, "~", 1); - padding--; } - - while (padding--) - { - abAppend(ab, " ", 1); - } - - abAppend(ab, welcome, welcomelen); } else { - abAppend(ab, "~", 1); + int len = E.row[filerow].size; + if (len > E.screencols) + { + len = E.screencols; + } + + abAppend(ab, E.row[filerow].chars, len); } abAppend(ab, "\x1b[K", 3); @@ -291,6 +372,8 @@ void editorDrawRows(struct abuf *ab) void editorRefreshScreen() { + editorScroll(); + struct abuf ab = ABUF_INIT; abAppend(&ab, "\x1b[?25l", 6); @@ -336,7 +419,7 @@ void editorMoveCursor(int key) break; case ARROW_DOWN: - if (E.cy != E.screenrows - 1) + if (E.cy < E.numrows) { E.cy++; } @@ -389,6 +472,9 @@ void initEditor() { E.cx = 0; E.cy = 0; + E.rowoff = 0; + E.numrows = 0; + E.row = NULL; if (getWindowSize(&E.screenrows, &E.screencols) == -1) { @@ -396,10 +482,14 @@ void initEditor() } } -int main() +int main(int argc, char *argv[]) { enableRawMode(); initEditor(); + if (argc >= 2) + { + editorOpen(argv[1]); + } while (1) {