#include "search.h" #include // for NULL #include // for free, malloc #include // for memcpy, memset, strlen, strstr #include "fn.h" // for E, editorConfig, erow, editorPrompt, editorHighl... #include "row.h" // for editorRowRxToCx #include "hl.h" // for editorSelectSyntaxHighlight void editorSearchCallback(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; // Clean up the syntax highlighting editorSelectSyntaxHighlight(); 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 // Reposition the cursor if needed if (E.cy < E.rowoff) { E.rowoff = E.cy; } if (E.cy >= E.rowoff + E.screenrows) { E.rowoff = E.cy - E.screenrows + 1; } saved_hl_line = current; saved_hl = malloc(row->rsize); memcpy(saved_hl, row->hl, row->rsize); memset(&row->hl[match - row->render], HL_MATCH, strlen(query)); break; } } } void editorSearch() { int saved_cx = E.cx; int saved_cy = E.cy; int saved_coloff = E.coloff; int saved_rowoff = E.rowoff; char *query = editorPrompt("Search (Use Arrows/ESC/Enter): %s", editorSearchCallback); if (query) { free(query); } else { E.cx = saved_cx; E.cy = saved_cy; E.coloff = saved_coloff; E.rowoff = saved_rowoff; } }