+// Yeah, global variables!
+
+int nb_lines_max = 1000;
+char pattern_separator = ';';
+int output_to_vt_buffer = 0;
+int with_colors = 1;
+int zsh_history = 0, bash_history = 0;
+int inverse_order = 0;
+int remove_duplicates = 0;
+
+//////////////////////////////////////////////////////////////////////
+
+// This looks severely Linux-only ...
+
+void inject_into_tty_buffer(char *line) {
+ struct termios oldtio, newtio;
+ tcgetattr(STDIN_FILENO,&oldtio);
+ memset(&newtio, 0, sizeof(newtio));
+ // Set input mode (non-canonical, *no echo*,...)
+ tcsetattr(STDIN_FILENO, TCSANOW, &newtio);
+ // Put the selected line in the tty input buffer
+ for(char *k = line; *k; k++) {
+ ioctl(STDIN_FILENO, TIOCSTI, k);
+ }
+ // Restore the old settings
+ tcsetattr(STDIN_FILENO, TCSANOW, &oldtio);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+int match(char *string, int nb_patterns, char **patterns) {
+ for(int n = 0; n < nb_patterns; n++) {
+ if(strstr(string, patterns[n]) == 0) return 0;
+ }
+ return 1;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+void check_opt(int argc, char **argv, int n_opt, int n, const char *help) {
+ if(n_opt + n >= argc) {
+ cerr << "Missing argument for " << argv[n_opt] << "."
+ << " "
+ << "Expecting " << help << "."
+ << endl;
+ exit(1);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// A quick and dirty hash table
+
+int *new_hash_table(int hash_table_size) {
+ int *result;
+ result = new int[hash_table_size];
+ for(int k = 0; k < hash_table_size; k++) {
+ result[k] = -1;
+ }
+ return result;
+}
+
+int test_and_add(char *new_string, int new_index,
+ char **strings, int *hash_table, int hash_table_size) {
+ unsigned int code = 0;
+
+ for(int k = 0; new_string[k]; k++) {
+ code += int(new_string[k]) << (8 * k%4);
+ }
+
+ code = code % hash_table_size;
+
+ while(hash_table[code] >= 0) {
+ if(strcmp(new_string, strings[hash_table[code]]) == 0) return 1;
+ code = (code + 1) % hash_table_size;
+ }
+
+ hash_table[code] = new_index;
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+int previous_visible(int current_line, int nb_lines, char **lines, int nb_patterns, char **patterns) {
+ int line = current_line - 1;
+ while(line >= 0 && !match(lines[line], nb_patterns, patterns)) line--;
+ return line;
+}
+
+int next_visible(int current_line, int nb_lines, char **lines, int nb_patterns, char **patterns) {
+ int line = current_line + 1;
+ while(line < nb_lines && !match(lines[line], nb_patterns, patterns)) line++;
+
+ if(line < nb_lines)
+ return line;
+ else
+ return -1;
+}
+
+void update_screen(int *current_line, int *temporary_line, int motion,
+ int nb_lines, char **lines,
+ char *pattern_list) {
+