From: Francois Fleuret Date: Wed, 11 Mar 2009 15:13:22 +0000 (+0100) Subject: *** empty log message *** X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?a=commitdiff_plain;h=46c2d7bcdb9e4ca9ca803f9255606c11f4441ea1;p=selector.git *** empty log message *** --- diff --git a/selector.cc b/selector.cc index 0878f82..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; -int 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,50 +55,107 @@ int refresh_screen(int *screen_line, int *line, int nb_lines, char **lines, char printw("\n"); int nb_printed_lines = 1, last_printer_line = -1; - int y = 0; - int current_line = -1; - 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)); - current_line = y; - } 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; + + 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 = y; - nb_printed_lines++; + 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); } } @@ -99,20 +165,20 @@ int refresh_screen(int *screen_line, int *line, int nb_lines, char **lines, char 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)); refresh(); // After doing something on the display, we refresh it - - return current_line; } 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"; @@ -159,16 +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); - - int current_line = -1; + 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'; @@ -182,29 +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; } - current_line = 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"); - out << lines[current_line] << endl; - out.flush(); + // 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; }