Errors messages are now in red.
[selector.git] / selector.cc
index a3d54dd..a62d352 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 // To use it as a super-history-search for bash:
-// alias h='selector -d -i -b -v -f <(history)'
+// selector -q -b -i -d -v -w -l 10000 <(history)
 
 #include <fstream>
 #include <iostream>
@@ -51,7 +51,8 @@ char label_separator = '\0';
 int output_to_vt_buffer = 0;
 int add_control_qs = 0;
 int with_colors = 1;
-int zsh_history = 0, bash_history = 0;
+int zsh_history = 0;
+int bash_history = 0;
 int inverse_order = 0;
 int remove_duplicates = 0;
 int use_regexp = 0;
@@ -61,6 +62,7 @@ int error_flash = 0;
 
 #define COLOR_MODELINE 1
 #define COLOR_HIGHLIGHTED_LINE 2
+#define COLOR_ERROR 3
 
 //////////////////////////////////////////////////////////////////////
 
@@ -70,10 +72,10 @@ void inject_into_tty_buffer(char *string) {
   memset(&newtio, 0, sizeof(newtio));
   // Set input mode (non-canonical, *no echo*,...)
   tcsetattr(STDIN_FILENO, TCSANOW, &newtio);
-  char control_q = '\021';
+  const char control_q = '\021';
   // Put the selected string in the tty input buffer
-  for(char *k = string; *k; k++) {
-    if(add_control_qs) {
+  for(const char *k = string; *k; k++) {
+    if(add_control_qs && !(*k >= ' ' && *k <= '~')) {
       // Add ^Q to quote control characters
       ioctl(STDIN_FILENO, TIOCSTI, &control_q);
     }
@@ -123,6 +125,18 @@ void error_feedback() {
   }
 }
 
+void print_error_message(const char *message, int width) {
+  if(with_colors) {
+    attron(COLOR_PAIR(COLOR_ERROR));
+    addnstr(message, width);
+    attroff(COLOR_PAIR(COLOR_ERROR));
+  } else {
+    attron(A_STANDOUT);
+    addnstr(message, width);
+    attroff(A_STANDOUT);
+  }
+}
+
 //////////////////////////////////////////////////////////////////////
 // A quick and dirty hash table
 
@@ -349,12 +363,11 @@ void update_screen(int *current_line, int *temporary_line, int motion,
 
   int nb_printed_lines = 0;
 
-  clear();
   use_default_colors();
   addstr("\n");
 
   if(matcher.regexp_error) {
-    addstr("[regexp error]");
+    print_error_message("[regexp error]", console_width);
   } else if(nb_lines > 0) {
     int new_line;
     if(match(lines[*current_line], &matcher)) {
@@ -445,6 +458,8 @@ void update_screen(int *current_line, int *temporary_line, int motion,
           buffer[k++] = '\n';
           buffer[k++] = '\0';
 
+          clrtoeol();
+
           // Highlight the highlighted line ...
 
           if(l == new_line) {
@@ -473,12 +488,14 @@ void update_screen(int *current_line, int *temporary_line, int motion,
     *temporary_line = new_line;
 
     if(nb_printed_lines == 0) {
-      addnstr("[no selection]\n", console_width);
+      print_error_message("[no selection]\n", console_width);
     }
   } else {
-    addnstr("[empty choice]\n", console_width);
+    print_error_message("[empty choice]\n", console_width);
   }
 
+  clrtobot();
+
   // Draw the modeline
 
   move(0, 0);
@@ -773,6 +790,7 @@ int main(int argc, char **argv) {
          << endl
          << " -h      show this help" << endl
          << " -v      inject the selected line in the tty" << endl
+         << " -w      quote control characters with ^Qs when using -v" << endl
          << " -d      remove duplicated lines" << endl
          << " -b      remove the bash history line prefix" << endl
          << " -z      remove the zsh history line prefix" << endl
@@ -781,7 +799,7 @@ int main(int argc, char **argv) {
          << " -a      case sensitive" << endl
          << " -m      monochrome mode" << endl
          << " -q      make a flash instead of a beep on an edition error" << endl
-         << " --      rest of the arguments are filenames" << endl
+         << " --      all following arguments are filenames" << endl
          << " -t <title>" << endl
          << "         add a title in the modeline" << endl
          << " -c <fg modeline> <bg modeline> <fg highlight> <bg highlight>" << endl
@@ -869,6 +887,7 @@ int main(int argc, char **argv) {
 
   char pattern[buffer_size];
   pattern[0] = '\0';
+
   int cursor_position;
   cursor_position = 0;
 
@@ -900,6 +919,7 @@ int main(int argc, char **argv) {
 
       init_pair(COLOR_MODELINE, color_fg_modeline, color_bg_modeline);
       init_pair(COLOR_HIGHLIGHTED_LINE, color_fg_highlight, color_bg_highlight);
+      init_pair(COLOR_ERROR, COLOR_WHITE, COLOR_RED);
 
     } else {
       with_colors = 0;
@@ -909,7 +929,8 @@ int main(int argc, char **argv) {
   int key;
   int current_line = 0, temporary_line = 0;
 
-  update_screen(&current_line, &temporary_line, 0, nb_lines, labels, cursor_position, pattern);
+  update_screen(&current_line, &temporary_line, 0,
+                nb_lines, labels, cursor_position, pattern);
 
   do {
 
@@ -994,6 +1015,11 @@ int main(int argc, char **argv) {
       kill_after_cursor(pattern, &cursor_position);
     }
 
+    else if(key == '\014') { // ^L
+      // I suspect that we may sometime mess up the display
+      clear();
+    }
+
     update_screen(&current_line, &temporary_line, motion,
                   nb_lines, labels, cursor_position, pattern);