Пример #1
0
static int tab_callback(int count, int key) {
    if (!rl_point) {
        strip_initial_spaces += tab_width;
        return 0;
    }
    int i;
    for (i = line_start(rl_point); i < rl_point; i++) {
        if (rl_line_buffer[i] != ' ') {
            // do tab completion
            i = rl_point;
            rl_complete_internal('!');
            if (i < rl_point && rl_line_buffer[rl_point-1] == ' ') {
                rl_delete_text(rl_point-1, rl_point);
                rl_point = rl_point-1;
            }
            return 0;
        }
    }
    // indent to next tab stop
    if (suppress_space()) {
        spaces_suppressed += tab_width;
    } else {
        i = line_start(rl_point) + prompt_length;
        do { rl_insert_text(" "); } while ((rl_point - i) % tab_width);
    }
    return 0;
}
Пример #2
0
//------------------------------------------------------------------------------
static void suffix_translation()
{
    // readline's path completion may have appended a '/'. If so; flip it.

    char from;
    char* to;

    if (!rl_filename_completion_desired)
    {
        return;
    }

    if (g_slash_translation < 0)
    {
        return;
    }

    // Decide what direction we're going in.
    switch (g_slash_translation)
    {
    case 1:     from = '\\'; to = "/";  break;
    default:    from = '/';  to = "\\"; break;
    }

    // Swap the trailing slash, using Readline's API to maintain undo state.
    if ((rl_point > 0) && (rl_line_buffer[rl_point - 1] == from))
    {
        rl_delete_text(rl_point - 1, rl_point);
        --rl_point;
        rl_insert_text(to);
    }
}
Пример #3
0
static void gnu_rl_sigint_handler (int sig) /*{{{*/
{
   (void) sig;
   rl_delete_text (0, rl_end);
   rl_point = rl_end = 0;
   fprintf (stdout, "\n");
   rl_forced_update_display ();
}
Пример #4
0
static int delete_callback(int count, int key) {
    reset_indent();
    int j = rl_point;
    j += (rl_line_buffer[j] == '\n') ? prompt_length+1 : 1;
    if (rl_end < j) j = rl_end;
    rl_delete_text(rl_point, j);
    return 0;
}
Пример #5
0
static int delete_callback(int count, int key) {
    reset_indent();
    int j = rl_point;
    do {
        j += (rl_line_buffer[j] == '\n') ? prompt_length+1 : 1;
    } while (locale_is_utf8 && !isutf(rl_line_buffer[j]));
    if (rl_end < j) j = rl_end;
    rl_delete_text(rl_point, j);
    return 0;
}
Пример #6
0
static PyObject *
delete_text(PyObject *self, PyObject *args)
{
	int startpos, endpos;
	if (!PyArg_ParseTuple(args, "ii:delete_text", &startpos, &endpos))
		return NULL;
	rl_delete_text(startpos, endpos);
	Py_INCREF(Py_None);
	return Py_None;
}
Пример #7
0
int tio_rl_handler(int count, int key)
{
	if (key == CTRL('T')) {
		printf("\n");
		tio_print_status();
		printf("\n");
	}
    rl_delete_text(0, rl_end);
    rl_done = 1;
    return(0);
}
Пример #8
0
//------------------------------------------------------------------------------
static int getc_impl(FILE* stream)
{
    int i;
    while (1)
    {
        wchar_t wc[2];
        char utf8[4];

        i = _getwch();
        if (i == 0)
        {
            i = 0xe0;
        }

        // treat esc like cmd.exe does - clear the line.
        if (i == 0x1b)
        {
            rl_delete_text(0, rl_end);
            rl_point = 0;
            display();
            continue;
        }

        if (i < 0x7f || i == 0xe0)
        {
            break;
        }

        // Convert to utf-8 and insert directly into rl's line buffer.
        wc[0] = (wchar_t)i;
        wc[1] = L'\0';

        WideCharToMultiByte(
            CP_UTF8, 0,
            wc, -1,
            utf8, sizeof(utf8),
            NULL,
            NULL
        );

        rl_insert_text(utf8);
        display();
    }

    // Set the "meta" key bit if the ALT key is pressed.
    if (GetAsyncKeyState(VK_MENU) & 0x8000)
    {
        i |= 0x80;
    }

    return i;
}
Пример #9
0
int
rl_vi_change_to(int count, int key)
{
  int c, start_pos;

  if (_rl_uppercase_p (key))
    rl_stuff_char ('$');
  else if (vi_redoing)
    rl_stuff_char (_rl_vi_last_motion);

  start_pos = rl_point;

  if (rl_vi_domove (key, &c))
    {
      rl_ding ();
      return -1;
    }

  /* These are the motion commands that do not require adjusting the
     mark.  c[wW] are handled by special-case code in rl_vi_domove(),
     and already leave the mark at the correct location. */
  if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
    rl_mark++;

  /* The cursor never moves with c[wW]. */
  if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
    rl_point = start_pos;

  if (vi_redoing)
    {
      if (vi_insert_buffer && *vi_insert_buffer)
	rl_begin_undo_group ();
      rl_delete_text (rl_point, rl_mark);
      if (vi_insert_buffer && *vi_insert_buffer)
	{
	  rl_insert_text (vi_insert_buffer);
	  rl_end_undo_group ();
	}
    }
  else
    {
      rl_begin_undo_group ();		/* to make the `u' command work */
      rl_kill_text (rl_point, rl_mark);
      /* `C' does not save the text inserted for undoing or redoing. */
      if (_rl_uppercase_p (key) == 0)
        _rl_vi_doing_insert = 1;
      _rl_vi_set_last (key, count, rl_arg_sign);
      rl_vi_insertion_mode (1, key);
    }

  return (0);
}
Пример #10
0
int rline_clear(struct rline *rline)
{
    if (!rline)
        return -1;

    /* Clear whatever readline has in it's buffer. */
    rl_point = 0;
    rl_end = 0;
    rl_mark = 0;
    rl_delete_text(0, rl_end);

    return 0;
}
Пример #11
0
//------------------------------------------------------------------------------
int getc_impl(FILE* stream)
{
    int printable;
    int alt;
    int i;
    while (1)
    {
        wchar_t wc[2];
        char utf8[4];

        alt = 0;
        i = GETWCH_IMPL(&alt);

        // MSB is set if value represents a printable character.
        printable = (i & 0x80000000);
        i &= ~printable;

        // Treat esc like cmd.exe does - clear the line.
        if (i == 0x1b)
        {
            if (rl_editing_mode == emacs_mode &&
                get_clink_setting_int("esc_clears_line"))
            {
                using_history();
                rl_delete_text(0, rl_end);
                rl_point = 0;
                rl_redisplay();
                continue;
            }
        }

        // Mask off top bits, they're used to track ALT key state.
        if (i < 0x80 || (i == 0xe0 && !printable))
        {
            break;
        }

        // Convert to utf-8 and insert directly into rl's line buffer.
        wc[0] = (wchar_t)i;
        wc[1] = L'\0';
        WideCharToMultiByte(CP_UTF8, 0, wc, -1, utf8, sizeof(utf8), NULL, NULL);

        rl_insert_text(utf8);
        rl_redisplay();
    }

    alt = RL_ISSTATE(RL_STATE_MOREINPUT) ? 0 : alt;
    alt = alt ? 0x80 : 0;
    return i|alt;
}
Пример #12
0
static VALUE readline_buffer_ext(VALUE self, VALUE str){
  rb_secure(4);
  StringValue(str);

  if(rl_line_buffer == NULL)
    return Qnil;

#ifdef HAVE_RL_DELETE_TEXT
  rl_delete_text(0, rl_end);
#else
  rl_line_buffer[rl_end = 0] = '\0';
#endif
  rl_insert_text(RSTRING_PTR(str));
  rl_redisplay();

  return rb_str_new(rl_line_buffer, strlen(rl_line_buffer));
}
Пример #13
0
/* save readline internal state in rl_state, redisplay the prompt
   (so that client output gets printed at the right place) */
