Got stuck on a bug for a while, fix was to check for errors when using system calls. Lesson learned.
128 lines
2.9 KiB
C
128 lines
2.9 KiB
C
#define _POSIX_C_SOURCE 199309L
|
|
|
|
#include <ctype.h>
|
|
#include <signal.h>
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "buffer.h"
|
|
#include "input.h"
|
|
#include "kilo.h"
|
|
#include "terminal.h"
|
|
#include "ui.h"
|
|
#include "utils.h"
|
|
|
|
void editor_init(char *filename);
|
|
void editor_resize();
|
|
|
|
struct editor_state E;
|
|
|
|
int main(int argc, char **argv) {
|
|
editor_init(argc >= 2 ? argv[1] : NULL);
|
|
|
|
while (true) {
|
|
ui_draw_screen();
|
|
input_process_key(terminal_read_key());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void editor_init(char *filename) {
|
|
if (!isatty(STDIN_FILENO)) {
|
|
printf("kilo only supports a terminal at standard in. Exiting.");
|
|
exit(1);
|
|
}
|
|
|
|
if (terminal_enable_raw() == -1) die("term_enable_raw");
|
|
|
|
if (terminal_get_win_size(&E.screenrows, &E.screencols) == -1)
|
|
die("term_get_win_size");
|
|
E.quit_times = 3;
|
|
|
|
E.current_buf = buffer_create();
|
|
if (filename)
|
|
buffer_read_file(E.current_buf, filename);
|
|
|
|
editor_set_message("Welcome to kilo! | CTRL-Q: Quit | CTRL-S: SAVE");
|
|
terminal_clear();
|
|
|
|
struct sigaction sa;
|
|
sa.sa_handler = editor_resize;
|
|
sigaction(SIGWINCH, &sa, NULL);
|
|
}
|
|
|
|
void editor_set_message(const char *fmt, ...) {
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
vsnprintf(E.message, sizeof(E.message), fmt, ap);
|
|
va_end(ap);
|
|
|
|
E.message_time = time(NULL);
|
|
}
|
|
|
|
// TODO: This could use some work
|
|
char *editor_prompt(const char *prompt) {
|
|
size_t buf_cap = 64;
|
|
size_t buf_size = 0;
|
|
char *buf = malloc(buf_cap);
|
|
|
|
char *prompt_prefix = strstr(prompt, "%s");
|
|
int prefix_len = (prompt_prefix ? prompt_prefix - prompt : 0);
|
|
|
|
buf[buf_size] = '\0';
|
|
|
|
while (true) {
|
|
editor_set_message(prompt, buf);
|
|
ui_draw_screen();
|
|
|
|
if (prompt_prefix)
|
|
terminal_set_cursor_pos(E.screenrows + 2, prefix_len + buf_size + 1);
|
|
|
|
KEY key = terminal_read_key();
|
|
switch (key) {
|
|
case BACKSPACE:
|
|
if (buf_size > 0)
|
|
buf[--buf_size] = '\0';
|
|
break;
|
|
case ENTER:
|
|
if (buf_size > 0) goto success;
|
|
else goto failure;
|
|
break;
|
|
case ESCAPE:
|
|
goto failure;
|
|
break;
|
|
default:
|
|
if (isprint(key)) {
|
|
if (buf_size + 1 >= buf_cap)
|
|
buf = realloc(buf, buf_cap *= 2);
|
|
|
|
buf[buf_size] = key;
|
|
buf_size++;
|
|
buf[buf_size] = '\0';
|
|
}
|
|
}
|
|
}
|
|
|
|
failure:
|
|
free(buf);
|
|
buf = NULL;
|
|
success:
|
|
if (buf)
|
|
buf = realloc(buf, buf_size + 1);
|
|
|
|
editor_set_message("");
|
|
return buf;
|
|
}
|
|
|
|
void editor_resize() {
|
|
if (terminal_get_win_size(&E.screenrows, &E.screencols) == -1)
|
|
die("term_get_win_size");
|
|
|
|
ui_draw_screen();
|
|
}
|