-
Notifications
You must be signed in to change notification settings - Fork 85
Open
Description
First of all thank you for the amazing tutorial! I came across an issue in search feature. When we press the arrow keys to find the next match, we move to the next or previous rows. But, there might be matches in the same row. Also, when we search in the reverse direction the match in the last position must be found. I tried implementing this by adding a new function editorFindRowLastMatch( ) and making changes to editorFindCallback( ) and it seems to work.
/*** find ***/
int editorFindRowLastMatch(erow* row, int start, int end, char* query) //find position of last match in a row
{
int qlen = strlen(query);
while (end >= start)
{
if (row->render[end] == query[0])
{
if (!strncmp(&row->render[end], query, qlen))
return end;
}
end--;
}
return -1;
}
void editorFindCallback(char* query, int key) {
static int last_match = -1;
static int direction = 1;
static int saved_hl_line;
static char* saved_hl = NULL;
if (saved_hl) {
memcpy(E.row[saved_hl_line].hl, saved_hl, E.row[saved_hl_line].rsize);
free(saved_hl);
saved_hl = NULL;
}
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 rx = -1; //this variable will contain the postion of the match
int same_row = 0; //if the match is found in the same row
if (current != -1) //we check in the same row if there was a previous match
{
erow* row = &E.row[current];
if (direction == 1)
{
char* match = strstr(&row->render[E.rx + 1], query); //find a match after the previous match position(E.rx) in the same row
if (match)
{
rx = match - row->render;
E.cx = editorRowRxToCx(row, rx);
same_row = 1;
}
}
else //if in reverse direction
{
int lfound = editorFindRowLastMatch(row, 0, E.rx - 1, query); //find the first match before previous match in the same row
if (lfound != -1)
{
rx = lfound;
E.cx = editorRowRxToCx(row, rx);
same_row = 1;
}
}
}
if (!same_row) // if match was not found in the same_row
{
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;
rx = match - row->render;
if (direction == -1) //if match found and the direction is reverse we find the last match in that row
{
int lfound = editorFindRowLastMatch(row, rx + 1, row->rsize - strlen(query), query);
if (lfound != -1)
{
rx = lfound;
}
}
E.cx = editorRowRxToCx(row, rx);
E.rowoff = E.numrows;
break;
}
}
}
if (rx != -1) // highlight only when match is found
{
erow* row = &E.row[current];
saved_hl_line = current;
saved_hl = malloc(row->rsize);
memcpy(saved_hl, row->hl, row->rsize);
memset(&row->hl[rx], HL_MATCH, strlen(query));
}
}Metadata
Metadata
Assignees
Labels
No labels