From 5fe2c9acdc088859478437ef120042455480b5a6 Mon Sep 17 00:00:00 2001 From: Francois Fleuret Date: Thu, 9 Apr 2009 08:07:06 +0200 Subject: [PATCH] Add multi-file input. The first argument without a leading '-' and all the following, or all arguments following a '--', are now considered as filenames and their contents are concatenated as a single input. The -f option is now useless but remains for compatibility. --- selector.1 | 9 ++- selector.cc | 165 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 102 insertions(+), 72 deletions(-) diff --git a/selector.1 b/selector.1 index 58b6757..12c6e06 100644 --- a/selector.1 +++ b/selector.1 @@ -3,7 +3,7 @@ selector - A simple command line for dynamic pattern selection .SH "SYNOPSIS" .PP -\fBselector\fP [\fBoptions\fP] -f +\fBselector\fP [\fBoptions\fP] [ [ ...]] .SH "DESCRIPTION" .PP \fBselector\fP is a command line dynamic string selection. As you type @@ -20,8 +20,9 @@ line into the virtual tty input buffer, hence allowing the user to edit the line and execute it as a standard command. Keys corresponding to ASCII codes between ' ' and '~' add a character -to the pattern string. The Delete key, Backspace key, ^D and ^H delete -one character from the pattern string. +to the pattern string. The Backspace key, ^H and ^? delete a character +on the left of cursor, while Delete key and ^D delete a character on +the right of the cursor. The Up and Down cursor keys move the selected line accordingly, and PageUp and PageDown move by ten lines. The Home and End key move to @@ -49,6 +50,8 @@ remove duplicated lines start with the regexp mode activated .IP "\fB-a\fP" 10 make the matching case sensitive +.IP "\fB--\fP" 10 +state that all following arguments are filenames .IP "\fB-t \fP" 10 add a title in the modeline .IP "\fB-c <fg modeline> <bg modeline> <fg highlight> <bg highlight>\fP" 10 diff --git a/selector.cc b/selector.cc index a58e2bb..ccc6158 100644 --- a/selector.cc +++ b/selector.cc @@ -499,6 +499,78 @@ void update_screen(int *current_line, int *temporary_line, int motion, ////////////////////////////////////////////////////////////////////// +void read_file(const char *input_filename, + int nb_lines_max, int *nb_lines, char **lines, + int hash_table_size, int *hash_table) { + + char buffer[buffer_size], raw_line[buffer_size];; + + ifstream file(input_filename); + + if(file.fail()) { + cerr << "Can not open " << input_filename << endl; + exit(1); + } + + while(*nb_lines < nb_lines_max && !file.eof()) { + + file.getline(raw_line, buffer_size); + + if(raw_line[0]) { + + if(file.fail()) { + cerr << "Line too long:" << endl; + cerr << raw_line << endl; + exit(1); + } + + char *s, *t; + const char *u; + + s = buffer; + t = raw_line; + while(*t) { + u = unctrl(*t++); + while(*u) { *s++ = *u++; } + } + *s = '\0'; + + s = buffer; + + if(zsh_history && *s == ':') { + while(*s && *s != ';') s++; + if(*s == ';') s++; + } + + if(bash_history && (*s == ' ' || (*s >= '0' && *s <= '9'))) { + while(*s == ' ' || (*s >= '0' && *s <= '9')) s++; + } + + int dup; + + if(hash_table) { + dup = test_and_add(s, *nb_lines, lines, hash_table, hash_table_size); + } else { + dup = -1; + } + + if(dup < 0) { + lines[*nb_lines] = new char[strlen(s) + 1]; + strcpy(lines[*nb_lines], s); + } else { + // The string was already in there, so we do not allocate a + // new string but use the pointer to the first occurence of it + lines[*nb_lines] = lines[dup]; + lines[dup] = 0; + } + + (*nb_lines)++; + } + } +} + +////////////////////////////////////////////////////////////////////// + int main(int argc, char **argv) { if(!ttyname(STDIN_FILENO)) { @@ -506,7 +578,6 @@ int main(int argc, char **argv) { exit(1); } - char buffer[buffer_size], raw_line[buffer_size];; int color_fg_modeline, color_bg_modeline; int color_fg_highlight, color_bg_highlight; @@ -524,8 +595,9 @@ int main(int argc, char **argv) { int i = 1; int error = 0, show_help = 0; + int rest_are_files = 0; - while(!error && !show_help && i < argc) { + while(!error && !show_help && i < argc && argv[i][0] == '-' && !rest_are_files) { if(strcmp(argv[i], "-o") == 0) { check_opt(argc, argv, i, 1, "<output filename>"); @@ -608,13 +680,18 @@ int main(int argc, char **argv) { i += 5; } + else if(strcmp(argv[i], "--") == 0) { + rest_are_files = 1; + i++; + } + else if(strcmp(argv[i], "-h") == 0) { show_help = 1; i++; } else { - cerr << "Unknown argument " << argv[i] << "." << endl; + cerr << "Unknown option " << argv[i] << "." << endl; error = 1; } } @@ -625,7 +702,7 @@ int main(int argc, char **argv) { << "Written by Francois Fleuret <francois@fleuret.org>." << endl << endl - << "Usage: " << argv[0] << " [options] -f <file>" << endl + << "Usage: " << argv[0] << " [options] [<filename1> [<filename2> ...]]" << endl << endl << " -h show this help" << endl << " -v inject the selected line in the tty" << endl @@ -636,6 +713,7 @@ int main(int argc, char **argv) { << " -e start in regexp mode" << endl << " -a case sensitive" << endl << " -m monochrome mode" << endl + << " -- rest of the arguments are filenames" << endl << " -t <title>" << endl << " add a title in the modeline" << endl << " -c <fg modeline> <bg modeline> <fg highlight> <bg highlight>" << endl @@ -653,20 +731,7 @@ int main(int argc, char **argv) { char **lines = new char *[nb_lines_max]; - if(!input_filename[0]) { - cerr << "You must specify a input file with -f." << endl; - exit(1); - } - int nb_lines = 0; - - ifstream file(input_filename); - - if(file.fail()) { - cerr << "Can not open " << input_filename << endl; - return 1; - } - int hash_table_size = nb_lines_max * 10; int *hash_table = 0; @@ -674,60 +739,22 @@ int main(int argc, char **argv) { hash_table = new_hash_table(hash_table_size); } - while(nb_lines < nb_lines_max && !file.eof()) { - - file.getline(raw_line, buffer_size); - - if(raw_line[0]) { - - if(file.fail()) { - cerr << "Line too long:" << endl; - cerr << raw_line << endl; - exit(1); - } - - char *s, *t; - const char *u; - - s = buffer; - t = raw_line; - while(*t) { - u = unctrl(*t++); - while(*u) { *s++ = *u++; } - } - *s = '\0'; - - s = buffer; - - if(zsh_history && *s == ':') { - while(*s && *s != ';') s++; - if(*s == ';') s++; - } - - if(bash_history && (*s == ' ' || (*s >= '0' && *s <= '9'))) { - while(*s == ' ' || (*s >= '0' && *s <= '9')) s++; - } + // if(i == argc && !input_filename[0]) { + // cerr << "You must provide a filename." << endl; + // exit(1); + // } - int dup; - - if(hash_table) { - dup = test_and_add(s, nb_lines, lines, hash_table, hash_table_size); - } else { - dup = -1; - } - - if(dup < 0) { - lines[nb_lines] = new char[strlen(s) + 1]; - strcpy(lines[nb_lines], s); - } else { - // The string was already in there, so we do not allocate a - // new string but use the pointer to the first occurence of it - lines[nb_lines] = lines[dup]; - lines[dup] = 0; - } + if(input_filename[0]) { + read_file(input_filename, + nb_lines_max, &nb_lines, lines, + hash_table_size, hash_table); + } - nb_lines++; - } + while(i < argc) { + read_file(argv[i], + nb_lines_max, &nb_lines, lines, + hash_table_size, hash_table); + i++; } delete[] hash_table; -- 2.39.5