Add search function

This commit is contained in:
Aaron Fischer 2018-10-09 10:29:14 +02:00
parent ba3fc967be
commit 1a24341130

86
kilo.c
View file

@ -70,7 +70,7 @@ struct editorConfig E;
void editorSetStatusMessage(const char *fmt, ...); void editorSetStatusMessage(const char *fmt, ...);
void editorRefreshScreen(); void editorRefreshScreen();
char *editorPrompt(char *prompt); char *editorPrompt(char *prompt, void (*callback)(char *, int));
/*** terminal ***/ /*** terminal ***/
@ -203,6 +203,19 @@ int editorRowCxToRx(erow *row, int cx) {
return rx; return rx;
} }
int editorRowRxToCx(erow *row, int rx) {
int cur_rx = 0;
int cx;
for (cx=0; cx < row->size; cx++) {
if (row->chars[cx] == '\t')
cur_rx += (KILO_TAB_STOP - 1) - (cur_rx % KILO_TAB_STOP);
cur_rx++;
if (cur_rx > rx) return cx;
}
return cx;
}
void editorUpdateRow(erow *row) { void editorUpdateRow(erow *row) {
int tabs = 0; int tabs = 0;
int j; int j;
@ -373,7 +386,7 @@ void editorOpen(char *filename) {
void editorSave() { void editorSave() {
if (E.filename == NULL) { if (E.filename == NULL) {
E.filename = editorPrompt("Save as: %s (ESC to cancel)"); E.filename = editorPrompt("Save as: %s (ESC to cancel)", NULL);
if (E.filename == NULL) { if (E.filename == NULL) {
editorSetStatusMessage("Save aborted"); editorSetStatusMessage("Save aborted");
return; return;
@ -401,6 +414,63 @@ void editorSave() {
editorSetStatusMessage("Can't save! I/O error: %s", strerror(errno)); editorSetStatusMessage("Can't save! I/O error: %s", strerror(errno));
} }
/** find **/
void editorFindCallback(char *query, int key) {
static int last_match = -1;
static int direction = 1;
if (key == '\r' || key == '\xb') {
last_match = -1;
direction = 1;
return;
} else if (key == ARROW_RIGHT || key == ARROW_DOWN) {
direction = 1;
} else if (key == ARROW_LEFT || key == ARROW_UP) {
direction = -1;
} else {
last_match = -1;
direction = 1;
}
if (last_match == -1) direction = 1;
int current = last_match;
int i;
for (i=0; i < E.numrows; i++) {
current += direction;
if (current == -1) current = E.numrows -1;
else if (current == E.numrows) current = 0;
erow *row = &E.row[current];
char *match = strstr(row->render, query);
if (match) {
last_match = current;
E.cy = current;
E.cx = editorRowRxToCx(row, match - row->render); // Substract pointers here
E.rowoff = E.numrows;
break;
}
}
}
void editorFind() {
int saved_cx = E.cx;
int saved_cy = E.cy;
int saved_coloff = E.coloff;
int saved_rowoff = E.rowoff;
char *query = editorPrompt("Search: %s (Use ESC/Arrows/Enter)", editorFindCallback);
if (query) {
free(query);
} else {
E.cx = saved_cx;
E.cy = saved_cy;
E.coloff = saved_coloff;
E.rowoff = saved_rowoff;
}
}
/*** append buffer ***/ /*** append buffer ***/
struct abuf { struct abuf {
@ -539,7 +609,7 @@ void editorSetStatusMessage(const char *fmt, ...) {
/*** input ***/ /*** input ***/
char *editorPrompt(char *prompt) { char *editorPrompt(char *prompt, void (*callback)(char *, int)) {
size_t bufsize = 128; size_t bufsize = 128;
char *buf = malloc(bufsize); char *buf = malloc(bufsize);
@ -555,11 +625,13 @@ char *editorPrompt(char *prompt) {
if (buflen != 0) buf[--buflen] = '\0'; if (buflen != 0) buf[--buflen] = '\0';
} else if (c == '\x1b') { } else if (c == '\x1b') {
editorSetStatusMessage(""); editorSetStatusMessage("");
if (callback) callback(buf, c);
free(buf); free(buf);
return NULL; return NULL;
} else if (c == '\r') { } else if (c == '\r') {
if (buflen != 0) { if (buflen != 0) {
editorSetStatusMessage(""); editorSetStatusMessage("");
if (callback) callback(buf, c);
return buf; return buf;
} }
} else if (!iscntrl(c) && c < 128) { } else if (!iscntrl(c) && c < 128) {
@ -570,6 +642,8 @@ char *editorPrompt(char *prompt) {
buf[buflen++] = c; buf[buflen++] = c;
buf[buflen] = '\0'; buf[buflen] = '\0';
} }
if (callback) callback(buf, c);
} }
} }
@ -649,6 +723,10 @@ void editorProcessKeypress() {
} }
break; break;
case CTRL_KEY('f'):
editorFind();
break;
case BACKSPACE: case BACKSPACE:
case CTRL_KEY('h'): case CTRL_KEY('h'):
case DEL_KEY: case DEL_KEY:
@ -716,7 +794,7 @@ int main(int argc, char *argv[]) {
editorOpen(argv[1]); editorOpen(argv[1]);
} }
editorSetStatusMessage("HELP: Ctrl-S = save | Ctrl-Q = Quit"); editorSetStatusMessage("HELP: Ctrl-S = save | Ctrl-Q = Quit | Ctrl-F = find");
while (1) { while (1) {
editorRefreshScreen(); editorRefreshScreen();