Archived
1
Fork 0
This repository has been archived on 2024-10-07. You can view files and clone it, but cannot push or open issues or pull requests.
kilo/src/kilo.c
Hadeed Ahmad c10f4a243b Add support to handle terminal resizing
Got stuck on a bug for a while, fix was to check for errors when using
system calls. Lesson learned.
2023-09-26 06:42:36 +05:00

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();
}