summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jet.c7
-rw-r--r--page.c93
-rw-r--r--point.c87
-rw-r--r--test/page.c54
4 files changed, 91 insertions, 150 deletions
diff --git a/jet.c b/jet.c
index b539082..290b95e 100644
--- a/jet.c
+++ b/jet.c
@@ -6,6 +6,7 @@
#include <unistd.h>
#include <curses.h>
#include "page.c"
+#include "point.c"
int main(int argc, char *argv[]) {
initscr();
@@ -33,7 +34,7 @@ int main(int argc, char *argv[]) {
int number_of_lines = 0;
for (struct point i = {page, 0}; !at_eof(&i); move_point_forward(&i)) {
- if (get_element(&i) == '\n') number_of_lines++;
+ if (element(&i) == '\n') number_of_lines++;
}
while (1) {
@@ -42,8 +43,8 @@ int main(int argc, char *argv[]) {
int iter_line = 0;
for (struct point i = {page, 0}; !at_eof(&i) && iter_line < window_height + current_line; move_point_forward(&i)) {
- if (iter_line >= current_line) addch(get_element(&i));
- if (get_element(&i) == '\n') iter_line++;
+ if (iter_line >= current_line) addch(element(&i));
+ if (element(&i) == '\n') iter_line++;
}
}
diff --git a/page.c b/page.c
index d450522..b945ef8 100644
--- a/page.c
+++ b/page.c
@@ -1,5 +1,4 @@
#include <stdint.h>
-#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
@@ -14,45 +13,6 @@ struct page {
struct page *prev;
};
-struct point {
- struct page *current_page;
- uint16_t index;
-};
-
-uint16_t index_to_offset(struct page *page, uint16_t index) {
- if (index < page->gap_start) {
- return index;
- } else {
- return index + (page->gap_end - page->gap_start);
- }
-}
-
-bool at_eof(struct point *point) {
- return point->index == point->current_page->element_count;
-}
-
-void move_point_forward(struct point *point) {
- struct page *page = point->current_page;
- if (point->index < page->element_count) {
- point->index++;
- }
- if (point->index == page->element_count && page->next) {
- point->index = 0;
- point->current_page = page->next;
- }
-}
-
-void move_point_backward(struct point *point) {
- struct page *page = point->current_page;
- if (point->index == 0 && page->prev) {
- point->index = page->prev->element_count;
- point->current_page = page->prev;
- }
- if (point->index > 0) {
- point->index--;
- }
-}
-
struct page *new_page() {
struct page *result = malloc(sizeof(struct page));
result->buffer = malloc(PAGE_SIZE);
@@ -105,56 +65,3 @@ void move_gap_backward(struct page *page) {
page->gap_start--;
page->buffer[page->gap_end] = page->buffer[page->gap_start];
}
-
-void move_gap(struct page *page, uint16_t index) {
- while (page->gap_end < index_to_offset(page, index)) {
- move_gap_forward(page);
- }
- while (page->gap_end > index_to_offset(page, index)) {
- move_gap_backward(page);
- }
-}
-
-void insert_at_point(struct point *point, uint8_t c) {
- struct page *page = point->current_page;
- if (page->gap_start == page->gap_end) {
- split_page(page);
- if (point->index >= PAGE_SIZE / 2) {
- page = page->next;
- point->current_page = page;
- point->index -= PAGE_SIZE / 2;
- }
- }
- move_gap(page, point->index);
- page->buffer[page->gap_start] = c;
- page->gap_start++;
- page->element_count++;
- move_point_forward(point);
-}
-
-void delete_at_point(struct point *point) {
- struct page *page = point->current_page;
- if (page->element_count == 0) {
- if (page->prev) {
- page = page->prev;
- free_page(point->current_page);
- point->current_page = page;
- point->index = page->element_count;
- } else if (page->next) {
- page = page->next;
- free_page(point->current_page);
- point->current_page = page;
- point->index = 0;
- }
- }
- move_gap(page, point->index);
- if (page->gap_start != 0) {
- page->gap_start--;
- page->element_count--;
- move_point_backward(point);
- }
-}
-
-uint8_t get_element(struct point *point) {
- return point->current_page->buffer[index_to_offset(point->current_page, point->index)];
-}
diff --git a/point.c b/point.c
new file mode 100644
index 0000000..e9d6472
--- /dev/null
+++ b/point.c
@@ -0,0 +1,87 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+struct point {
+ struct page *page;
+ uint16_t index;
+};
+
+uint16_t index_to_offset(struct point *point) {
+ if (point->index < point->page->gap_start) {
+ return point->index;
+ } else {
+ return point->index + (point->page->gap_end - point->page->gap_start);
+ }
+}
+
+uint8_t element(struct point *point) {
+ return point->page->buffer[index_to_offset(point)];
+}
+
+bool at_eof(struct point *point) {
+ return point->index == point->page->element_count;
+}
+
+void move_point_forward(struct point *point) {
+ if (point->index < point->page->element_count) {
+ point->index++;
+ }
+ if (point->index == point->page->element_count && point->page->next) {
+ point->index = 0;
+ point->page = point->page->next;
+ }
+}
+
+void move_point_backward(struct point *point) {
+ if (point->index == 0 && point->page->prev) {
+ point->index = point->page->prev->element_count;
+ point->page = point->page->prev;
+ }
+ if (point->index > 0) {
+ point->index--;
+ }
+}
+
+void align_gap(struct point *point) {
+ while (point->page->gap_end < index_to_offset(point)) {
+ move_gap_forward(point->page);
+ }
+ while (point->page->gap_end > index_to_offset(point)) {
+ move_gap_backward(point->page);
+ }
+}
+
+void insert_at_point(struct point *point, uint8_t c) {
+ if (point->page->gap_start == point->page->gap_end) {
+ split_page(point->page);
+ if (point->index >= PAGE_SIZE / 2) {
+ point->page = point->page->next;
+ point->index -= PAGE_SIZE / 2;
+ }
+ }
+ align_gap(point);
+ point->page->buffer[point->page->gap_start] = c;
+ point->page->gap_start++;
+ point->page->element_count++;
+ move_point_forward(point);
+}
+
+void delete_at_point(struct point *point) {
+ if (point->page->element_count == 0) {
+ if (point->page->prev) {
+ point->page = point->page->prev;
+ point->index = point->page->element_count;
+ free_page(point->page->next);
+ } else if (point->page->next) {
+ point->page = point->page->next;
+ point->index = 0;
+ free_page(point->page->prev);
+ }
+ }
+ align_gap(point);
+ if (point->page->gap_start != 0) {
+ point->page->gap_start--;
+ point->page->element_count--;
+ move_point_backward(point);
+ }
+}
diff --git a/test/page.c b/test/page.c
deleted file mode 100644
index 0d4dd33..0000000
--- a/test/page.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <curses.h>
-
-#include "../page.c"
-
-int main() {
- int exit = 0;
- struct page *page = new_page();
- struct point point = {0};
- point.current_page = page;
-
- initscr();
- cbreak();
- noecho();
- nonl();
- intrflush(stdscr, FALSE);
- keypad(stdscr, TRUE);
-
- while (!exit) {
- clear();
-
- struct page *iter = page;
- while (iter) {
- addch('|');
- for (int i = 0; i < iter->gap_start; i++) {
- addch(iter->buffer[i]);
- }
- for (int i = iter->gap_start; i < iter->gap_end; i++) {
- addch('_');
- }
- for (int i = iter->gap_end; i < PAGE_SIZE; i++) {
- addch(iter->buffer[i]);
- }
- iter = iter->next;
- }
-
- int input = getch();
- switch (input) {
- case KEY_LEFT:
- move_point_backward(&point);
- break;
- case KEY_RIGHT:
- move_point_forward(&point);
- break;
- case KEY_BACKSPACE:
- delete_at_point(&point);
- break;
- default:
- insert_at_point(&point, input);
- }
- }
-
- endwin();
- return 0;
-}