X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?a=blobdiff_plain;f=selector.cc;h=a6eec4717aebe07437ce6ffbeab5477ebeb99074;hb=46c2d7bcdb9e4ca9ca803f9255606c11f4441ea1;hp=1ac71b2fe2a771461128cb0571ca06b179c032f2;hpb=50766773ece1be211a42d2342203b14c051aaf0b;p=selector.git diff --git a/selector.cc b/selector.cc index 1ac71b2..a6eec47 100644 --- a/selector.cc +++ b/selector.cc @@ -28,14 +28,23 @@ using namespace std; +ostream *log; + const int buffer_size = 1024; const int nb_lines_max = 100000; -void refresh_screen(int *screen_line, int *line, int nb_lines, char **lines, char *regexp, int noblink) { +int match(char *string, char *regexp) { + return strstr(string, regexp) != 0; +} + +void update_screen(int *current_line, int motion, + int nb_lines, char **lines, + char *regexp, int noblink) { + char buffer[buffer_size]; - int maxx = getmaxx(stdscr); - int maxy = min(buffer_size-2, getmaxy(stdscr)); + int console_width = getmaxx(stdscr); + int console_height = getmaxy(stdscr); if(!noblink) { clear(); @@ -46,48 +55,107 @@ void refresh_screen(int *screen_line, int *line, int nb_lines, char **lines, cha printw("\n"); int nb_printed_lines = 1, last_printer_line = -1; - int y = 0; - while(nb_printed_lines < maxy && y < nb_lines) { - if(strstr(lines[y], regexp) && - (last_printer_line < 0 || strcmp(lines[y], lines[last_printer_line]))) { - int k = 0; + int new_line; + if(motion >= 0) { + new_line = *current_line + motion; + while(new_line < nb_lines && !match(lines[new_line], regexp)) { + new_line++; + } + if(new_line == nb_lines) { + new_line = *current_line; + while(new_line >= 0 && ! match(lines[new_line], regexp)) { + new_line--; + } + } + } else { + + new_line = *current_line - 1; + while(new_line >= 0 && ! match(lines[new_line], regexp)) { + new_line--; + } - while(lines[y][k] && k < buffer_size - 2 && k < maxx - 1) { - buffer[k] = lines[y][k]; - k++; + if(new_line < 0) { + new_line = *current_line; + while(new_line < nb_lines && !match(lines[new_line], regexp)) { + new_line++; + } + if(new_line == nb_lines) { + new_line = -1; } + } + } + + // Here new_line is either a line number matching the regexp, or -1 - if(noblink) { - while(k < maxx - 1) { - buffer[k++] = ' '; + if(new_line >= 0) { + int first_line = new_line, last_line = new_line, nb_match = 1; + + while(nb_match < console_height && (first_line > 0 || last_line < nb_lines - 1)) { + + if(first_line > 0) { + first_line--; + while(first_line > 0 && !match(lines[first_line], regexp)) { + first_line--; + } + if(match(lines[first_line], regexp)) { + nb_match++; } } - buffer[k++] = '\n'; - buffer[k++] = '\0'; - - if(nb_printed_lines == *line + 1) { - attron(COLOR_PAIR(2)); - printw(buffer); - attroff(COLOR_PAIR(2)); - } else { - printw(buffer); + + if(last_line < nb_lines - 1) { + last_line++; + while(last_line < nb_lines - 1 && !match(lines[last_line], regexp)) { + last_line++; + } + + if(match(lines[last_line], regexp)) { + nb_match++; + } } + } + + for(int l = first_line; l <= last_line; l++) { + if(match(lines[l], regexp)) { + int k = 0; - last_printer_line = y; - nb_printed_lines++; + while(lines[l][k] && k < buffer_size - 2 && k < console_width - 1) { + buffer[k] = lines[l][k]; + k++; + } + + if(noblink) { + while(k < console_width - 1) { + buffer[k++] = ' '; + } + } + buffer[k++] = '\n'; + buffer[k++] = '\0'; + + if(l == new_line) { + attron(COLOR_PAIR(2)); + printw(buffer); + attroff(COLOR_PAIR(2)); + } else { + printw(buffer); + } + + last_printer_line = l; + nb_printed_lines++; + } } - y++; + + *current_line = new_line; } if(noblink) { // Erase the rest of the window. That's slightly ugly. int k = 0; - while(k < maxx - 1) { + while(k < console_width - 1) { buffer[k++] = ' '; } buffer[k++] = '\n'; buffer[k++] = '\0'; - for(int l = nb_printed_lines; l < maxy; l++) { + for(int l = nb_printed_lines; l < console_height; l++) { printw(buffer); } } @@ -97,8 +165,8 @@ void refresh_screen(int *screen_line, int *line, int nb_lines, char **lines, cha move(0, 0); attron(COLOR_PAIR(1)); sprintf(buffer, "%d/%d pattern: %s", nb_printed_lines - 1, nb_lines, regexp); - for(int k = strlen(buffer); k < maxx - 1; k++) buffer[k] = ' '; - buffer[maxx-1] = '\0'; + for(int k = strlen(buffer); k < console_width - 1; k++) buffer[k] = ' '; + buffer[console_width-1] = '\0'; printw(buffer); attroff(COLOR_PAIR(1)); @@ -108,7 +176,9 @@ void refresh_screen(int *screen_line, int *line, int nb_lines, char **lines, cha int main(int argc, char **argv) { char buffer[buffer_size]; char *lines[nb_lines_max]; - int noblink = 1; + int noblink = 0; + + log = new fstream("/tmp/selector.log"); char *file_name; char stdin_name[] = "/dev/stdin"; @@ -155,14 +225,18 @@ int main(int argc, char **argv) { int key; - int line = 0, screen_line = 0; + int line = 0; - refresh_screen(&screen_line, &line, nb_lines, lines, regexp, noblink); + update_screen(&line, 0, + nb_lines, lines, + regexp, noblink); do { key = getch(); + int motion = 0; + if(key >= ' ' && key <= 'z') { regexp[regexp_point++] = key; regexp[regexp_point] = '\0'; @@ -176,25 +250,34 @@ int main(int argc, char **argv) { } else if(key == KEY_UP || key == '') { - if(line > 0) { - line--; - } + motion = -1; } else if(key == KEY_DOWN || key == '') { - line++; + motion = 1; } - refresh_screen(&screen_line, &line, nb_lines, lines, regexp, noblink); + update_screen(&line, motion, nb_lines, lines, regexp, noblink); } while(key != '\n' && key != KEY_ENTER && key != ''); echo(); curs_set(1); endwin(); + // ofstream out("/tmp/selector.out"); + // if(key == KEY_ENTER || key == '\n') { + // out << lines[highlighted_line] << endl; + // } else { + // out << endl; + // } + // out.flush(); + for(int l = 0; l < nb_lines; l++) { delete[] lines[l]; } + log->flush(); + delete log; + return 0; }