commit 47e4d61a6d4032ad5385e4ec2b250d03b33e3ee2
parent 232db589e330589fcae177d2a0edbe8005d67a52
Author: night0721 <[email protected]>
Date: Wed, 3 Jul 2024 11:11:48 +0100
Search text
Diffstat:
6 files changed, 170 insertions(+), 78 deletions(-)
diff --git a/include/editor.h b/include/editor.h
@@ -5,5 +5,8 @@ void insert_char(int c);
void insert_new_line();
void shift_new_line();
void del_char();
+void open_editor(char *filename);
+char *prompt_editor(char *prompt, void (*callback)(char *, int));
+void find_editor();
#endif
diff --git a/include/row.h b/include/row.h
@@ -2,6 +2,7 @@
#define ROW_H_
int row_cx_to_rx(row *row, int cx);
+int row_rx_to_cx(row *row, int rx);
void update_row(row *row);
void insert_row(int at, char *s, size_t len);
void free_row(row *row);
diff --git a/include/vip.h b/include/vip.h
@@ -23,11 +23,25 @@
#define GREEN_FG "\x1b[48;2;166;227;161m"
#define GREEN_BG "\x1b[38;2;166;227;161m"
-
#define NORMAL 0
#define INSERT 1
#define VISUAL 2
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+enum keys {
+ BACKSPACE = 127,
+ ARROW_LEFT = 1000,
+ ARROW_RIGHT,
+ ARROW_UP,
+ ARROW_DOWN,
+ DEL_KEY,
+ HOME_KEY,
+ END_KEY,
+ PAGE_UP,
+ PAGE_DOWN
+};
+
typedef struct row {
int size;
int render_size;
@@ -60,10 +74,11 @@ struct abuf {
void abAppend(struct abuf *ab, const char *s, int len);
+int read_key();
+void refresh_screen();
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);
-char *prompt_editor(char *prompt);
extern editor vip;
diff --git a/src/editor.c b/src/editor.c
@@ -1,5 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
#include "vip.h"
+#include "bar.h"
#include "row.h"
+#include "term.h"
extern editor vip;
@@ -54,3 +61,119 @@ void del_char()
vip.cy--;
}
}
+
+void open_editor(char *filename)
+{
+ free(vip.filename);
+ vip.filename = strdup(filename);
+ FILE *fp = fopen(filename, "r");
+ if (!fp) {
+ die("fopen");
+ }
+ char *line = NULL;
+ size_t linecap = 0;
+ ssize_t len;
+ while ((len = getline(&line, &linecap, fp)) != -1) {
+ /* remove new line and carriage return at end of line */
+ while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
+ len--;
+ }
+ insert_row(vip.rows, line, len);
+ }
+ free(line);
+ fclose(fp);
+ /* reset dirtiness as nothing is modified yet */
+ vip.dirty = 0;
+}
+
+char *prompt_editor(char *prompt, void (*callback)(char *, int))
+{
+ size_t bufsize = 128;
+ char *buf = malloc(bufsize);
+ size_t buflen = 0;
+ buf[0] = '\0';
+ while (1) {
+ set_status_bar_message(prompt, buf);
+ refresh_screen();
+ int c = read_key();
+ if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
+ if (buflen != 0) {
+ buf[--buflen] = '\0';
+ }
+ } else if (c == '\x1b') {
+ set_status_bar_message("");
+ if (callback) callback(buf, c);
+ free(buf);
+ return NULL;
+ } else if (c == '\r') {
+ if (buflen != 0) {
+ set_status_bar_message("");
+ if (callback) callback(buf, c);
+ return buf;
+ }
+ } else if (!iscntrl(c) && c < 128) {
+ if (buflen == bufsize - 1) {
+ bufsize *= 2;
+ buf = realloc(buf, bufsize);
+ }
+ buf[buflen++] = c;
+ buf[buflen] = '\0';
+ }
+
+ if (callback) callback(buf, c);
+ }
+}
+
+void find_callback(char *query, int key)
+{
+ static int last_match = -1;
+ static int direction = 1;
+ if (key == '\r' || key == '\x1b') {
+ last_match = -1;
+ direction = 1;
+ return;
+ } else if (key == CTRL_KEY('n')) {
+ direction = 1;
+ } else if (key == CTRL_KEY('p')) {
+ direction = -1;
+ } else {
+ last_match = -1;
+ direction = 1;
+ }
+
+ if (last_match == -1) direction = 1;
+ int current = last_match;
+ for (int i = 0; i < vip.rows; i++) {
+ current += direction;
+
+ if (current == -1) current = vip.rows - 1;
+ else if (current == vip.rows) current = 0;
+
+ row *row = &vip.row[current];
+ char *match = strstr(row->render, query);
+ if (match) {
+ last_match = current;
+ vip.cy = current;
+ vip.cx = row_rx_to_cx(row, match - row->render);
+ vip.rowoff = vip.rows;
+ break;
+ }
+ }
+}
+
+void find_editor()
+{
+ int tmp_cx = vip.cx;
+ int tmp_cy = vip.cy;
+ int tmp_coloff = vip.coloff;
+ int tmp_rowoff = vip.rowoff;
+ char *query = prompt_editor("/%s", find_callback);
+ if (query) {
+ free(query);
+ } else {
+ vip.cx = tmp_cx;
+ vip.cy = tmp_cy;
+ vip.coloff = tmp_coloff;
+ vip.rowoff = tmp_rowoff;
+ }
+}
diff --git a/src/row.c b/src/row.c
@@ -18,6 +18,21 @@ int row_cx_to_rx(row *row, int cx)
return rx;
}
+int row_rx_to_cx(row *row, int rx)
+{
+ int cur_rx = 0;
+ int cx;
+ for (cx = 0; cx < row->size; cx++) {
+ if (row->chars[cx] == '\t') {
+ cur_rx += (TAB_SIZE - 1) - (cur_rx % TAB_SIZE);
+ }
+ cur_rx++;
+ if (cur_rx > rx)
+ return cx;
+ }
+ return cx;
+}
+
void update_row(row *row)
{
int tabs = 0;
diff --git a/src/vip.c b/src/vip.c
@@ -15,21 +15,6 @@
#include "editor.h"
#include "row.h"
-#define CTRL_KEY(k) ((k) & 0x1f)
-
-enum editorKey {
- BACKSPACE = 127,
- ARROW_LEFT = 1000,
- ARROW_RIGHT,
- ARROW_UP,
- ARROW_DOWN,
- DEL_KEY,
- HOME_KEY,
- END_KEY,
- PAGE_UP,
- PAGE_DOWN
-};
-
editor vip;
int read_key()
@@ -87,34 +72,10 @@ int read_key()
}
}
-void open_editor(char *filename)
-{
- free(vip.filename);
- vip.filename = strdup(filename);
- FILE *fp = fopen(filename, "r");
- if (!fp) {
- die("fopen");
- }
- char *line = NULL;
- size_t linecap = 0;
- ssize_t len;
- while ((len = getline(&line, &linecap, fp)) != -1) {
- /* remove new line and carriage return at end of line */
- while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
- len--;
- }
- insert_row(vip.rows, line, len);
- }
- free(line);
- fclose(fp);
- /* reset dirtiness as nothing is modified yet */
- vip.dirty = 0;
-}
-
void save_file()
{
if (vip.filename == NULL) {
- vip.filename = prompt_editor("Save as: %s (ESC to cancel)");
+ vip.filename = prompt_editor("Save as: %s", NULL);
if (vip.filename == NULL) {
set_status_bar_message("Save aborted");
return;
@@ -230,40 +191,6 @@ void refresh_screen()
abFree(&ab);
}
-char *prompt_editor(char *prompt)
-{
- size_t bufsize = 128;
- char *buf = malloc(bufsize);
- size_t buflen = 0;
- buf[0] = '\0';
- while (1) {
- set_status_bar_message(prompt, buf);
- refresh_screen();
- int c = read_key();
- if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
- if (buflen != 0) {
- buf[--buflen] = '\0';
- }
- } else if (c == '\x1b') {
- set_status_bar_message("");
- free(buf);
- return NULL;
- } else if (c == '\r') {
- if (buflen != 0) {
- set_status_bar_message("");
- return buf;
- }
- } else if (!iscntrl(c) && c < 128) {
- if (buflen == bufsize - 1) {
- bufsize *= 2;
- buf = realloc(buf, bufsize);
- }
- buf[buflen++] = c;
- buf[buflen] = '\0';
- }
- }
-}
-
void move_cursor(int key)
{
row *row = (vip.cy >= vip.rows) ? NULL : &vip.row[vip.cy];
@@ -365,7 +292,10 @@ void process_key()
case ':': /* PASSTHROUGH */
if (vip.mode == NORMAL) {
- char *cmd = prompt_editor(":%s");
+ char *cmd = prompt_editor(":%s", NULL);
+ if (cmd == NULL) {
+ return;
+ }
switch (cmd[0]) {
case 'q':
if (cmd[1] == '!') {
@@ -388,6 +318,11 @@ void process_key()
save_file();
}
}
+ case '/': /* PASSTHROUGH */
+ if (vip.mode == NORMAL) {
+ find_editor();
+ break;
+ }
case 'k': /* PASSTHROUGH */
if (vip.mode != INSERT) {
@@ -457,7 +392,7 @@ int main(int argc, char **argv)
open_editor(argv[1]);
}
- set_status_bar_message(":w - Save, :q - Quit");
+ set_status_bar_message("By night0721 and gnucolas");
while (1) {
refresh_screen();