Archived
1
Fork 0

Add simple backspacing

This commit is contained in:
Hadeed 2023-09-04 08:56:00 +05:00
parent 7a9727a550
commit 818ef8d40b
10 changed files with 135 additions and 39 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ kilo
.cache .cache
.clangd .clangd
compile_commands.json compile_commands.json
test_file

View file

@ -1,6 +1,8 @@
#ifndef BUFFER_H #ifndef BUFFER_H
#define BUFFER_H #define BUFFER_H
#include <stdbool.h>
#include "utils.h" #include "utils.h"
struct erow { struct erow {
@ -15,6 +17,7 @@ struct buffer {
char *filename; char *filename;
struct erow *rows; struct erow *rows;
int n_rows; int n_rows;
bool modified;
}; };
struct buffer *buffer_create(void); struct buffer *buffer_create(void);
@ -24,6 +27,7 @@ ERRCODE buffer_write_file(struct buffer *buffer);
void erow_update_rendering(struct erow *erow); void erow_update_rendering(struct erow *erow);
void erow_insert_char(struct erow *erow, int at, char c); 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_cx_to_rx(struct erow *erow, int cx);
int erow_rx_to_cx(struct erow *erow, int rx); int erow_rx_to_cx(struct erow *erow, int rx);

View file

@ -3,8 +3,10 @@
#include "input.h" #include "input.h"
void command_quit(void);
void command_move_cursor(KEY key); void command_move_cursor(KEY key);
void command_insert_char(char c); void command_insert_char(char c);
void command_delete_char(void);
void command_save_buffer(void); void command_save_buffer(void);
#endif // COMMANDS_H #endif // COMMANDS_H

View file

@ -11,6 +11,7 @@ struct editor_state {
int cx, cy, rx; int cx, cy, rx;
int row_off, col_off; int row_off, col_off;
int screenrows, screencols; int screenrows, screencols;
int quit_times;
struct buffer *current_buf; struct buffer *current_buf;
struct termios orig_termios; struct termios orig_termios;

View file

@ -7,6 +7,7 @@
#define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
typedef int ERRCODE; typedef int ERRCODE;
#define RETURN(code) do {errcode = code; goto END;} while(0)
void die(const char *context); void die(const char *context);

View file

@ -10,15 +10,17 @@
#include "utils.h" #include "utils.h"
static void buffer_free_rows(struct buffer *buffer); static void buffer_free_rows(struct buffer *buffer);
static char *buffer_get_string(struct buffer *buffer, size_t *len_p);
struct buffer *buffer_create(void) { struct buffer *buffer_create(void) {
struct buffer *buf = malloc(sizeof(struct buffer)); struct buffer *buffer = malloc(sizeof(struct buffer));
buf->filename = NULL; buffer->filename = NULL;
buf->rows = NULL; buffer->rows = NULL;
buf->n_rows = 0; buffer->n_rows = 0;
buffer->modified = false;
return buf; return buffer;
} }
// TODO: Handle file not existing // TODO: Handle file not existing
@ -57,33 +59,40 @@ void buffer_read_file(struct buffer *buffer, const char *filename) {
free(line_buffer); free(line_buffer);
fclose(file); fclose(file);
buffer->modified = false;
} }
ERRCODE buffer_write_file(struct buffer *buffer) { ERRCODE buffer_write_file(struct buffer *buffer) {
ERRCODE errcode = 0;
int fd = -1;
char *write_buffer = NULL;
if (buffer->filename == NULL) if (buffer->filename == NULL)
return -1; RETURN(-1);
size_t len = 0; size_t len;
write_buffer = buffer_get_string(buffer, &len);
for (int i = 0; i < buffer->n_rows; i++) fd = open(buffer->filename, O_RDWR | O_TRUNC | O_CREAT, 0644);
len += buffer->rows[i].n_chars + 1; if (fd == -1)
RETURN(-2);
char *write_buffer = malloc(len); if (write(fd, write_buffer, len) != (ssize_t) len)
char *p = write_buffer; RETURN(-3);
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++;
}
int fd = open(buffer->filename, O_RDWR | O_TRUNC | O_CREAT, 0644); END:
write(fd, write_buffer, len); if (fd != -1)
close(fd); close(fd);
if (write_buffer)
free(write_buffer); free(write_buffer);
return 0; if (errcode == 0)
buffer->modified = false;
return errcode;
} }
void buffer_append_row(struct buffer *buffer, const char *chars, int n_chars) { void buffer_append_row(struct buffer *buffer, const char *chars, int n_chars) {
@ -98,6 +107,8 @@ void buffer_append_row(struct buffer *buffer, const char *chars, int n_chars) {
new_row->n_rchars = 0; new_row->n_rchars = 0;
erow_update_rendering(new_row); erow_update_rendering(new_row);
buffer->modified = true;
} }
void buffer_free(struct buffer *buffer) { void buffer_free(struct buffer *buffer) {
@ -112,6 +123,25 @@ static void buffer_free_rows(struct buffer *buffer) {
} }
} }
static char *buffer_get_string(struct buffer *buffer, size_t *len_p) {
*len_p = 0;
for (int i = 0; i < buffer->n_rows; i++)
*len_p += 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++;
}
return write_buffer;
}
/*****************************************************************************/ /*****************************************************************************/
void erow_update_rendering(struct erow *erow) { void erow_update_rendering(struct erow *erow) {
@ -160,6 +190,25 @@ void erow_insert_char(struct erow *erow, int at, char c) {
erow->n_chars++; erow->n_chars++;
erow_update_rendering(erow); erow_update_rendering(erow);
// TODO: Seems like a bad idea
E.current_buf->modified = true;
}
void erow_delete_char(struct erow *erow, int at) {
if (at < 0) at = 0;
if (at > erow->n_chars) at = erow->n_chars;
if (at != 0) {
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);
}
// TODO
E.current_buf->modified = true;
} }
int erow_cx_to_rx(struct erow *erow, int cx) { int erow_cx_to_rx(struct erow *erow, int cx) {

View file

@ -1,15 +1,29 @@
#include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "buffer.h"
#include "commands.h" #include "commands.h"
#include "input.h" #include "input.h"
#include "kilo.h" #include "kilo.h"
#include "buffer.h" #include "terminal.h"
#include "utils.h" #include "utils.h"
static void cursor_adjust_viewport(void); static void cursor_adjust_viewport(void);
static void cursor_check_file_bounds(bool horizontal); static void cursor_check_file_bounds(bool horizontal);
static void cursor_update_rx(bool horizontal); static void cursor_update_rx(bool horizontal);
void command_quit(void) {
if (E.current_buf->modified && E.quit_times) {
editor_set_message("Unsaved changed! Press quit %d more time(s)", E.quit_times);
E.quit_times--;
} else {
terminal_clear();
exit(0);
}
}
void command_move_cursor(KEY key) { void command_move_cursor(KEY key) {
struct erow *rows = E.current_buf->rows; struct erow *rows = E.current_buf->rows;
int n_rows = E.current_buf->n_rows; int n_rows = E.current_buf->n_rows;
@ -64,13 +78,24 @@ void command_insert_char(char c) {
E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx); E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx);
} }
void command_delete_char(void) {
struct erow *row = E.current_buf->rows + E.cy;
if (E.cx == 0) {
// TODO
} else
erow_delete_char(row, E.cx);
E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx);
}
void command_save_buffer(void) { void command_save_buffer(void) {
ERRCODE errcode = buffer_write_file(E.current_buf); ERRCODE errcode = buffer_write_file(E.current_buf);
if (errcode == 0) if (errcode == 0)
editor_set_message("Saved file %s", E.current_buf->filename); editor_set_message("Saved file %s", E.current_buf->filename);
else if (errcode == -1) else
editor_set_message("Save failed, no filename"); editor_set_message("Save failed: ERRCODE %d: %s", errcode, strerror(errno));
} }
static void cursor_check_file_bounds(bool horizontal) { static void cursor_check_file_bounds(bool horizontal) {
@ -87,7 +112,13 @@ static void cursor_check_file_bounds(bool horizontal) {
E.cy = n_rows; E.cy = n_rows;
if (E.cx < 0) { if (E.cx < 0) {
if (E.cy > 0 && horizontal) E.cx = rows[--E.cy].n_chars; if (E.cy > 0 && horizontal)
{
current_row = &rows[--E.cy];
max_x = current_row->n_chars;
E.cx = max_x;
}
else E.cx = 0; else E.cx = 0;
} }

View file

@ -1,8 +1,9 @@
#include <stdlib.h> #include <stdlib.h>
#include "input.h"
#include "terminal.h"
#include "commands.h" #include "commands.h"
#include "input.h"
#include "kilo.h"
#include "terminal.h"
#include "utils.h" #include "utils.h"
void input_process_key(void) { void input_process_key(void) {
@ -20,28 +21,31 @@ void input_process_key(void) {
command_move_cursor(c); command_move_cursor(c);
break; break;
case CTRL_KEY('Q'):
command_quit();
return;
case CTRL_KEY('S'): case CTRL_KEY('S'):
command_save_buffer(); command_save_buffer();
break; break;
case CTRL_KEY('Q'):
terminal_clear();
exit(0);
break;
case '\r': case '\r':
// TODO
break; break;
case BACKSPACE: case BACKSPACE:
case CTRL_KEY('H'): case CTRL_KEY('H'):
case DEL: case DEL:
command_delete_char();
break; break;
case CTRL_KEY('L'): case CTRL_KEY('L'):
// case NOP: case NOP:
break; break;
default: default:
command_insert_char(c); command_insert_char(c);
} }
E.quit_times = 3;
} }

View file

@ -40,6 +40,7 @@ void editor_init(char *filename) {
if (terminal_get_win_size(&E.screenrows, &E.screencols) == -1) if (terminal_get_win_size(&E.screenrows, &E.screencols) == -1)
die("term_get_win_size"); die("term_get_win_size");
E.screenrows -= 2; E.screenrows -= 2;
E.quit_times = 3;
E.current_buf = buffer_create(); E.current_buf = buffer_create();
if (filename) if (filename)

View file

@ -72,7 +72,9 @@ static void ui_draw_statusbar(struct append_buf *draw_buf) {
ab_append(draw_buf, "\x1b[7m", 4); ab_append(draw_buf, "\x1b[7m", 4);
char *display = E.current_buf->filename ? E.current_buf->filename : "[NO NAME]"; char *display = E.current_buf->filename ? E.current_buf->filename : "[NO NAME]";
len = sprintf(buf, "%s -- %d lines", display, E.current_buf->n_rows); char *modified = E.current_buf->modified ? "(modified) " : "";
int n_rows = E.current_buf->n_rows;
len = sprintf(buf, "%s %s-- %d lines", display, modified, n_rows);
memcpy(status_buf, buf, len); memcpy(status_buf, buf, len);
len = sprintf(buf, "%d:%d", E.cy + 1, E.rx + 1); len = sprintf(buf, "%d:%d", E.cy + 1, E.rx + 1);