Refactor a lot
Doesn't compile yet. Dreading the time when it does and there's an error in the hundreds of lines I changed. For future: commit small changes that can be compiled and tested atomically.
This commit is contained in:
parent
e3fb954aeb
commit
fc5e50e4db
8 changed files with 282 additions and 229 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,5 +3,5 @@ kilo
|
|||
|
||||
.cache
|
||||
.clangd
|
||||
.nvim.lua
|
||||
compile_commands.json
|
||||
test_file
|
||||
|
|
|
@ -5,34 +5,27 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
struct erow {
|
||||
char *chars;
|
||||
int n_chars;
|
||||
|
||||
char *rchars;
|
||||
int n_rchars;
|
||||
};
|
||||
#include "erow.h"
|
||||
|
||||
struct buffer {
|
||||
char *filename;
|
||||
struct erow *rows;
|
||||
|
||||
int cx, cy, rx;
|
||||
int row_off, col_off;
|
||||
|
||||
struct erow **rows;
|
||||
int n_rows;
|
||||
|
||||
bool modified;
|
||||
};
|
||||
|
||||
struct buffer *buffer_create(void);
|
||||
void buffer_read_file(struct buffer *buffer, const char *filename);
|
||||
void buffer_insert_row(struct buffer *buffer, const char *chars, int n_chars, int at);
|
||||
ERRCODE buffer_read_file(struct buffer *buffer, const char *filename);
|
||||
ERRCODE buffer_write_file(struct buffer *buffer, size_t *bytes_written);
|
||||
void buffer_insert_row(struct buffer *buffer, struct erow *erow, int at);
|
||||
void buffer_delete_row(struct buffer *buffer, int at);
|
||||
ERRCODE buffer_write_file(struct buffer *buffer, int *bytes_written);
|
||||
struct erow *buffer_get_crow(struct buffer *buffer);
|
||||
void buffer_free(struct buffer *buffer);
|
||||
|
||||
void erow_update_rendering(struct erow *erow);
|
||||
void erow_append_string(struct erow *erow, const char *s, size_t s_len);
|
||||
void erow_insert_char(struct erow *erow, int at, char c);
|
||||
void erow_delete_char(struct erow *erow, int at);
|
||||
int erow_cx_to_rx(struct erow *erow, int cx);
|
||||
int erow_rx_to_cx(struct erow *erow, int rx);
|
||||
void erow_free(struct erow *erow);
|
||||
|
||||
#endif // BUFFER_H
|
||||
|
|
23
include/erow.h
Normal file
23
include/erow.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef EROW_H
|
||||
#define EROW_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct erow {
|
||||
char *chars;
|
||||
size_t n_chars;
|
||||
|
||||
char *rchars;
|
||||
size_t n_rchars;
|
||||
|
||||
struct buffer *buffer;
|
||||
};
|
||||
|
||||
struct erow *erow_create(const char* chars, size_t n_chars, struct buffer *buffer);
|
||||
void erow_insert_chars(struct erow *erow, const char *chars, size_t n_chars, int at);
|
||||
void erow_delete_char(struct erow *erow, int at);
|
||||
int erow_cx_to_rx(struct erow *erow, int cx);
|
||||
int erow_rx_to_cx(struct erow *erow, int rx);
|
||||
void erow_free(struct erow *erow);
|
||||
|
||||
#endif // EROW_H
|
|
@ -7,8 +7,6 @@
|
|||
#include <time.h>
|
||||
|
||||
struct editor_state {
|
||||
int cx, cy, rx;
|
||||
int row_off, col_off;
|
||||
int screenrows, screencols;
|
||||
int quit_times;
|
||||
|
||||
|
|
271
src/buffer.c
271
src/buffer.c
|
@ -1,12 +1,8 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "kilo.h"
|
||||
#include "erow.h"
|
||||
#include "utils.h"
|
||||
|
||||
static void buffer_free_rows(struct buffer *buffer);
|
||||
|
@ -16,75 +12,89 @@ struct buffer *buffer_create(void) {
|
|||
struct buffer *buffer = malloc(sizeof(struct buffer));
|
||||
|
||||
buffer->filename = NULL;
|
||||
|
||||
buffer->cx = buffer->cy = buffer->rx = 0;
|
||||
buffer->row_off = buffer->col_off = 0;
|
||||
|
||||
buffer->rows = NULL;
|
||||
buffer->n_rows = 0;
|
||||
|
||||
buffer->modified = false;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void buffer_read_file(struct buffer *buffer, const char *filename) { // TODO: Add error handling
|
||||
if (buffer->filename)
|
||||
free(buffer->filename);
|
||||
|
||||
if (buffer->rows)
|
||||
buffer_free_rows(buffer);
|
||||
ERRCODE buffer_read_file(struct buffer *buffer, const char *filename) {
|
||||
ERRCODE errcode = 0;
|
||||
|
||||
if (buffer->filename) free(buffer->filename);
|
||||
size_t filename_len = strlen(filename);
|
||||
buffer->filename = malloc(filename_len);
|
||||
memcpy(buffer->filename, filename, filename_len);
|
||||
|
||||
if (buffer->rows)
|
||||
buffer_free_rows(buffer);
|
||||
|
||||
size_t buf_cap = 64;
|
||||
size_t buf_size = 0;
|
||||
char *buf = malloc(buf_cap);
|
||||
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file) die("fopen");
|
||||
if (file == NULL)
|
||||
RETURN(-1);
|
||||
|
||||
size_t line_buffer_size = 64;
|
||||
char *line_buffer = malloc(line_buffer_size);
|
||||
|
||||
bool file_remaining = true;
|
||||
while (file_remaining) {
|
||||
while (true) {
|
||||
char c;
|
||||
int i;
|
||||
|
||||
for (i = 0; (c = getc(file)) != '\n' && c != EOF; i++) {
|
||||
if (i >= (int) line_buffer_size)
|
||||
line_buffer = realloc(line_buffer, line_buffer_size *= 2);
|
||||
while ((c = getc(file)) != '\n' && c != EOF) {
|
||||
if (buf_size >= buf_cap)
|
||||
buf = realloc(buf, buf_cap *= 2);
|
||||
|
||||
line_buffer[i] = c;
|
||||
buf[buf_size++] = c;
|
||||
}
|
||||
|
||||
buffer_insert_row(buffer, line_buffer, i, buffer->n_rows);
|
||||
file_remaining = (c != EOF);
|
||||
struct erow* erow = erow_create(buf, buf_size, buffer);
|
||||
buffer_insert_row(buffer, erow, buffer->n_rows);
|
||||
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
|
||||
free(line_buffer);
|
||||
END:
|
||||
if (file != NULL)
|
||||
fclose(file);
|
||||
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
|
||||
buffer->modified = false;
|
||||
|
||||
return errcode;
|
||||
}
|
||||
|
||||
ERRCODE buffer_write_file(struct buffer *buffer, int *bytes_written) {
|
||||
ERRCODE buffer_write_file(struct buffer *buffer, size_t *bytes_written) {
|
||||
ERRCODE errcode = 0;
|
||||
|
||||
int fd = -1;
|
||||
FILE *file = NULL;
|
||||
char *write_buffer = NULL;
|
||||
|
||||
if (buffer->filename == NULL)
|
||||
RETURN(-1);
|
||||
|
||||
size_t len;
|
||||
write_buffer = buffer_get_string(buffer, &len);
|
||||
size_t n_chars;
|
||||
write_buffer = buffer_get_string(buffer, &n_chars);
|
||||
|
||||
fd = open(buffer->filename, O_RDWR | O_TRUNC | O_CREAT, 0644);
|
||||
if (fd == -1)
|
||||
file = fopen(buffer->filename, "w");
|
||||
if (file == NULL)
|
||||
RETURN(-2);
|
||||
|
||||
*bytes_written = write(fd, write_buffer, len);
|
||||
if (*bytes_written != (ssize_t) len)
|
||||
*bytes_written = fwrite(write_buffer, 1, n_chars, file);
|
||||
if (*bytes_written != n_chars)
|
||||
RETURN(-3);
|
||||
|
||||
END:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (file != NULL)
|
||||
fclose(file);
|
||||
|
||||
if (write_buffer)
|
||||
free(write_buffer);
|
||||
|
@ -95,21 +105,41 @@ END:
|
|||
return errcode;
|
||||
}
|
||||
|
||||
void buffer_insert_row(struct buffer *buffer, const char *chars, int n_chars, int at) { // TODO: Make this take an erow
|
||||
buffer->rows = realloc(buffer->rows, sizeof(struct erow) * (buffer->n_rows + 1));
|
||||
memmove(buffer->rows + at + 1, buffer->rows + at, sizeof(struct erow) * (buffer->n_rows - at));
|
||||
struct erow *erow = buffer->rows + at;
|
||||
ERRCODE buffer_get_row_chars(struct buffer *buffer, char **chars, size_t *n_chars, int at) {
|
||||
if (buffer == NULL)
|
||||
return -1;
|
||||
|
||||
erow->chars = malloc(n_chars);
|
||||
memcpy(erow->chars, chars, n_chars);
|
||||
erow->n_chars = n_chars;
|
||||
if (!(0 <= at && at <= buffer->n_rows))
|
||||
return -2;
|
||||
|
||||
erow->rchars = NULL;
|
||||
erow->n_rchars = 0;
|
||||
if (chars) *chars = buffer->rows[at]->chars;
|
||||
if (n_chars) *n_chars = buffer->rows[at]->n_chars;
|
||||
|
||||
erow_update_rendering(erow);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERRCODE buffer_get_row_rchars(struct buffer *buffer, char **rchars, size_t *n_rchars, int at) {
|
||||
if (buffer == NULL)
|
||||
return -1;
|
||||
|
||||
if (!(0 <= at && at <= buffer->n_rows))
|
||||
return -2;
|
||||
|
||||
if (rchars) *rchars = buffer->rows[at]->rchars;
|
||||
if (n_rchars) *n_rchars = buffer->rows[at]->n_rchars;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void buffer_insert_row(struct buffer *buffer, struct erow *erow, int at) {
|
||||
if (!(0 <= at && at <= buffer->n_rows))
|
||||
return;
|
||||
|
||||
buffer->rows = realloc(buffer->rows, sizeof(struct erow *) * (buffer->n_rows + 1));
|
||||
memmove(buffer->rows + at + 1, buffer->rows + at, sizeof(struct erow *) * (buffer->n_rows - at));
|
||||
|
||||
buffer->rows[at] = erow;
|
||||
|
||||
buffer->modified = true;
|
||||
buffer->n_rows++;
|
||||
}
|
||||
|
||||
|
@ -117,150 +147,47 @@ void buffer_delete_row(struct buffer *buffer, int at) {
|
|||
if (!(0 <= at && at < buffer->n_rows))
|
||||
return;
|
||||
|
||||
erow_free(buffer->rows + at);
|
||||
memmove(buffer->rows + at, buffer->rows + at + 1, sizeof(struct erow) * (buffer->n_rows - at - 1));
|
||||
erow_free(buffer->rows[at]);
|
||||
memmove(buffer->rows + at, buffer->rows + at + 1, sizeof(struct erow *) * (buffer->n_rows - at - 1));
|
||||
buffer->n_rows--;
|
||||
|
||||
buffer->modified = true;
|
||||
}
|
||||
|
||||
struct erow *buffer_get_crow(struct buffer *buffer) {
|
||||
return (buffer->cy < buffer->n_rows ? buffer->rows[buffer->cy]: NULL);
|
||||
}
|
||||
|
||||
void buffer_free(struct buffer *buffer) {
|
||||
free(buffer->filename);
|
||||
|
||||
buffer_free_rows(buffer);
|
||||
}
|
||||
|
||||
static void buffer_free_rows(struct buffer *buffer) {
|
||||
for (int i = 0; i < buffer->n_rows; i++)
|
||||
erow_free(buffer->rows + i);
|
||||
erow_free(buffer->rows[i]);
|
||||
|
||||
free(buffer->rows);
|
||||
|
||||
buffer->rows = NULL;
|
||||
buffer->n_rows = 0;
|
||||
}
|
||||
|
||||
static char *buffer_get_string(struct buffer *buffer, size_t *len_p) {
|
||||
*len_p = 0;
|
||||
static char *buffer_get_string(struct buffer *buffer, size_t *n_chars) {
|
||||
*n_chars = 0;
|
||||
|
||||
for (int i = 0; i < buffer->n_rows; i++)
|
||||
*len_p += buffer->rows[i].n_chars + 1;
|
||||
*n_chars += buffer->rows[i]->n_chars + 1;
|
||||
|
||||
char *write_buffer = malloc(*len_p);
|
||||
char *p = write_buffer;
|
||||
for (int i = 0; i < buffer->n_rows; i++) {
|
||||
struct erow *row = buffer->rows+i;
|
||||
memcpy(p, row->chars, row->n_chars);
|
||||
p += row->n_chars;
|
||||
*p = '\n';
|
||||
p++;
|
||||
char *write_buffer = malloc(*n_chars);
|
||||
for (int i = 0, j = 0; i < buffer->n_rows; j++, i++) {
|
||||
struct erow *row = buffer->rows[i];
|
||||
|
||||
memcpy(write_buffer + j, row->chars, row->n_chars);
|
||||
j += row->n_chars;
|
||||
write_buffer[j++] = '\n';
|
||||
}
|
||||
|
||||
return write_buffer;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void erow_update_rendering(struct erow *erow) {
|
||||
size_t line_buffer_size = 64;
|
||||
char *line_buffer = malloc(line_buffer_size);
|
||||
size_t n_rchars = 0;
|
||||
|
||||
for (int i = 0; i < erow->n_chars; i++) {
|
||||
switch (erow->chars[i]) {
|
||||
case '\t': {
|
||||
int spaces = KILO_TAB_STOP - (n_rchars % KILO_TAB_STOP);
|
||||
while (spaces--) {
|
||||
if (n_rchars >= line_buffer_size)
|
||||
line_buffer = realloc(line_buffer, 2*line_buffer_size);
|
||||
|
||||
line_buffer[n_rchars++] = ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (n_rchars >= line_buffer_size)
|
||||
line_buffer = realloc(line_buffer, 2*line_buffer_size);
|
||||
|
||||
line_buffer[n_rchars++] = erow->chars[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (erow->rchars)
|
||||
free(erow->rchars);
|
||||
|
||||
erow->rchars = malloc(n_rchars);
|
||||
erow->n_rchars = n_rchars;
|
||||
memcpy(erow->rchars, line_buffer, n_rchars);
|
||||
|
||||
free(line_buffer);
|
||||
}
|
||||
|
||||
void erow_append_string(struct erow *erow, const char *s, size_t s_len) {
|
||||
erow->n_chars = erow->n_chars + s_len;
|
||||
erow->chars = realloc(erow->chars, erow->n_chars);
|
||||
|
||||
memcpy(erow->chars + erow->n_chars - s_len, s, s_len);
|
||||
erow_update_rendering(erow);
|
||||
|
||||
E.current_buf->modified = true; // TODO
|
||||
}
|
||||
|
||||
void erow_insert_char(struct erow *erow, int at, char c) {
|
||||
if (!(0 <= at && at <= erow->n_chars))
|
||||
return;
|
||||
|
||||
erow->chars = realloc(erow->chars, erow->n_chars + 1);
|
||||
memmove(erow->chars + at + 1, erow->chars + at, erow->n_chars - at);
|
||||
|
||||
erow->chars[at] = c;
|
||||
erow->n_chars++;
|
||||
|
||||
erow_update_rendering(erow);
|
||||
|
||||
E.current_buf->modified = true; // TODO
|
||||
}
|
||||
|
||||
void erow_delete_char(struct erow *erow, int at) {
|
||||
if (!(0 <= at && at < erow->n_chars))
|
||||
return;
|
||||
|
||||
memmove(erow->chars + at, erow->chars + at + 1, erow->n_chars - at);
|
||||
erow->n_chars--;
|
||||
erow->chars = realloc(erow->chars, erow->n_chars);
|
||||
E.cx--;
|
||||
erow_update_rendering(erow);
|
||||
|
||||
E.current_buf->modified = true; // TODO
|
||||
}
|
||||
|
||||
int erow_cx_to_rx(struct erow *erow, int cx) {
|
||||
int rx = 0;
|
||||
|
||||
if (erow == NULL)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < MIN(cx, erow->n_chars); i++) {
|
||||
if (erow->chars[i] == '\t')
|
||||
rx += KILO_TAB_STOP - (rx % KILO_TAB_STOP);
|
||||
else rx++;
|
||||
}
|
||||
|
||||
return rx;
|
||||
}
|
||||
|
||||
int erow_rx_to_cx(struct erow *erow, int rx) {
|
||||
int cx = 0, _rx = 0;
|
||||
|
||||
if (erow == NULL)
|
||||
return 0;
|
||||
|
||||
while (_rx < rx && cx < erow->n_chars) {
|
||||
if (erow->chars[cx] == '\t') {
|
||||
_rx += KILO_TAB_STOP - (_rx % KILO_TAB_STOP);
|
||||
} else _rx++;
|
||||
|
||||
cx++;
|
||||
}
|
||||
|
||||
return (_rx >= rx ? cx : erow->n_chars);
|
||||
}
|
||||
|
||||
void erow_free(struct erow *erow) {
|
||||
if (erow->chars) free(erow->chars);
|
||||
if (erow->rchars) free(erow->rchars);
|
||||
}
|
||||
|
|
111
src/erow.c
Normal file
111
src/erow.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "erow.h"
|
||||
#include "kilo.h"
|
||||
|
||||
static void erow_update_rchars(struct erow *erow);
|
||||
|
||||
struct erow *erow_create(const char* chars, size_t n_chars, struct buffer *buffer) {
|
||||
struct erow *erow = malloc(sizeof(struct erow));
|
||||
|
||||
erow->chars = malloc(n_chars);
|
||||
erow->n_chars = n_chars;
|
||||
|
||||
memcpy(erow->chars, chars, erow->n_chars);
|
||||
erow_update_rchars(erow);
|
||||
|
||||
erow->buffer = buffer;
|
||||
|
||||
return erow;
|
||||
}
|
||||
|
||||
void erow_insert_chars(struct erow *erow, const char *chars, size_t n_chars, int at) {
|
||||
erow->chars = realloc(erow->chars, erow->n_chars + n_chars);
|
||||
memmove(erow->chars + at + n_chars, erow->chars + at, n_chars - at);
|
||||
memcpy(erow->chars + at, chars, n_chars);
|
||||
|
||||
erow->n_chars += n_chars;
|
||||
|
||||
erow_update_rchars(erow);
|
||||
|
||||
if (erow->buffer)
|
||||
erow->buffer->modified = true;
|
||||
}
|
||||
|
||||
void erow_delete_char(struct erow *erow, int at) {
|
||||
memmove(erow->chars + at, erow->chars + at + 1, erow->n_chars - at);
|
||||
erow->chars = realloc(erow->chars, --erow->n_chars);
|
||||
|
||||
erow_update_rchars(erow);
|
||||
|
||||
if (erow->buffer)
|
||||
erow->buffer->modified = true;
|
||||
}
|
||||
|
||||
int erow_cx_to_rx(struct erow *erow, int cx) {
|
||||
int rx = 0;
|
||||
|
||||
for (char *c = erow->chars; c < erow->chars + cx; c++) {
|
||||
if (*c == '\t')
|
||||
rx += KILO_TAB_STOP - (rx % KILO_TAB_STOP);
|
||||
else
|
||||
rx++;
|
||||
}
|
||||
|
||||
return rx;
|
||||
}
|
||||
|
||||
int erow_rx_to_cx(struct erow *erow, int rx) {
|
||||
if ((size_t) rx >= erow->n_rchars)
|
||||
return erow->n_chars;
|
||||
|
||||
int c_rx = 0;
|
||||
|
||||
for (int cx = 0; (size_t) cx < erow->n_chars; cx++) {
|
||||
if (erow->chars[cx] == '\t')
|
||||
c_rx += KILO_TAB_STOP - (c_rx % KILO_TAB_STOP);
|
||||
else
|
||||
c_rx++;
|
||||
|
||||
if (c_rx >= rx)
|
||||
return cx;
|
||||
}
|
||||
|
||||
return erow->n_chars;
|
||||
}
|
||||
|
||||
void erow_free(struct erow *erow) {
|
||||
if (erow->chars) free(erow->chars);
|
||||
if (erow->rchars) free(erow->rchars);
|
||||
}
|
||||
|
||||
static void erow_update_rchars(struct erow *erow) {
|
||||
if (erow->rchars)
|
||||
free(erow->rchars);
|
||||
|
||||
size_t n_rchars_max = 16;
|
||||
erow->rchars = malloc(erow->n_rchars);
|
||||
erow->n_rchars = 0;
|
||||
|
||||
for (char *c = erow->chars; c < erow->chars + erow->n_chars; c++) {
|
||||
if (*c == '\t') {
|
||||
int spaces = KILO_TAB_STOP - (erow->n_rchars % KILO_TAB_STOP);
|
||||
|
||||
while (erow->n_rchars + spaces > n_rchars_max)
|
||||
erow->rchars = realloc(erow->rchars, n_rchars_max *= 2);
|
||||
|
||||
memset(erow->rchars + erow->n_rchars, ' ', spaces);
|
||||
erow->n_rchars += spaces;
|
||||
} else {
|
||||
if (erow->n_rchars + 1 > n_rchars_max)
|
||||
erow->rchars = realloc(erow->rchars, n_rchars_max *= 2);
|
||||
|
||||
erow->rchars[erow->n_rchars++] = *c;
|
||||
}
|
||||
}
|
||||
|
||||
erow->rchars = realloc(erow->rchars, erow->n_rchars);
|
||||
}
|
||||
|
50
src/kilo.c
50
src/kilo.c
|
@ -36,9 +36,6 @@ void editor_init(char *filename) {
|
|||
|
||||
if (terminal_enable_raw() == -1) die("term_enable_raw");
|
||||
|
||||
E.cx = E.cy = E.rx = 0;
|
||||
E.row_off = E.col_off = 0;
|
||||
|
||||
if (terminal_get_win_size(&E.screenrows, &E.screencols) == -1)
|
||||
die("term_get_win_size");
|
||||
E.screenrows -= 2;
|
||||
|
@ -61,39 +58,40 @@ void editor_set_message(const char *fmt, ...) {
|
|||
E.message_time = time(NULL);
|
||||
}
|
||||
|
||||
// TODO: Implement a fully featured line editor
|
||||
// TODO: Implement a fully featured line editor here
|
||||
char *editor_prompt(const char *prompt) {
|
||||
size_t buffer_size = 64;
|
||||
char *buffer = malloc(buffer_size);
|
||||
size_t buf_cap = 64;
|
||||
size_t buf_size = 0;
|
||||
char *buf = malloc(buf_cap);
|
||||
|
||||
size_t buffer_len = 0;
|
||||
buffer[buffer_len] = '\0';
|
||||
buf[buf_size] = '\0';
|
||||
|
||||
while (true) {
|
||||
editor_set_message(prompt, buffer);
|
||||
editor_set_message(prompt, buf);
|
||||
ui_draw_screen();
|
||||
|
||||
KEY key = terminal_read_key();
|
||||
if (key == ESCAPE) {
|
||||
editor_set_message("");
|
||||
free(buffer);
|
||||
return NULL;
|
||||
} else if (key == ENTER) {
|
||||
if (buffer_len > 0) {
|
||||
editor_set_message("");
|
||||
buffer = realloc(buffer, buffer_len + 1);
|
||||
return buffer;
|
||||
}
|
||||
if (key == ESCAPE) goto failure;
|
||||
else if (key == ENTER) {
|
||||
if (buf_size > 0) goto success;
|
||||
else goto failure;
|
||||
} else if (isprint(key)) {
|
||||
if (buffer_len >= buffer_size - 1) {
|
||||
buffer_size *= 2;
|
||||
buffer = realloc(buffer, buffer_size);
|
||||
}
|
||||
if (buf_size + 1 >= buf_cap)
|
||||
buf = realloc(buf, buf_cap *= 2);
|
||||
|
||||
buffer[buffer_len++] = key;
|
||||
buffer[buffer_len] = '\0';
|
||||
buf[buf_size] = key;
|
||||
buf_size++;
|
||||
buf[buf_size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
failure:
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
success:
|
||||
if (buf)
|
||||
buf = realloc(buf, buf_size + 1);
|
||||
|
||||
editor_set_message("");
|
||||
return buf;
|
||||
}
|
||||
|
|
19
src/ui.c
19
src/ui.c
|
@ -28,8 +28,8 @@ void ui_draw_screen(void) {
|
|||
write(STDIN_FILENO, draw_buf->chars, draw_buf->n_chars);
|
||||
ab_free(draw_buf);
|
||||
|
||||
int row_pos = E.cy - E.row_off + 1;
|
||||
int col_pos = E.rx - E.col_off + 1;
|
||||
int row_pos = E.current_buf->cy - E.current_buf->row_off + 1;
|
||||
int col_pos = E.current_buf->rx - E.current_buf->col_off + 1;
|
||||
if (terminal_set_cursor_pos(row_pos, col_pos) == -1)
|
||||
die("term_set_cursor_pos");
|
||||
|
||||
|
@ -40,14 +40,17 @@ void ui_draw_screen(void) {
|
|||
static void ui_draw_rows(struct append_buf *draw_buf) {
|
||||
terminal_set_cursor_pos(1, 1);
|
||||
for (int y = 0; y < E.screenrows; y++) {
|
||||
bool in_file = (y < E.current_buf->n_rows - E.row_off);
|
||||
bool no_file = (E.current_buf->n_rows == 0);
|
||||
bool in_file = (y < E.current_buf->n_rows - E.current_buf->row_off);
|
||||
bool no_file = (E.current_buf->filename == NULL && E.current_buf->n_rows == 0);
|
||||
|
||||
if (in_file) {
|
||||
struct erow erow = E.current_buf->rows[y + E.row_off];
|
||||
int max_len = MIN(erow.n_rchars - E.col_off, E.screencols);
|
||||
struct erow *crow = buffer_get_crow(E.current_buf);
|
||||
|
||||
ab_append(draw_buf, erow.rchars + E.col_off, MAX(max_len, 0));
|
||||
size_t len = crow->n_rchars - E.current_buf->col_off;
|
||||
len = MIN(len, (size_t) E.screencols);
|
||||
len = MAX(len, 0);
|
||||
|
||||
ab_append(draw_buf, crow->rchars + E.current_buf->col_off, len);
|
||||
} else if (no_file && y == E.screenrows / 2) {
|
||||
char welcome[64];
|
||||
int len = snprintf(welcome, sizeof(welcome),
|
||||
|
@ -78,7 +81,7 @@ static void ui_draw_statusbar(struct append_buf *draw_buf) {
|
|||
len = sprintf(buf, "%s %s-- %d lines", display, modified, n_rows);
|
||||
memcpy(status_buf, buf, len);
|
||||
|
||||
len = sprintf(buf, "%d:%d", E.cy + 1, E.rx + 1);
|
||||
len = sprintf(buf, "%d:%d", E.current_buf->cy + 1, E.current_buf->rx + 1);
|
||||
memcpy(status_buf + E.screencols - len, buf, len);
|
||||
|
||||
ab_append(draw_buf, status_buf, E.screencols);
|
||||
|
|
Reference in a new issue