Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Searching in the same row #48

Open
patient74 opened this issue Dec 22, 2021 · 0 comments
Open

Searching in the same row #48

patient74 opened this issue Dec 22, 2021 · 0 comments

Comments

@patient74
Copy link

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));
    }

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant