r/o

7785902418fa42f533981871a080ebc992cf2a62 parent e510b0df

authored by Yuki Izumi <yuki@kivikakk.ee> 10 years ago

Backspace up lines.

qb.c | 39 +++++++++++++++++++++++++++++++++++++++
qb.h | 2 +-
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/qb.c b/qb.c
index cd2753c..5b888b1 100644
--- a/qb.c
+++ b/qb.c
@@ -43,6 +43,11 @@ static doc_line_t *create_doc_line(void) {
return d;
}
+static void free_doc_line(doc_line_t *d) {
+ free(d->line);
+ free(d);
+}
+
static doc_line_t *get_current_doc_line(void) {
doc_line_t *d = active_doc;
for (int y = 0; y < cursor_y; ++y) {
@@ -78,6 +83,7 @@ static void insert_character(doc_line_t *d, int offset, char c) {
static void split_line(doc_line_t *d, int offset) {
doc_line_t *n = create_doc_line();
n->next = d->next;
+ n->prev = d;
d->next = n;
n->stored = d->stored - offset;
@@ -89,6 +95,34 @@ static void split_line(doc_line_t *d, int offset) {
++total_lines;
}
+static void delete_at(doc_line_t *d, int offset, int dir) {
+ /* dir should be -1 (backspace) or 0 (delete) */
+ if (dir == -1 && offset == 0) {
+ doc_line_t *p = d->prev;
+
+ if (!p) {
+ /* WRONG
+ * WAY
+ * GO BACK */
+ return;
+ }
+
+ --cursor_y;
+ cursor_x = p->stored;
+
+ ensure_available(p, d->stored);
+ memcpy(p->line + p->stored, d->line, d->stored);
+ p->next = d->next;
+ p->stored += d->stored;
+ if (d->next) {
+ d->next->prev = p;
+ }
+
+ free_doc_line(d);
+ --total_lines;
+ }
+}
+
static char get_character(SDL_Keycode sym, Uint16 mod) {
if (sym >= SDLK_a && sym <= SDLK_z) {
if (mod & (KMOD_SHIFT | KMOD_CAPS)) {
@@ -119,6 +153,7 @@ void qb_init(void) {
active_doc->allocated = active_doc->stored + 1;
active_doc->next = create_doc_line();
+ active_doc->next->prev = active_doc;
active_doc->next->line = strdup("20 GOTO 10");
active_doc->next->stored = strlen(active_doc->next->line);
active_doc->next->allocated = active_doc->next->stored + 1;
@@ -152,6 +187,10 @@ void qb_keypress(SDL_Keycode sym, Uint16 mod) {
split_line(get_current_doc_line(), cursor_x);
cursor_x = 0;
++cursor_y;
+ } else if (sym == SDLK_BACKSPACE) {
+ delete_at(get_current_doc_line(), cursor_x, -1);
+ } else if (sym == SDLK_DELETE) {
+ delete_at(get_current_doc_line(), cursor_x, 0);
}
qb_render();
diff --git a/qb.h b/qb.h
index e6ee0a3..e0878e2 100644
--- a/qb.h
+++ b/qb.h
@@ -6,7 +6,7 @@
typedef struct doc_line {
char *line;
int allocated, stored;
- struct doc_line *next;
+ struct doc_line *prev, *next;
} doc_line_t;
extern doc_line_t *active_doc;