Chapter4Halfway

This commit is contained in:
Benjamyn Love 2024-02-08 10:59:32 +11:00
parent 5e21cccadc
commit 3872447fa2

89
kilo.c
View File

@ -1,11 +1,16 @@
/*** includes ***/ /*** includes ***/
#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#define _GNU_SOURCE
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <termios.h> #include <termios.h>
@ -30,11 +35,20 @@ enum editorKey
/*** data ***/ /*** data ***/
typedef struct erow {
int size;
char *chars;
} erow;
struct editorConfig struct editorConfig
{ {
int cx, cy; int cx, cy;
int rowoff; // Row offset
int coloff; // Col offset
int screenrows; int screenrows;
int screencols; int screencols;
int numrows;
erow *row;
struct termios orig_termios; struct termios orig_termios;
}; };
@ -191,6 +205,37 @@ int getWindowSize(int *rows, int *cols)
} }
} }
/*** 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 ***/ /*** append buffer ***/
struct abuf struct abuf
@ -222,12 +267,29 @@ void abFree(struct abuf *ab)
/*** output ***/ /*** 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;
}
if (E.cx < E.coloff) {
E.coloff = E.cx;
}
if (E.cx >= E.coloff + E.screencols) {
E.coloff = E.cx - E.screencols + 1;
}
}
void editorDrawRows(struct abuf *ab) void editorDrawRows(struct abuf *ab)
{ {
int y; int y;
for (y = 0; y < E.screenrows; y++) for (y = 0; y < E.screenrows; y++)
{ {
if (y == E.screenrows / 3) int filerow = y + E.rowoff;
if (filerow >= E.numrows) {
if (E.numrows == 0 && y == E.screenrows / 3)
{ {
char welcome[80]; char welcome[80];
int welcomelen = snprintf(welcome, sizeof(welcome), int welcomelen = snprintf(welcome, sizeof(welcome),
@ -249,6 +311,12 @@ void editorDrawRows(struct abuf *ab)
abAppend(ab, "~", 1); abAppend(ab, "~", 1);
} }
} else {
int len = E.row[filerow].size - E.coloff;
if (len < 0) len = 0;
if (len > E.screencols) len = E.screencols;
abAppend(ab, &E.row[filerow].chars[E.coloff], len);
}
abAppend(ab, "\x1b[K", 3); abAppend(ab, "\x1b[K", 3);
if (y < E.screenrows - 1) if (y < E.screenrows - 1)
{ {
@ -259,6 +327,7 @@ void editorDrawRows(struct abuf *ab)
void editorRefreshScreen() void editorRefreshScreen()
{ {
editorScroll();
struct abuf ab = ABUF_INIT; struct abuf ab = ABUF_INIT;
abAppend(&ab, "\x1b[?25l", 6); abAppend(&ab, "\x1b[?25l", 6);
@ -267,7 +336,7 @@ void editorRefreshScreen()
editorDrawRows(&ab); editorDrawRows(&ab);
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "\x1b[%d;%dH", E.cy + 1, E.cx + 1); snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (E.cy - E.rowoff) + 1, (E.cx - E.coloff) + 1);
abAppend(&ab, buf, strlen(buf)); abAppend(&ab, buf, strlen(buf));
abAppend(&ab, "\x1b[?25h", 6); abAppend(&ab, "\x1b[?25h", 6);
@ -279,6 +348,7 @@ void editorRefreshScreen()
void editorMoveCursor(int key) void editorMoveCursor(int key)
{ {
erow *row = (E.cy >=E.numrows) ? NULL : &E.row[E.cy];
switch (key) switch (key)
{ {
case ARROW_LEFT: case ARROW_LEFT:
@ -288,8 +358,7 @@ void editorMoveCursor(int key)
} }
break; break;
case ARROW_RIGHT: case ARROW_RIGHT:
if (E.cx != E.screencols - 1) if (row && E.cx < row->size) {
{
E.cx++; E.cx++;
} }
break; break;
@ -301,7 +370,7 @@ void editorMoveCursor(int key)
} }
break; break;
case ARROW_DOWN: case ARROW_DOWN:
if (E.cy != E.screenrows - 1) if (E.cy < E.numrows)
{ {
E.cy++; E.cy++;
} }
@ -353,14 +422,22 @@ void initEditor()
{ {
E.cx = 0; E.cx = 0;
E.cy = 0; E.cy = 0;
E.rowoff = 0;
E.coloff = 0;
E.numrows = 0;
E.row = NULL;
if (getWindowSize(&E.screenrows, &E.screencols) == -1) if (getWindowSize(&E.screenrows, &E.screencols) == -1)
die("getWindowSize"); die("getWindowSize");
} }
int main() int main(int argc, char *argv[])
{ {
enableRawMode(); enableRawMode();
initEditor(); initEditor();
if (argc >= 2) {
editorOpen(argv[1]);
}
while (1) while (1)
{ {