Incremental search
This commit is contained in:
parent
827be306ef
commit
be036bbee3
128
kilo.c
128
kilo.c
@ -69,7 +69,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 ***/
|
||||||
|
|
||||||
@ -269,6 +269,27 @@ 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 rx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cx;
|
||||||
|
}
|
||||||
|
|
||||||
void editorUpdateRow(erow *row)
|
void editorUpdateRow(erow *row)
|
||||||
{
|
{
|
||||||
int tabs = 0;
|
int tabs = 0;
|
||||||
@ -501,7 +522,7 @@ 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");
|
||||||
@ -532,6 +553,87 @@ 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 == '\x1b')
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
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 {
|
||||||
@ -735,7 +837,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);
|
||||||
@ -759,6 +861,10 @@ char *editorPrompt(char *prompt)
|
|||||||
else if (c == '\x1b')
|
else if (c == '\x1b')
|
||||||
{
|
{
|
||||||
editorSetStatusMessage("");
|
editorSetStatusMessage("");
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
callback(buf, c);
|
||||||
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -767,6 +873,10 @@ char *editorPrompt(char *prompt)
|
|||||||
if (buflen != 0)
|
if (buflen != 0)
|
||||||
{
|
{
|
||||||
editorSetStatusMessage("");
|
editorSetStatusMessage("");
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
callback(buf, c);
|
||||||
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -780,6 +890,11 @@ char *editorPrompt(char *prompt)
|
|||||||
buf[buflen++] = c;
|
buf[buflen++] = c;
|
||||||
buf[buflen] = '\0';
|
buf[buflen] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
callback(buf, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -876,6 +991,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:
|
||||||
@ -962,7 +1081,8 @@ 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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user