void
save_rl_state()
{
  free(saved_rl_state.input_buffer); /* free(saved_rl_state.raw_prompt) */;
  saved_rl_state.input_buffer = mysavestring(rl_line_buffer);
  /* saved_rl_state.raw_prompt = mysavestring(rl_prompt); */
 
  saved_rl_state.point = rl_point;      /* and point    */
  rl_line_buffer[0] = '\0';
  if (saved_rl_state.already_saved)
    return;
  saved_rl_state.already_saved = 1;
  rl_delete_text(0, rl_end);    /* clear line  (after prompt) */
  rl_point = 0;
  my_redisplay();               /* and redisplay (this time without user input, cf the comments for the line_handler() function below) */
  rl_callback_handler_remove(); /* restore original terminal settings */
  rl_deprep_terminal();

}
Пример #14
0
static int backspace_callback(int count, int key) {
    reset_indent();
    if (!rl_point) return 0;

    int i = line_start(rl_point), j = rl_point, k;
    if (!i || rl_point <= i + prompt_length) goto backspace;
    for (k = i; k < rl_point; k++)
        if (rl_line_buffer[k] != ' ') goto backspace;

//unindent:
    k = i + prompt_length;
    do { rl_point--; } while ((rl_point - k) % tab_width);
    goto finish;

backspace:
    rl_point = (i == 0 || rl_point-i > prompt_length) ? rl_point-1 : i-1;

finish:
    rl_delete_text(rl_point, j);
    return 0;
}
Пример #15
0
static int complete(lua_State *L)
{
  const char* line;
  char* out = NULL;
  line = lua_tostring(L, 1);
  rl_insert_text(line);
  lua_pop(L, 1);
  rl_complete(0, 0);
  if(rl_outstream == NULL)
    return 0;
  if (!lua_istable(L, -1)) {
    out = rl_copy_text(0, rl_end);
    /* Nothing found */
    if (out[0] == '\0')
      lua_pushfstring(L, line);
    else
      lua_pushfstring(L, out);
    free(out);
  }
  rl_delete_text(0, rl_end);
  rl_point = 0;
  return 1;
}
Пример #16
0
int
rl_vi_subst (int count, int key)
{
  rl_begin_undo_group ();

  if (uppercase_p (key))
    {
      rl_beg_of_line (1, key);
      rl_kill_line (1, key);
    }
  else
    rl_delete_text (rl_point, rl_point+count);

  rl_end_undo_group ();

  _rl_vi_set_last (key, count, rl_arg_sign);

  rl_begin_undo_group ();
  _rl_vi_doing_insert = 1;
  rl_vi_insertion_mode (1, key);

  return (0);
}
Пример #17
0
//------------------------------------------------------------------------------
static int completion_shim(int count, int invoking_key)
{
    int ret;

    // rl_complete checks if it was called previously.
    if (rl_last_func == completion_shim)
    {
        rl_last_func = rl_complete;
    }

    rl_begin_undo_group();
    ret = rl_complete(count, invoking_key);

    // readline's path completion may have appended a '/'. If so; flip it.
    if ((rl_point > 0) && (rl_line_buffer[rl_point - 1] == '/'))
    {
        rl_delete_text(rl_point - 1, rl_point);
        --rl_point;
        rl_insert_text("\\");
    }

    rl_end_undo_group();
    return ret;
}
Пример #18
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;
}
Пример #19
0
static int
munge_line_in_editor(int UNUSED(count), int UNUSED(key))
{
  int line_number = 0, column_number = 0, tmpfile_fd, bytes_read;
  size_t tmpfilesize;
  char *p, *tmpfilename, *text_to_edit;
  char *input, *rewritten_input, *rewritten_input2;


  if (!multiline_separator)
    return 0;

  tmpfile_fd = open_unique_tempfile(multi_line_tmpfile_ext, &tmpfilename);

  text_to_edit =
    search_and_replace(multiline_separator, "\n", rl_line_buffer, rl_point,
                       &line_number, &column_number);
  write_patiently(tmpfile_fd, text_to_edit, strlen(text_to_edit), "to temporary file");

  if (close(tmpfile_fd) != 0) /* improbable */
    myerror(FATAL|USE_ERRNO, "couldn't close temporary file %s", tmpfilename); 

  munge_file_in_editor(tmpfilename, line_number, column_number);
  
  /* read back edited input, replacing real newline with substitute */
  tmpfile_fd = open(tmpfilename, O_RDONLY);
  if (tmpfile_fd < 0)
    myerror(FATAL|USE_ERRNO, "could not read temp file %s", tmpfilename);
  tmpfilesize = filesize(tmpfilename);
  input = mymalloc(tmpfilesize + 1);
  bytes_read = read(tmpfile_fd, input, tmpfilesize);
  if (bytes_read < 0)
    myerror(FATAL|USE_ERRNO, "unreadable temp file %s", tmpfilename);
  input[bytes_read] = '\0';
  rewritten_input = search_and_replace("\t", "    ", input, 0, NULL, NULL);     /* rlwrap cannot handle tabs in input lines */
  rewritten_input2 =
    search_and_replace("\n", multiline_separator, rewritten_input, 0, NULL, NULL);
  for(p = rewritten_input2; *p ;p++)
    if(*p >= 0 && *p < ' ') /* @@@FIXME: works for UTF8, but not UTF16 or UTF32 (Mention this in manpage?)*/ 
      *p = ' ';        /* replace all control characters (like \r) by spaces */


  rl_delete_text(0, strlen(rl_line_buffer));
  rl_point = 0;  
  clear_line();
  cr();
  my_putstr(saved_rl_state.cooked_prompt);
  rl_insert_text(rewritten_input2);
  rl_point = 0;                 /* leave cursor on predictable place */
  rl_done = 1;                  /* accept line immediately */

  


  /* wash those dishes */
  if (unlink(tmpfilename))
    myerror(FATAL|USE_ERRNO, "could not delete temporary file %s", tmpfilename);

  free(tmpfilename);
  free(text_to_edit);
  free(input);
  free(rewritten_input);
  free(rewritten_input2);
  
  return_key = (char)'\n';
  return 0;
}
Пример #20
0
static void
line_handler(char *line)
{
  char *rewritten_line, *filtered_line;
  
  if (line == NULL) {           /* EOF on input, forward it  */
    DPRINTF1(DEBUG_READLINE, "EOF detected, writing character %d", term_eof);
    /* colour_the_prompt = FALSE; don't mess with the cruft that may come out of dying command @@@ but command may not die!*/
    write_EOF_to_master_pty();
  } else {
    if (*line &&                 /* forget empty lines  */
        redisplay &&             /* forget passwords    */
        !forget_line &&          /* forget lines entered by CTRL-O */
        !match_regexp(line, forget_regexp, TRUE)) {     /* forget lines (case-inseitively) matching -g option regexp */ 
      my_add_history(line);
    }
    forget_line = FALSE; /* until CTRL-O is used again */

    /* Time for a design decision: when we send the accepted line to the client command, it will most probably be echoed
       back. We have two choices: we leave the entered line on screen and suppress just enough of the clients output (I
       believe this is what rlfe does), or we remove the entered input (but not the prompt!) and let it be replaced by
       the echo.

       This is what we do; as a bonus, if the program doesn't echo, e.g. at a password prompt, the **** which has been
       put there by our homegrown_redisplay function will be removed (@@@is this what we want?)

       I think this method is more natural for multi-line input as well, (we will actually see our multi-line input as
       multiple lines) but not everyone will agree with that.
          
       O.K, we know for sure that cursor is at start of line. When clients output arrives, it will be printed at
       just the right place - but first we 'll erase the user input (as it may be about to be changed by the filter) */
    
    rl_delete_text(0, rl_end);  /* clear line  (after prompt) */
    rl_point = 0;
    my_redisplay();             /* and redisplay (this time without user input, cf the comments for the line_handler() function below) */

    rewritten_line =
      (multiline_separator ? 
       search_and_replace(multiline_separator, "\n", line, 0, NULL,
                          NULL) : mysavestring(line));


    
      
    if (redisplay)
      filtered_line = pass_through_filter(TAG_INPUT, rewritten_line);
    else { /* password, none of filters business */
      pass_through_filter(TAG_INPUT, "***"); /* filter some input anyway, to keep filter in sync (result is discarded).  */
      filtered_line = mysavestring(rewritten_line);
    }   
    free(rewritten_line);
        
    
    /* do we have to adapt clients winzsize now? */
    if (deferred_adapt_commands_window_size) {
      adapt_tty_winsize(STDIN_FILENO, master_pty_fd);
      kill(-command_pid, SIGWINCH);
      deferred_adapt_commands_window_size = FALSE;
    }


    
    /*OK, now feed line to underlying command and wait for the echo to come back */
    put_in_output_queue(filtered_line);
    DPRINTF2(DEBUG_READLINE, "putting %d bytes %s in output queue", (int) strlen(rewritten_line),
             mangle_string_for_debug_log(rewritten_line, 40));
    write_EOL_to_master_pty(return_key ? &return_key : "\n");

    accepted_lines++;
    free_foreign(line);         /* free_foreign because line was malloc'ed by readline, not by rlwrap */
    free(filtered_line);        /* we're done with them  */
        
    return_key = 0;
    within_line_edit = FALSE;
    if(!RL_ISSTATE(RL_STATE_MACROINPUT)) /* when called during playback of a multi-line macro, line_handler() will be called more 
                                            than once whithout re-entering main_loop(). If we'd remove it here, the second call
                                            would crash  */ 
       rl_callback_handler_remove();
    set_echo(FALSE);
    free(saved_rl_state.input_buffer);
    free(saved_rl_state.raw_prompt);
    free(saved_rl_state.cooked_prompt); 
    
    saved_rl_state.input_buffer = mysavestring("");
    saved_rl_state.raw_prompt = mysavestring("");
    saved_rl_state.cooked_prompt = NULL;
    saved_rl_state.point = 0;
    saved_rl_state.already_saved = TRUE;
    redisplay  = TRUE;

    if (one_shot_rlwrap)
      write_EOF_to_master_pty();
  }
}
Пример #21
0
static int
munge_line_in_editor(int count, int key)
{
  int line_number = 0, column_number = 0, tmpfile_OK, ret, tmpfile_fd, bytes_read;
  size_t tmpfilesize;
  char *p, *tmpdir, *tmpfilename, *text_to_edit;
  char *editor_command1, *editor_command2, *editor_command3, *editor_command4,
    *line_number_as_string, *column_number_as_string;
  char *input, *rewritten_input, *rewritten_input2, **possible_tmpdirs, **possible_editor_commands;


  if (!multiline_separator)
    return 0;

  possible_tmpdirs = list4(getenv("TMPDIR"), getenv("TMP"), getenv("TEMP"), "/tmp");
  possible_editor_commands = list4(getenv("RLWRAP_EDITOR"), getenv("EDITOR"), getenv("VISUAL"), "vi +%L");

  /* create temporary filename */
#ifdef HAVE_MKSTEMP
  tmpdir = first_of(possible_tmpdirs);
  tmpfilename = add3strings(tmpdir, "/rlwrap_", "XXXXXX");
  tmpfile_OK = mkstemp(tmpfilename);
#else
  tmpfilename = mymalloc(L_tmpnam);
  tmpfile_OK = (int)tmpnam(tmpfilename); /* manpage says: Never use this function. Use mkstemp(3) instead */
#endif
  if (!tmpfile_OK)
    myerror("could not find unique temporary file name");

  /* write current input to it, replacing the newline substitute (multiline_separator) with the real thing */
  tmpfile_fd = open(tmpfilename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
  if (tmpfile_fd < 0)
    myerror("could not create temporary file %s", tmpfilename);
  text_to_edit =
    search_and_replace(multiline_separator, "\n", rl_line_buffer, rl_point,
                       &line_number, &column_number);
  write_patiently(tmpfile_fd, text_to_edit, strlen(text_to_edit), "to temporary file");

  if (close(tmpfile_fd) != 0) /* improbable */
    myerror("couldn't close temporary file %s", tmpfilename); 

  /* find out which editor command we have to use */

  editor_command1 = first_of(possible_editor_commands);
  line_number_as_string = as_string(line_number);
  column_number_as_string = as_string(column_number);
  editor_command2 =
    search_and_replace("%L", line_number_as_string, editor_command1, 0, NULL,
                       NULL);
  editor_command3 =
    search_and_replace("%C", column_number_as_string, editor_command2, 0,
                       NULL, NULL);
  editor_command4 = add3strings(editor_command3, " ", tmpfilename);

  
  
  

  /* call editor, temporarily restoring terminal settings */    
  if (terminal_settings_saved && (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_terminal_settings) < 0))    /* reset terminal */
    myerror("tcsetattr error on stdin");
  DPRINTF1(DEBUG_READLINE, "calling %s", editor_command4);
  if ((ret = system(editor_command4))) {
    if (WIFSIGNALED(ret)) {
      fprintf(stderr, "\n"); errno = 0;
      myerror("editor killed by signal");
    } else {    
      myerror("failed to invoke editor with '%s'", editor_command4);
    }
  }
  completely_mirror_slaves_terminal_settings();
  ignore_queued_input = TRUE;  

  /* read back edited input, replacing real newline with substitute */
  tmpfile_fd = open(tmpfilename, O_RDONLY);
  if (tmpfile_fd < 0)
    myerror("could not read temp file %s", tmpfilename);
  tmpfilesize = filesize(tmpfilename);
  input = mymalloc(tmpfilesize + 1);
  bytes_read = read(tmpfile_fd, input, tmpfilesize);
  if (bytes_read < 0)
    myerror("unreadable temp file %s", tmpfilename);
  input[bytes_read] = '\0';
  rewritten_input = search_and_replace("\t", "    ", input, 0, NULL, NULL);     /* rlwrap cannot handle tabs in input lines */
  rewritten_input2 =
    search_and_replace("\n", multiline_separator, rewritten_input, 0, NULL,
                       NULL);
  for(p = rewritten_input2; *p ;p++)
    if(*p < ' ')
      *p = ' ';        /* replace all control characters (like \r) by spaces */


  rl_delete_text(0, strlen(rl_line_buffer));
  rl_point = 0;  
  clear_line();
  cr();
  my_putstr(saved_rl_state.cooked_prompt);
  rl_insert_text(rewritten_input2);
  rl_point = 0;                 /* leave cursor on predictable place */
  rl_done = 1;                  /* accept line immediately */

  


  /* wash those dishes */
  if (unlink(tmpfilename))
    myerror("could not delete temporary file %s", tmpfilename);
  free(editor_command2);
  free(editor_command3);
  free(editor_command4);
  free(line_number_as_string);
  free(column_number_as_string);
  free(tmpfilename);
  free(text_to_edit);
  free(input);
  free(rewritten_input);
  free(rewritten_input2);
  
  return_key = (char)'\n';
  return 0;
}
Пример #22
0
static int
munge_line_in_editor(int count, int key)
{
  int line_number = 0, column_number = 0,  ret, tmpfile_fd, bytes_read;
  size_t tmpfilesize;
  char *p, *tmpfilename, *text_to_edit;
  char *editor_command1, *editor_command2, *editor_command3, *editor_command4,
    *line_number_as_string, *column_number_as_string;
  char *input, *rewritten_input, *rewritten_input2,  **possible_editor_commands;


  if (!multiline_separator)
    return 0;

  tmpfile_fd = open_unique_tempfile(multi_line_tmpfile_ext, &tmpfilename);

  text_to_edit =
    search_and_replace(multiline_separator, "\n", rl_line_buffer, rl_point,
                       &line_number, &column_number);
  write_patiently(tmpfile_fd, text_to_edit, strlen(text_to_edit), "to temporary file");

  if (close(tmpfile_fd) != 0) /* improbable */
    myerror(FATAL|USE_ERRNO, "couldn't close temporary file %s", tmpfilename); 

  /* find out which editor command we have to use */
  possible_editor_commands = list4(getenv("RLWRAP_EDITOR"), getenv("EDITOR"), getenv("VISUAL"), "vi +%L");
  editor_command1 = first_of(possible_editor_commands);
  line_number_as_string = as_string(line_number);
  column_number_as_string = as_string(column_number);
  editor_command2 =
    search_and_replace("%L", line_number_as_string, editor_command1, 0, NULL,
                       NULL);
  editor_command3 =
    search_and_replace("%C", column_number_as_string, editor_command2, 0,
                       NULL, NULL);
  editor_command4 = add3strings(editor_command3, " ", tmpfilename);
  

  /* call editor, temporarily restoring terminal settings */    
  if (terminal_settings_saved && (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_terminal_settings) < 0))    /* reset terminal */
    myerror(FATAL|USE_ERRNO, "tcsetattr error on stdin");
  DPRINTF1(DEBUG_READLINE, "calling %s", editor_command4);
  if ((ret = system(editor_command4))) {
    if (WIFSIGNALED(ret)) {
      fprintf(stderr, "\n"); 
      myerror(FATAL|NOERRNO, "editor killed by signal");
    } else {    
      myerror(FATAL|USE_ERRNO, "failed to invoke editor with '%s'", editor_command4);
    }
  }
  completely_mirror_slaves_terminal_settings();
  ignore_queued_input = TRUE;  

  /* read back edited input, replacing real newline with substitute */
  tmpfile_fd = open(tmpfilename, O_RDONLY);
  if (tmpfile_fd < 0)
    myerror(FATAL|USE_ERRNO, "could not read temp file %s", tmpfilename);
  tmpfilesize = filesize(tmpfilename);
  input = mymalloc(tmpfilesize + 1);
  bytes_read = read(tmpfile_fd, input, tmpfilesize);
  if (bytes_read < 0)
    myerror(FATAL|USE_ERRNO, "unreadable temp file %s", tmpfilename);
  input[bytes_read] = '\0';
  rewritten_input = search_and_replace("\t", "    ", input, 0, NULL, NULL);     /* rlwrap cannot handle tabs in input lines */
  rewritten_input2 =
    search_and_replace("\n", multiline_separator, rewritten_input, 0, NULL, NULL);
  for(p = rewritten_input2; *p ;p++)
    if(*p >= 0 && *p < ' ') /* @@@FIXME: works for UTF8, but not UTF16 or UTF32 (Mention this in manpage?)*/ 
      *p = ' ';        /* replace all control characters (like \r) by spaces */


  rl_delete_text(0, strlen(rl_line_buffer));
  rl_point = 0;  
  clear_line();
  cr();
  my_putstr(saved_rl_state.cooked_prompt);
  rl_insert_text(rewritten_input2);
  rl_point = 0;                 /* leave cursor on predictable place */
  rl_done = 1;                  /* accept line immediately */

  


  /* wash those dishes */
  if (unlink(tmpfilename))
    myerror(FATAL|USE_ERRNO, "could not delete temporary file %s", tmpfilename);
  free(editor_command2);
  free(editor_command3);
  free(editor_command4);
  free(line_number_as_string);
  free(column_number_as_string);
  free(tmpfilename);
  free(text_to_edit);
  free(input);
  free(rewritten_input);
  free(rewritten_input2);
  
  return_key = (char)'\n';
  return 0;
}
Пример #23
0
//------------------------------------------------------------------------------
static int clear_line(int count, int invoking_key)
{
    rl_delete_text(0, rl_end);
    rl_point = 0;
    return 0;
}