j and k bindings, caught up to the end of the first video
This commit is contained in:
59
main.c
59
main.c
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define EDITOR_CAPACITY 1024
|
#define EDITOR_CAPACITY (10*1024)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t begin;
|
size_t begin;
|
||||||
@@ -24,6 +24,8 @@ typedef struct {
|
|||||||
} Editor;
|
} Editor;
|
||||||
|
|
||||||
void editor_compute_lines(Editor *e) {
|
void editor_compute_lines(Editor *e) {
|
||||||
|
// populate `e` with entries for `e->lines` and `e->data_count`
|
||||||
|
e->lines_count = 0;
|
||||||
size_t begin = 0;
|
size_t begin = 0;
|
||||||
for (size_t i = 0; i < e->data_count; ++i) {
|
for (size_t i = 0; i < e->data_count; ++i) {
|
||||||
if (e->data[i] == '\n') {
|
if (e->data[i] == '\n') {
|
||||||
@@ -38,6 +40,16 @@ void editor_compute_lines(Editor *e) {
|
|||||||
e->lines_count += 1;
|
e->lines_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void editor_insert_char(Editor *e, char x) {
|
||||||
|
if (e->data_count < EDITOR_CAPACITY) {
|
||||||
|
memmove(&e->data[e->cursor + 1], &e->data[e->cursor], e->data_count - e->cursor);
|
||||||
|
e->data[e->cursor] = x;
|
||||||
|
e->cursor += 1;
|
||||||
|
e->data_count += 1;
|
||||||
|
editor_compute_lines(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t editor_current_line(const Editor *e) {
|
size_t editor_current_line(const Editor *e) {
|
||||||
assert(e->cursor <= e->data_count);
|
assert(e->cursor <= e->data_count);
|
||||||
Line line;
|
Line line;
|
||||||
@@ -64,7 +76,7 @@ void editor_rerender(const Editor *e) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int editor_start_interactive(Editor *e) {
|
int editor_start_interactive(Editor *e, const char * filepath) {
|
||||||
if (!isatty(0)) {
|
if (!isatty(0)) {
|
||||||
fprintf(stderr, "Please run in the terminal!\n");
|
fprintf(stderr, "Please run in the terminal!\n");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -98,10 +110,23 @@ int editor_start_interactive(Editor *e) {
|
|||||||
while (!quit && !feof(stdin)) {
|
while (!quit && !feof(stdin)) {
|
||||||
editor_rerender(e);
|
editor_rerender(e);
|
||||||
if (insert) {
|
if (insert) {
|
||||||
|
int i = fgetc(stdin);
|
||||||
|
switch (i) {
|
||||||
|
case 27: {
|
||||||
|
insert = false;
|
||||||
|
FILE *f = fopen(filepath, "wb");
|
||||||
|
fwrite(e->data, 1, e->data_count, f);
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
editor_insert_char(e, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int x = fgetc(stdin);
|
int x = fgetc(stdin);
|
||||||
switch (x) {
|
switch (x) {
|
||||||
|
case 'i': {
|
||||||
|
insert = true;
|
||||||
|
} break;
|
||||||
case 'q': {
|
case 'q': {
|
||||||
quit = true;
|
quit = true;
|
||||||
} break;
|
} break;
|
||||||
@@ -115,6 +140,26 @@ int editor_start_interactive(Editor *e) {
|
|||||||
e->cursor += 1;
|
e->cursor += 1;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case 'j': {
|
||||||
|
size_t current_line = editor_current_line(e);
|
||||||
|
if (current_line < e->lines_count - 1) {
|
||||||
|
size_t current_col = e->cursor - e->lines[current_line].begin;
|
||||||
|
e->cursor = e->lines[current_line + 1].begin + current_col;
|
||||||
|
if (e->cursor > e->lines[current_line + 1].end) {
|
||||||
|
e->cursor = e->lines[current_line + 1].end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case 'k': {
|
||||||
|
size_t current_line = editor_current_line(e);
|
||||||
|
if (current_line > 0) {
|
||||||
|
size_t current_col = e->cursor - e->lines[current_line].begin;
|
||||||
|
e->cursor = e->lines[current_line - 1].begin + current_col;
|
||||||
|
if (e->cursor > e->lines[current_line - 1].end) {
|
||||||
|
e->cursor = e->lines[current_line - 1].end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,14 +174,14 @@ int editor_start_interactive(Editor *e) {
|
|||||||
|
|
||||||
static Editor editor;
|
static Editor editor;
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int num_args, char **args) {
|
||||||
if (argc < 2) {
|
if (num_args < 2) {
|
||||||
fprintf(stderr, "Usage: zed <input.txt>\n");
|
fprintf(stderr, "Usage: zed <input.txt>\n");
|
||||||
fprintf(stderr, "ERROR: no input file was provided\n");
|
fprintf(stderr, "ERROR: no input file was provided\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *file_path = argv[1];
|
const char *file_path = args[1];
|
||||||
FILE *f = fopen(file_path, "rb");
|
FILE *f = fopen(file_path, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
fprintf(
|
fprintf(
|
||||||
@@ -155,6 +200,6 @@ int main(int argc, char **argv) {
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
editor_compute_lines(&editor);
|
editor_compute_lines(&editor);
|
||||||
|
|
||||||
return editor_start_interactive(&editor);
|
return editor_start_interactive(&editor, file_path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user