Search text

This commit is contained in:
Night Kaly 2024-07-03 11:11:48 +01:00
parent 232db589e3
commit 47e4d61a6d
Signed by: night0721
GPG key ID: 957D67B8DB7A119B
6 changed files with 170 additions and 78 deletions

View file

@ -5,5 +5,8 @@ void insert_char(int c);
void insert_new_line(); void insert_new_line();
void shift_new_line(); void shift_new_line();
void del_char(); void del_char();
void open_editor(char *filename);
char *prompt_editor(char *prompt, void (*callback)(char *, int));
void find_editor();
#endif #endif

View file

@ -2,6 +2,7 @@
#define ROW_H_ #define ROW_H_
int row_cx_to_rx(row *row, int cx); int row_cx_to_rx(row *row, int cx);
int row_rx_to_cx(row *row, int rx);
void update_row(row *row); void update_row(row *row);
void insert_row(int at, char *s, size_t len); void insert_row(int at, char *s, size_t len);
void free_row(row *row); void free_row(row *row);

View file

@ -23,11 +23,25 @@
#define GREEN_FG "\x1b[48;2;166;227;161m" #define GREEN_FG "\x1b[48;2;166;227;161m"
#define GREEN_BG "\x1b[38;2;166;227;161m" #define GREEN_BG "\x1b[38;2;166;227;161m"
#define NORMAL 0 #define NORMAL 0
#define INSERT 1 #define INSERT 1
#define VISUAL 2 #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 { typedef struct row {
int size; int size;
int render_size; int render_size;
@ -60,10 +74,11 @@ struct abuf {
void abAppend(struct abuf *ab, const char *s, int len); 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 append_row(char *s, size_t len);
void row_insert_char(row *row, int at, int c); void row_insert_char(row *row, int at, int c);
void row_del_char(row *row, int at); void row_del_char(row *row, int at);
char *prompt_editor(char *prompt);
extern editor vip; extern editor vip;

View file

@ -1,5 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "vip.h" #include "vip.h"
#include "bar.h"
#include "row.h" #include "row.h"
#include "term.h"
extern editor vip; extern editor vip;
@ -54,3 +61,119 @@ void del_char()
vip.cy--; 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;
}
}

View file

@ -18,6 +18,21 @@ int row_cx_to_rx(row *row, int cx)
return rx; 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) void update_row(row *row)
{ {
int tabs = 0; int tabs = 0;

View file

@ -15,21 +15,6 @@
#include "editor.h" #include "editor.h"
#include "row.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; editor vip;
int read_key() 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() void save_file()
{ {
if (vip.filename == NULL) { 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) { if (vip.filename == NULL) {
set_status_bar_message("Save aborted"); set_status_bar_message("Save aborted");
return; return;
@ -230,40 +191,6 @@ void refresh_screen()
abFree(&ab); 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) void move_cursor(int key)
{ {
row *row = (vip.cy >= vip.rows) ? NULL : &vip.row[vip.cy]; row *row = (vip.cy >= vip.rows) ? NULL : &vip.row[vip.cy];
@ -365,7 +292,10 @@ void process_key()
case ':': /* PASSTHROUGH */ case ':': /* PASSTHROUGH */
if (vip.mode == NORMAL) { if (vip.mode == NORMAL) {
char *cmd = prompt_editor(":%s"); char *cmd = prompt_editor(":%s", NULL);
if (cmd == NULL) {
return;
}
switch (cmd[0]) { switch (cmd[0]) {
case 'q': case 'q':
if (cmd[1] == '!') { if (cmd[1] == '!') {
@ -388,6 +318,11 @@ void process_key()
save_file(); save_file();
} }
} }
case '/': /* PASSTHROUGH */
if (vip.mode == NORMAL) {
find_editor();
break;
}
case 'k': /* PASSTHROUGH */ case 'k': /* PASSTHROUGH */
if (vip.mode != INSERT) { if (vip.mode != INSERT) {
@ -457,7 +392,7 @@ int main(int argc, char **argv)
open_editor(argv[1]); open_editor(argv[1]);
} }
set_status_bar_message(":w - Save, :q - Quit"); set_status_bar_message("By night0721 and gnucolas");
while (1) { while (1) {
refresh_screen(); refresh_screen();