예제 #1
0
파일: filter.c 프로젝트: rubicks/rlwrap
void handle_out_of_band(int tag, char *message) {
    int split_em_up = FALSE;
    switch (tag) {
    case TAG_ERROR:
        if (expected_tag == TAG_COMPLETION) /* start new line when completing (looks better) */
            fprintf(stderr, "\n"); /* @@@ error reporting (still) uses bufered I/O */
        myerror(FATAL|NOERRNO, message);
    case TAG_OUTPUT_OUT_OF_BAND:
        my_putstr(message);
        break;
    case TAG_ADD_TO_COMPLETION_LIST:
    case TAG_REMOVE_FROM_COMPLETION_LIST:
        split_em_up = TRUE;
        break;
    case TAG_IGNORE:
        break;
    default:
        myerror(FATAL|USE_ERRNO, "out-of-band message with unknown tag %d: <%20s>", tag, message);
    }
    if (split_em_up) {
        char **words = split_with(message, " \n\t");
        char **plist, *word;
        for(plist = words; (word = *plist); plist++)
            if (tag == TAG_ADD_TO_COMPLETION_LIST)
                add_word_to_completions(word);
            else
                remove_word_from_completions(word);
        free_splitlist(words);
    }
    free(message);
}
예제 #2
0
static int
handle_hotkey2(int UNUSED(count), int hotkey, int ignore_history)
{
  char *prefix, *postfix, *history,  *histpos_as_string, *executing_keyseq;
  char *new_prefix, *new_postfix, *new_history, *new_histpos_as_string, *message; 
  char *filter_food, *filtered, **fragments,  *new_rl_line_buffer;
  int length, new_histpos;
  unsigned long int hash;

  static const unsigned int MAX_HISTPOS_DIGITS = 6; /* one million history items should suffice */

  
#ifdef HAVE_RL_EXECUTING_KEYSEQ /* i.e. if readline version is >= 6.3 */
  executing_keyseq = mysavestring(rl_executing_keyseq);
#else
  executing_keyseq = mysavestring("?");
  *executing_keyseq = hotkey; /* The filter will only get the *last* byte of the key sequence that triggered rl_handle_hotkey */ 
#endif

    
  DPRINTF3(DEBUG_READLINE, "hotkey press (ignore_history == %d): %x (%s)", ignore_history, hotkey, mangle_string_for_debug_log(executing_keyseq, MANGLE_LENGTH));

  if (hotkey == '\t') /* this would go horribly wrong with all the splitting on '\t' going on.... @@@ or pass key as a string e.g. "009" */
    myerror(FATAL | NOERRNO, "Sorry, you cannot use TAB as an hotkey in rlwrap");


  prefix = mysavestring(rl_line_buffer);
  prefix[rl_point] = '\0';                                     /* chop off just before cursor */
  postfix = mysavestring(rl_line_buffer + rl_point);

  if (ignore_history) {
    histpos_as_string = mysavestring("0");
    history = mysavestring("");
  } else {
    histpos_as_string = as_string(where_history());
    assert(strlen(histpos_as_string) <= MAX_HISTPOS_DIGITS);
    history = entire_history_as_one_string();
    hash = hash_multiple(2, history, histpos_as_string);
  }     

  /* filter_food = key + tab + prefix + tab + postfix + tab + history + tab + histpos  + '\0' */
  length = strlen(rl_line_buffer) + strlen(history) + MAX_HISTPOS_DIGITS + 5; 
  filter_food = mymalloc(length);   
  sprintf(filter_food, "%s\t%s\t%s\t%s\t%s", executing_keyseq, prefix, postfix, history, histpos_as_string); /* this is the format that the filter expects */

  /* let the filter filter ...! */
  filtered= pass_through_filter(TAG_HOTKEY, filter_food);
  
  /* OK, we now have to read back everything. There should be exactly 5 TAB-separated components*/
  fragments = split_on_single_char(filtered, '\t', 5);
  message               = fragments[0];
  new_prefix            = fragments[1];
  new_postfix           = fragments[2];
  new_history           = fragments[3];
  new_histpos_as_string = fragments[4];

  if (!ignore_history && hash_multiple(2, new_history, new_histpos_as_string) != hash) { /* history has been rewritten */
    char **linep, **history_lines = split_on_single_char(new_history, '\n', 0);
    DPRINTF3(DEBUG_READLINE, "hash=%lx, new_history is %d bytes long, histpos <%s>", hash, (int) strlen(new_history), new_histpos_as_string);
    clear_history();
    for (linep = history_lines; *linep; linep++) 
      add_history(*linep);
    new_histpos = my_atoi(new_histpos_as_string);
    history_set_pos(new_histpos);
    free_splitlist(history_lines);
  }
  new_rl_line_buffer = add2strings(new_prefix, new_postfix);

  if ( (length = strlen(new_rl_line_buffer)) > 0  &&  new_rl_line_buffer[length - 1] == '\n') {
    new_rl_line_buffer[length - 1] = '\0';
    rl_done = TRUE;
    return_key = (char) '\n';
    assert(strchr(new_rl_line_buffer, '\n') == NULL);
  }

  rl_delete_text(0, strlen(rl_line_buffer));
  rl_point = 0;
  rl_insert_text(new_rl_line_buffer);
  rl_point = strlen(new_rl_line_buffer);

  
  
  if (*message && *message != hotkey) {                          /* if message has been set (i.e. != hotkey) , and isn't empty: */ 
    message = append_and_free_old(mysavestring(message), " ");   /* put space (for readability) between the message and the input line .. */
    message_in_echo_area(message);                          /* .. then write it to echo area */
  }     

  clear_line();
  rl_on_new_line();
  rl_redisplay();
 

  free_splitlist(fragments);                                   /* this will free all the fragments (and the list itself) in one go  */
  free_multiple(prefix, postfix, filter_food, executing_keyseq, filtered, new_rl_line_buffer, history, histpos_as_string, FMEND);
  return 0;
}