commit 4854d4bceec950ee483994714fb7efddcc286670
parent 5df8a3fb5f92ff75e648abafa3e8a1e82f288576
Author: night0721 <[email protected]>
Date: Wed, 3 Jul 2024 02:41:28 +0100
Change white color, support enter and backspace and refactor
Diffstat:
6 files changed, 196 insertions(+), 91 deletions(-)
diff --git a/include/editor.h b/include/editor.h
@@ -2,5 +2,7 @@
#define EDITOR_H_
void insert_char(int c);
+void insert_new_line();
+void del_char();
#endif
diff --git a/include/row.h b/include/row.h
@@ -0,0 +1,14 @@
+#ifndef ROW_H_
+#define ROW_H_
+
+int row_cx_to_rx(row *row, int cx);
+void update_row(row *row);
+void insert_row(int at, char *s, size_t len);
+void free_row(row *row);
+void del_row(int at);
+void row_insert_char(row *row, int at, int c);
+void row_append_str(row *row, char *s, size_t len);
+void row_del_char(row *row, int at);
+char *rows_to_str(int *buflen);
+
+#endif
diff --git a/include/vip.h b/include/vip.h
@@ -7,6 +7,8 @@
/* CONFIG */
#define TAB_SIZE 4
+#define VERSION "0.0.1"
+
/* number of times of warning before quitting when there is modified text */
#define QUIT_CONFIRM 2
@@ -15,12 +17,15 @@
#define SURFACE_1_BG "\x1b[38;2;49;50;68m"
#define BLACK_BG "\x1b[38;2;0;0;0m"
#define BLACK_FG "\x1b[48;2;0;0;0m"
-#define WHITE_FG "\x1b[48;2;255;255;255m"
+#define WHITE_FG "\x1b[48;2;205;214;244m"
#define BLUE_FG "\x1b[48;2;137;180;250m"
#define BLUE_BG "\x1b[38;2;137;180;250m"
#define GREEN_FG "\x1b[48;2;166;227;161m"
-#define VERSION "0.0.1"
+
+#define NORMAL 0
+#define INSERT 1
+#define VISUAL 2
typedef struct row {
int size;
@@ -38,6 +43,7 @@ typedef struct editor {
int rows;
row *row;
int dirty;
+ int mode;
char *filename;
char statusmsg[80];
time_t statusmsg_time;
@@ -55,6 +61,7 @@ void abAppend(struct abuf *ab, const char *s, int len);
void append_row(char *s, size_t len);
void row_insert_char(row *row, int at, int c);
+void row_del_char(row *row, int at);
extern editor vip;
diff --git a/src/editor.c b/src/editor.c
@@ -1,12 +1,46 @@
#include "vip.h"
+#include "row.h"
extern editor vip;
void insert_char(int c)
{
if (vip.cy == vip.rows) {
- append_row("", 0);
+ insert_row(vip.rows, "", 0);
}
row_insert_char(&vip.row[vip.cy], vip.cx, c);
vip.cx++;
}
+
+void insert_new_line()
+{
+ if (vip.cx == 0) {
+ insert_row(vip.cy, "", 0);
+ } else {
+ row *row = &vip.row[vip.cy];
+ insert_row(vip.cy + 1, &row->chars[vip.cx], row->size - vip.cx);
+ row = &vip.row[vip.cy];
+ row->size = vip.cx;
+ row->chars[row->size] = '\0';
+ update_row(row);
+ }
+ vip.cy++;
+ vip.cx = 0;
+}
+
+void del_char()
+{
+ if (vip.cy == vip.rows) return;
+ if (vip.cx == 0 && vip.cy == 0) return;
+
+ row *row = &vip.row[vip.cy];
+ if (vip.cx > 0) {
+ row_del_char(row, vip.cx - 1);
+ vip.cx--;
+ } else {
+ vip.cx = vip.row[vip.cy - 1].size;
+ row_append_str(&vip.row[vip.cy - 1], row->chars, row->size);
+ del_row(vip.cy);
+ vip.cy--;
+ }
+}
diff --git a/src/row.c b/src/row.c
@@ -0,0 +1,127 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vip.h"
+
+extern editor vip;
+
+int row_cx_to_rx(row *row, int cx)
+{
+ int rx = 0;
+ for (int j = 0; j < cx; j++) {
+ if (row->chars[j] == '\t') {
+ rx += (TAB_SIZE - 1) - (rx % TAB_SIZE);
+ }
+ rx++;
+ }
+ return rx;
+}
+
+void update_row(row *row)
+{
+ int tabs = 0;
+ for (int j = 0; j < row->size; j++)
+ if (row->chars[j] == '\t') tabs++;
+ free(row->render);
+ row->render = malloc(row->size + tabs * (TAB_SIZE - 1) + 1);
+ int idx = 0;
+ for (int j = 0; j < row->size; j++) {
+ if (row->chars[j] == '\t') {
+ row->render[idx++] = ' ';
+ while (idx % TAB_SIZE != 0) {
+ row->render[idx++] = ' ';
+ }
+ }
+ else {
+ row->render[idx++] = row->chars[j];
+ }
+ }
+ row->render[idx] = '\0';
+ row->render_size = idx;
+}
+
+void insert_row(int at, char *s, size_t len)
+{
+ if (at < 0 || at > vip.rows) return;
+
+ vip.row = realloc(vip.row, sizeof(row) * (vip.rows + 1));
+ memmove(&vip.row[at + 1], &vip.row[at], sizeof(row) * (vip.rows - at));
+
+ vip.row[at].size = len;
+ vip.row[at].chars = malloc(len + 1);
+ memcpy(vip.row[at].chars, s, len);
+ vip.row[at].chars[len] = '\0';
+
+ vip.row[at].render_size = 0;
+ vip.row[at].render = NULL;
+ update_row(&vip.row[at]);
+
+ vip.rows++;
+ vip.dirty++;
+}
+
+void free_row(row *row)
+{
+ free(row->render);
+ free(row->chars);
+}
+
+void del_row(int at)
+{
+ if (at < 0 || at >= vip.rows) return;
+ free_row(&vip.row[at]);
+ memmove(&vip.row[at], &vip.row[at + 1], sizeof(row) * (vip.rows - at - 1));
+ vip.rows--;
+ vip.dirty++;
+}
+
+void row_insert_char(row *row, int at, int c)
+{
+ if (at < 0 || at > row->size) {
+ at = row->size;
+ }
+ row->chars = realloc(row->chars, row->size + 2);
+ memmove(&row->chars[at + 1], &row->chars[at], row->size - at + 1);
+ row->size++;
+ row->chars[at] = c;
+ update_row(row);
+ vip.dirty++;
+}
+
+void row_append_str(row *row, char *s, size_t len)
+{
+ row->chars = realloc(row->chars, row->size + len + 1);
+ memcpy(&row->chars[row->size], s, len);
+ row->size += len;
+ row->chars[row->size] = '\0';
+ update_row(row);
+ vip.dirty++;
+}
+
+void row_del_char(row *row, int at)
+{
+ if (at < 0 || at >= row->size) return;
+ memmove(&row->chars[at], &row->chars[at + 1], row->size - at);
+ row->size--;
+ update_row(row);
+ vip.dirty++;
+}
+
+char *rows_to_str(int *buflen)
+{
+ int total_len = 0;
+ for (int j = 0; j < vip.rows; j++) {
+ total_len += vip.row[j].size + 1;
+ }
+ *buflen = total_len;
+ char *buf = malloc(total_len);
+ char *p = buf;
+ for (int j = 0; j < vip.rows; j++) {
+ memcpy(p, vip.row[j].chars, vip.row[j].size);
+ p += vip.row[j].size;
+ *p = '\n';
+ p++;
+ }
+ return buf;
+}
diff --git a/src/vip.c b/src/vip.c
@@ -13,6 +13,7 @@
#include "term.h"
#include "bar.h"
#include "editor.h"
+#include "row.h"
#define CTRL_KEY(k) ((k) & 0x1f)
@@ -90,90 +91,6 @@ int read_key()
}
}
-int row_cx_to_rx(row *row, int cx)
-{
- int rx = 0;
- for (int j = 0; j < cx; j++) {
- if (row->chars[j] == '\t') {
- rx += (TAB_SIZE - 1) - (rx % TAB_SIZE);
- }
- rx++;
- }
- return rx;
-}
-
-void update_row(row *row)
-{
- int tabs = 0;
- for (int j = 0; j < row->size; j++)
- if (row->chars[j] == '\t') tabs++;
- free(row->render);
- row->render = malloc(row->size + tabs * (TAB_SIZE - 1) + 1);
- int idx = 0;
- for (int j = 0; j < row->size; j++) {
- if (row->chars[j] == '\t') {
- row->render[idx++] = ' ';
- while (idx % TAB_SIZE != 0) {
- row->render[idx++] = ' ';
- }
- }
- else {
- row->render[idx++] = row->chars[j];
- }
- }
- row->render[idx] = '\0';
- row->render_size = idx;
-}
-
-void append_row(char *s, size_t len)
-{
- vip.row = realloc(vip.row, sizeof(row) * (vip.rows + 1));
-
- int at = vip.rows;
- vip.row[at].size = len;
- vip.row[at].chars = malloc(len + 1);
- memcpy(vip.row[at].chars, s, len);
- vip.row[at].chars[len] = '\0';
-
- vip.row[at].render_size = 0;
- vip.row[at].render = NULL;
- update_row(&vip.row[at]);
-
- vip.rows++;
- vip.dirty++;
-}
-
-void row_insert_char(row *row, int at, int c)
-{
- if (at < 0 || at > row->size) {
- at = row->size;
- }
- row->chars = realloc(row->chars, row->size + 2);
- memmove(&row->chars[at + 1], &row->chars[at], row->size - at + 1);
- row->size++;
- row->chars[at] = c;
- update_row(row);
- vip.dirty++;
-}
-
-char *rows_to_str(int *buflen)
-{
- int total_len = 0;
- for (int j = 0; j < vip.rows; j++) {
- total_len += vip.row[j].size + 1;
- }
- *buflen = total_len;
- char *buf = malloc(total_len);
- char *p = buf;
- for (int j = 0; j < vip.rows; j++) {
- memcpy(p, vip.row[j].chars, vip.row[j].size);
- p += vip.row[j].size;
- *p = '\n';
- p++;
- }
- return buf;
-}
-
void open_editor(char *filename)
{
free(vip.filename);
@@ -190,7 +107,7 @@ void open_editor(char *filename)
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
len--;
}
- append_row(line, len);
+ insert_row(vip.rows, line, len);
}
free(line);
fclose(fp);
@@ -345,11 +262,12 @@ void move_cursor(int key)
void process_key()
{
- static int quit_times = QUIT_CONFIRM
+ static int quit_times = QUIT_CONFIRM;
+
int c = read_key();
switch (c) {
case '\r':
- /* TBC */
+ insert_new_line();
break;
case CTRL_KEY('q'):
@@ -380,7 +298,9 @@ void process_key()
case BACKSPACE:
case CTRL_KEY('h'):
case DEL_KEY:
- /* TBC */
+ if (c == DEL_KEY)
+ move_cursor(ARROW_RIGHT);
+ del_char();
break;
case PAGE_UP:
@@ -426,6 +346,7 @@ void init_editor()
vip.rows = 0;
vip.row = NULL;
vip.dirty = 0;
+ vip.mode = NORMAL;
vip.filename = NULL;
vip.statusmsg[0] = '\0';
vip.statusmsg_time = 0;