diff options
Diffstat (limited to 'lib/readline')
34 files changed, 698 insertions, 302 deletions
diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 1a804b5..67d14d6 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -1,6 +1,6 @@ /* bind.c -- key binding and startup file support for the readline library. */ -/* Copyright (C) 1987-2005 Free Software Foundation, Inc. +/* Copyright (C) 1987-2006 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -370,7 +370,10 @@ rl_generic_bind (type, keyseq, data, map) ic = uc; if (ic < 0 || ic >= KEYMAP_SIZE) - return -1; + { + free (keys); + return -1; + } if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) { @@ -462,12 +465,21 @@ rl_translate_keyseq (seq, array, len) } else if (c == 'M') { - i++; - /* XXX - should obey convert-meta setting? */ + i++; /* seq[i] == '-' */ + /* XXX - obey convert-meta setting */ if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP) array[l++] = ESC; /* ESC is meta-prefix */ + else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-') + { + i += 4; + temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); + array[l++] = META (temp); + } else { + /* This doesn't yet handle things like \M-\a, which may + or may not have any reasonable meaning. You're + probably better off using straight octal or hex. */ i++; array[l++] = META (seq[i]); } @@ -565,6 +577,11 @@ rl_untranslate_keyseq (seq) kseq[i++] = '-'; c = UNMETA (c); } + else if (c == ESC) + { + kseq[i++] = '\\'; + c = 'e'; + } else if (CTRL_CHAR (c)) { kseq[i++] = '\\'; @@ -613,7 +630,12 @@ _rl_untranslate_macro_value (seq) *r++ = '-'; c = UNMETA (c); } - else if (CTRL_CHAR (c) && c != ESC) + else if (c == ESC) + { + *r++ = '\\'; + c = 'e'; + } + else if (CTRL_CHAR (c)) { *r++ = '\\'; *r++ = 'C'; @@ -672,7 +694,7 @@ rl_function_of_keyseq (keyseq, map, type) { register int i; - if (!map) + if (map == 0) map = _rl_keymap; for (i = 0; keyseq && keyseq[i]; i++) @@ -681,25 +703,27 @@ rl_function_of_keyseq (keyseq, map, type) if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) { - if (map[ESC].type != ISKMAP) + if (map[ESC].type == ISKMAP) + { + map = FUNCTION_TO_KEYMAP (map, ESC); + ic = UNMETA (ic); + } + /* XXX - should we just return NULL here, since this obviously + doesn't match? */ + else { if (type) *type = map[ESC].type; return (map[ESC].function); } - else - { - map = FUNCTION_TO_KEYMAP (map, ESC); - ic = UNMETA (ic); - } } if (map[ic].type == ISKMAP) { /* If this is the last key in the key sequence, return the map. */ - if (!keyseq[i + 1]) + if (keyseq[i + 1] == '\0') { if (type) *type = ISKMAP; @@ -709,7 +733,12 @@ rl_function_of_keyseq (keyseq, map, type) else map = FUNCTION_TO_KEYMAP (map, ic); } - else + /* If we're not at the end of the key sequence, and the current key + is bound to something other than a keymap, then the entire key + sequence is not bound. */ + else if (map[ic].type != ISKMAP && keyseq[i+1]) + return ((rl_command_func_t *)NULL); + else /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */ { if (type) *type = map[ic].type; @@ -793,7 +822,8 @@ rl_re_read_init_file (count, ignore) to the first non-null filename from this list: 1. the filename used for the previous call 2. the value of the shell variable `INPUTRC' - 3. /etc/inputrc and ~/.inputrc + 3. ~/.inputrc + 4. /etc/inputrc If the file existed and could be opened and read, 0 is returned, otherwise errno is returned. */ int @@ -802,34 +832,18 @@ rl_read_init_file (filename) { /* Default the filename. */ if (filename == 0) + filename = last_readline_init_file; + if (filename == 0) + filename = sh_get_env_value ("INPUTRC"); + if (filename == 0 || *filename == 0) { - filename = last_readline_init_file; - if (filename == 0) { - filename = sh_get_env_value ("INPUTRC"); - read_system_init_file = 0; - } - if (filename == 0) { - filename = DEFAULT_INPUTRC; - read_system_init_file = 1; - } + filename = DEFAULT_INPUTRC; + /* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */ + if (_rl_read_init_file (filename, 0) == 0) + return 0; + filename = SYS_INPUTRC; } - if (*filename == 0) { - filename = DEFAULT_INPUTRC; - read_system_init_file = 1; - } - - if (read_system_init_file) - if (filename == last_readline_init_file) - { - filename = savestring (filename); - _rl_read_init_file (SYSTEM_INPUTRC, 0); - free (last_readline_init_file); - last_readline_init_file = filename; - } - else - _rl_read_init_file (SYSTEM_INPUTRC, 0); - #if defined (__MSDOS__) if (_rl_read_init_file (filename, 0) == 0) return 0; @@ -1526,8 +1540,6 @@ rl_variable_value (name) const char *name; { register int i; - int v; - char *ret; /* Check for simple variables first. */ i = find_boolean_var (name); @@ -1968,12 +1980,16 @@ rl_invoking_keyseqs_in_map (function, map) char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); if (key == ESC) -#if 0 - sprintf (keyname, "\\e"); -#else - /* XXX - experimental */ - sprintf (keyname, "\\M-"); -#endif + { + /* If ESC is the meta prefix and we're converting chars + with the eighth bit set to ESC-prefixed sequences, then + we can use \M-. Otherwise we need to use the sequence + for ESC. */ + if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP) + sprintf (keyname, "\\M-"); + else + sprintf (keyname, "\\e"); + } else if (CTRL_CHAR (key)) sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key))); else if (key == RUBOUT) @@ -2190,7 +2206,6 @@ _rl_get_string_variable_value (name) { static char numbuf[32]; char *ret; - int n; if (_rl_stricmp (name, "bell-style") == 0) { diff --git a/lib/readline/callback.c b/lib/readline/callback.c index 9120969..ada04d8 100644 --- a/lib/readline/callback.c +++ b/lib/readline/callback.c @@ -43,6 +43,7 @@ #include "rldefs.h" #include "readline.h" #include "rlprivate.h" +#include "xmalloc.h" /* Private data for callback registration functions. See comments in rl_callback_read_char for more details. */ @@ -124,73 +125,73 @@ rl_callback_read_char () return; } - if (RL_ISSTATE (RL_STATE_ISEARCH)) + do { - eof = _rl_isearch_callback (_rl_iscxt); - if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) - rl_callback_read_char (); - - return; - } - else if (RL_ISSTATE (RL_STATE_NSEARCH)) - { - eof = _rl_nsearch_callback (_rl_nscxt); - return; - } - else if (RL_ISSTATE (RL_STATE_NUMERICARG)) - { - eof = _rl_arg_callback (_rl_argcxt); - if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) - rl_callback_read_char (); - /* XXX - this should handle _rl_last_command_was_kill better */ - else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) - _rl_internal_char_cleanup (); + if (RL_ISSTATE (RL_STATE_ISEARCH)) + { + eof = _rl_isearch_callback (_rl_iscxt); + if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) + rl_callback_read_char (); - return; - } - else if (RL_ISSTATE (RL_STATE_MULTIKEY)) - { - eof = _rl_dispatch_callback (_rl_kscxt); /* For now */ - while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED)) - eof = _rl_dispatch_callback (_rl_kscxt); - if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0) + return; + } + else if (RL_ISSTATE (RL_STATE_NSEARCH)) { - _rl_internal_char_cleanup (); - _rl_want_redisplay = 1; + eof = _rl_nsearch_callback (_rl_nscxt); + return; } - } - else if (_rl_callback_func) - { - /* This allows functions that simply need to read an additional character - (like quoted-insert) to register a function to be called when input is - available. _rl_callback_data is simply a pointer to a struct that has - the argument count originally passed to the registering function and - space for any additional parameters. */ - eof = (*_rl_callback_func) (_rl_callback_data); - /* If the function `deregisters' itself, make sure the data is cleaned - up. */ - if (_rl_callback_func == 0) + else if (RL_ISSTATE (RL_STATE_NUMERICARG)) + { + eof = _rl_arg_callback (_rl_argcxt); + if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) + rl_callback_read_char (); + /* XXX - this should handle _rl_last_command_was_kill better */ + else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) + _rl_internal_char_cleanup (); + + return; + } + else if (RL_ISSTATE (RL_STATE_MULTIKEY)) { - if (_rl_callback_data) + eof = _rl_dispatch_callback (_rl_kscxt); /* For now */ + while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED)) + eof = _rl_dispatch_callback (_rl_kscxt); + if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0) { - _rl_callback_data_dispose (_rl_callback_data); - _rl_callback_data = 0; + _rl_internal_char_cleanup (); + _rl_want_redisplay = 1; } - _rl_internal_char_cleanup (); } - } - else - eof = readline_internal_char (); + else if (_rl_callback_func) + { + /* This allows functions that simply need to read an additional + character (like quoted-insert) to register a function to be + called when input is available. _rl_callback_data is simply a + pointer to a struct that has the argument count originally + passed to the registering function and space for any additional + parameters. */ + eof = (*_rl_callback_func) (_rl_callback_data); + /* If the function `deregisters' itself, make sure the data is + cleaned up. */ + if (_rl_callback_func == 0) + { + if (_rl_callback_data) + { + _rl_callback_data_dispose (_rl_callback_data); + _rl_callback_data = 0; + } + _rl_internal_char_cleanup (); + } + } + else + eof = readline_internal_char (); - if (rl_done == 0 && _rl_want_redisplay) - { - (*rl_redisplay_function) (); - _rl_want_redisplay = 0; - } + if (rl_done == 0 && _rl_want_redisplay) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + } - /* We loop in case some function has pushed input back with rl_execute_next. */ - for (;;) - { if (rl_done) { line = readline_internal_teardown (eof); @@ -212,11 +213,8 @@ rl_callback_read_char () if (in_handler == 0 && rl_linefunc) _rl_callback_newline (); } - if (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)) - eof = readline_internal_char (); - else - break; } + while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)); } /* Remove the handler, and make sure the terminal is in its normal state. */ diff --git a/lib/readline/complete.c b/lib/readline/complete.c index d93c15a..73f834a 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -950,7 +950,7 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) rl_compentry_func_t *our_func; int found_quote, quote_char; { - char **matches, *temp; + char **matches; rl_completion_found_quote = found_quote; rl_completion_quote_character = quote_char; @@ -969,21 +969,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) } } - /* Beware -- we're stripping the quotes here. Do this only if we know - we are doing filename completion and the application has defined a - filename dequoting function. */ - temp = (char *)NULL; - - if (found_quote && our_func == rl_filename_completion_function && - rl_filename_dequoting_function) - { - /* delete single and double quotes */ - temp = (*rl_filename_dequoting_function) (text, quote_char); - text = temp; /* not freeing text is not a memory leak */ - } + /* XXX -- filename dequoting moved into rl_filename_completion_function */ matches = rl_completion_matches (text, our_func); - FREE (temp); return matches; } @@ -1116,7 +1104,8 @@ compute_lcd_of_matches (match_list, matches, text) #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - mbstate_t ps_back = ps1; + mbstate_t ps_back; + ps_back = ps1; if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2)) break; else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1) @@ -1974,13 +1963,30 @@ rl_filename_completion_function (text, state) if (rl_directory_rewrite_hook) (*rl_directory_rewrite_hook) (&dirname); + /* The directory completion hook should perform any necessary + dequoting. */ if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname)) { free (users_dirname); users_dirname = savestring (dirname); } - + else if (rl_completion_found_quote && rl_filename_dequoting_function) + { + /* delete single and double quotes */ + temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character); + free (users_dirname); + users_dirname = temp; + } directory = opendir (dirname); + + /* Now dequote a non-null filename. */ + if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function) + { + /* delete single and double quotes */ + temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character); + free (filename); + filename = temp; + } filename_len = strlen (filename); rl_filename_completion_desired = 1; diff --git a/lib/readline/display.c b/lib/readline/display.c index 0d3ae6e..47ff061 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -1,6 +1,6 @@ /* display.c -- readline redisplay facility. */ -/* Copyright (C) 1987-2005 Free Software Foundation, Inc. +/* Copyright (C) 1987-2006 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -59,10 +59,6 @@ extern char *strchr (), *strrchr (); #endif /* !strchr && !__STDC__ */ -#if defined (HACK_TERMCAP_MOTION) -extern char *_rl_term_forward_char; -#endif - static void update_line PARAMS((char *, char *, int, int, int, int)); static void space_to_eol PARAMS((int)); static void delete_chars PARAMS((int)); @@ -80,9 +76,18 @@ static int *inv_lbreaks, *vis_lbreaks; static int inv_lbsize, vis_lbsize; /* Heuristic used to decide whether it is faster to move from CUR to NEW - by backing up or outputting a carriage return and moving forward. */ + by backing up or outputting a carriage return and moving forward. CUR + and NEW are either both buffer positions or absolute screen positions. */ #define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new))) +/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a + buffer index in others. This macro is used when deciding whether the + current cursor position is in the middle of a prompt string containing + invisible characters. */ +#define PROMPT_ENDING_INDEX \ + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) + + /* **************************************************************** */ /* */ /* Display stuff */ @@ -135,6 +140,7 @@ int _rl_last_c_pos = 0; int _rl_last_v_pos = 0; static int cpos_adjusted; +static int cpos_buffer_position; /* Number of lines currently on screen minus 1. */ int _rl_vis_botlin = 0; @@ -162,6 +168,7 @@ static int line_size = 1024; include invisible characters. */ static char *local_prompt, *local_prompt_prefix; +static int local_prompt_len; static int prompt_visible_length, prompt_prefix_length; /* The number of invisible characters in the line currently being @@ -197,6 +204,7 @@ static char *saved_local_prefix; static int saved_last_invisible; static int saved_visible_length; static int saved_prefix_length; +static int saved_local_length; static int saved_invis_chars_first_line; static int saved_physical_chars; @@ -220,7 +228,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp) char *pmt; int *lp, *lip, *niflp, *vlp; { - char *r, *ret, *p; + char *r, *ret, *p, *igstart; int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; /* Short-circuit if we can. */ @@ -244,19 +252,21 @@ expand_prompt (pmt, lp, lip, niflp, vlp) invfl = 0; /* invisible chars in first line of prompt */ invflset = 0; /* we only want to set invfl once */ + igstart = 0; for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++) { /* This code strips the invisible character string markers RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ - if (*p == RL_PROMPT_START_IGNORE) + if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */ { - ignoring++; + ignoring = 1; + igstart = p; continue; } else if (ignoring && *p == RL_PROMPT_END_IGNORE) { ignoring = 0; - if (p[-1] != RL_PROMPT_START_IGNORE) + if (p != (igstart + 1)) last = r - ret - 1; continue; } @@ -356,6 +366,7 @@ rl_expand_prompt (prompt) FREE (local_prompt_prefix); local_prompt = local_prompt_prefix = (char *)0; + local_prompt_len = 0; prompt_last_invisible = prompt_invis_chars_first_line = 0; prompt_visible_length = prompt_physical_chars = 0; @@ -371,6 +382,7 @@ rl_expand_prompt (prompt) &prompt_invis_chars_first_line, &prompt_physical_chars); local_prompt_prefix = (char *)0; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; return (prompt_visible_length); } else @@ -389,6 +401,7 @@ rl_expand_prompt (prompt) &prompt_invis_chars_first_line, (int *)NULL); *t = c; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; return (prompt_prefix_length); } } @@ -445,7 +458,7 @@ rl_redisplay () { register int in, out, c, linenum, cursor_linenum; register char *line; - int c_pos, inv_botlin, lb_botlin, lb_linenum, o_cpos; + int inv_botlin, lb_botlin, lb_linenum, o_cpos; int newlines, lpos, temp, modmark, n0, num; char *prompt_this_line; #if defined (HANDLE_MULTIBYTE) @@ -469,7 +482,7 @@ rl_redisplay () } /* Draw the line into the buffer. */ - c_pos = -1; + cpos_buffer_position = -1; line = invisible_line; out = inv_botlin = 0; @@ -496,24 +509,23 @@ rl_redisplay () number of non-visible characters in the prompt string. */ if (rl_display_prompt == rl_prompt || local_prompt) { - int local_len = local_prompt ? strlen (local_prompt) : 0; if (local_prompt_prefix && forced_display) _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); - if (local_len > 0) + if (local_prompt_len > 0) { - temp = local_len + out + 2; + temp = local_prompt_len + out + 2; if (temp >= line_size) { line_size = (temp + 1024) - (temp % 1024); visible_line = (char *)xrealloc (visible_line, line_size); line = invisible_line = (char *)xrealloc (invisible_line, line_size); } - strncpy (line + out, local_prompt, local_len); - out += local_len; + strncpy (line + out, local_prompt, local_prompt_len); + out += local_prompt_len; } line[out] = '\0'; - wrap_offset = local_len - prompt_visible_length; + wrap_offset = local_prompt_len - prompt_visible_length; } else { @@ -614,6 +626,7 @@ rl_redisplay () contents of the command line? */ while (lpos >= _rl_screenwidth) { + int z; /* fix from Darin Johnson <darin@acuson.com> for prompt string with invisible characters that is longer than the screen width. The prompt_invis_chars_first_line variable could be made into an array @@ -622,37 +635,46 @@ rl_redisplay () prompts that exceed two physical lines? Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ #if defined (HANDLE_MULTIBYTE) - n0 = num; - temp = local_prompt ? strlen (local_prompt) : 0; - while (num < temp) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - if (_rl_col_width (local_prompt, n0, num) > _rl_screenwidth) + n0 = num; + temp = local_prompt_len; + while (num < temp) { - num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); - break; + z = _rl_col_width (local_prompt, n0, num); + if (z > _rl_screenwidth) + { + num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); + break; + } + else if (z == _rl_screenwidth) + break; + num++; } - num++; + temp = num; } - temp = num + -#else - temp = ((newlines + 1) * _rl_screenwidth) + + else #endif /* !HANDLE_MULTIBYTE */ - ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line - : ((newlines == 1) ? wrap_offset : 0)) - : ((newlines == 0) ? wrap_offset :0)); + temp = ((newlines + 1) * _rl_screenwidth); + + /* Now account for invisible characters in the current line. */ + temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line + : ((newlines == 1) ? wrap_offset : 0)) + : ((newlines == 0) ? wrap_offset :0)); inv_lbreaks[++newlines] = temp; #if defined (HANDLE_MULTIBYTE) - lpos -= _rl_col_width (local_prompt, n0, num); -#else - lpos -= _rl_screenwidth; + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + lpos -= _rl_col_width (local_prompt, n0, num); + else #endif + lpos -= _rl_screenwidth; } prompt_last_screen_line = newlines; /* Draw the rest of the line (after the prompt) into invisible_line, keeping - track of where the cursor is (c_pos), the number of the line containing + track of where the cursor is (cpos_buffer_position), the number of the line containing the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin). It maintains an array of line breaks for display (inv_lbreaks). This handles expanding tabs for display and displaying meta characters. */ @@ -705,7 +727,7 @@ rl_redisplay () if (in == rl_point) { - c_pos = out; + cpos_buffer_position = out; lb_linenum = newlines; } @@ -799,7 +821,7 @@ rl_redisplay () } if (in == rl_point) { - c_pos = out; + cpos_buffer_position = out; lb_linenum = newlines; } for (i = in; i < in+wc_bytes; i++) @@ -830,9 +852,9 @@ rl_redisplay () } line[out] = '\0'; - if (c_pos < 0) + if (cpos_buffer_position < 0) { - c_pos = out; + cpos_buffer_position = out; lb_linenum = newlines; } @@ -841,7 +863,7 @@ rl_redisplay () inv_lbreaks[newlines+1] = out; cursor_linenum = lb_linenum; - /* C_POS == position in buffer where cursor should be placed. + /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed. CURSOR_LINENUM == line number where the cursor should be placed. */ /* PWP: now is when things get a bit hairy. The visible and invisible @@ -886,6 +908,8 @@ rl_redisplay () /* For each line in the buffer, do the updating display. */ for (linenum = 0; linenum <= inv_botlin; linenum++) { + /* This can lead us astray if we execute a program that changes + the locale from a non-multibyte to a multibyte one. */ o_cpos = _rl_last_c_pos; cpos_adjusted = 0; update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, @@ -898,7 +922,11 @@ rl_redisplay () change update_line itself. There is one case in which update_line adjusts _rl_last_c_pos itself (so it can pass _rl_move_cursor_relative accurate values); it communicates - this back by setting cpos_adjusted */ + this back by setting cpos_adjusted. If we assume that + _rl_last_c_pos is correct (an absolute cursor position) each + time update_line is called, then we can assume in our + calculations that o_cpos does not need to be adjusted by + wrap_offset. */ if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && cpos_adjusted == 0 && _rl_last_c_pos != o_cpos && @@ -967,7 +995,11 @@ rl_redisplay () invisible character in the prompt string. */ nleft = prompt_visible_length + wrap_offset; if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && - _rl_last_c_pos <= prompt_last_invisible && local_prompt) +#if 0 + _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt) +#else + _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) +#endif { #if defined (__MSDOS__) putc ('\r', rl_outstream); @@ -986,8 +1018,8 @@ rl_redisplay () in the buffer? */ pos = inv_lbreaks[cursor_linenum]; /* nleft == number of characters in the line buffer between the - start of the line and the cursor position. */ - nleft = c_pos - pos; + start of the line and the desired cursor position. */ + nleft = cpos_buffer_position - pos; /* NLEFT is now a number of characters in a buffer. When in a multibyte locale, however, _rl_last_c_pos is an absolute cursor @@ -999,6 +1031,7 @@ rl_redisplay () those characters here and call _rl_backspace() directly. */ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) { + /* TX == new physical cursor position in multibyte locale. */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset; else @@ -1032,11 +1065,11 @@ rl_redisplay () will be LMARGIN. */ /* The number of characters that will be displayed before the cursor. */ - ndisp = c_pos - wrap_offset; + ndisp = cpos_buffer_position - wrap_offset; nleft = prompt_visible_length + wrap_offset; /* Where the new cursor position will be on the screen. This can be longer than SCREENWIDTH; if it is, lmargin will be adjusted. */ - phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset); + phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset); t = _rl_screenwidth / 3; /* If the number of characters had already exceeded the screenwidth, @@ -1047,7 +1080,7 @@ rl_redisplay () two-thirds of the way across the screen. */ if (phys_c_pos > _rl_screenwidth - 2) { - lmargin = c_pos - (2 * t); + lmargin = cpos_buffer_position - (2 * t); if (lmargin < 0) lmargin = 0; /* If the left margin would be in the middle of a prompt with @@ -1061,7 +1094,7 @@ rl_redisplay () { /* If we are moving back towards the beginning of the line and the last margin is no longer correct, compute a new one. */ - lmargin = ((c_pos - 1) / t) * t; /* XXX */ + lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */ if (wrap_offset && lmargin > 0 && lmargin < nleft) lmargin = nleft; } @@ -1106,7 +1139,7 @@ rl_redisplay () if (visible_first_line_len > _rl_screenwidth) visible_first_line_len = _rl_screenwidth; - _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]); + _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]); last_lmargin = lmargin; } } @@ -1164,7 +1197,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) int col_lendiff, col_temp; #if defined (HANDLE_MULTIBYTE) mbstate_t ps_new, ps_old; - int new_offset, old_offset, tmp; + int new_offset, old_offset; #endif /* If we're at the right edge of a terminal that supports xn, we're @@ -1397,11 +1430,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) sequences (like drawing the `unbold' sequence without a corresponding `bold') that manifests itself on certain terminals. */ - lendiff = local_prompt ? strlen (local_prompt) : 0; + lendiff = local_prompt_len; od = ofd - old; /* index of first difference in visible line */ if (current_line == 0 && !_rl_horizontal_scroll_mode && _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && - od >= lendiff && _rl_last_c_pos <= prompt_last_invisible) + od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX) { #if defined (__MSDOS__) putc ('\r', rl_outstream); @@ -1420,7 +1453,19 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) _rl_last_c_pos = lendiff; } + /* When this function returns, _rl_last_c_pos is correct, and an absolute + cursor postion in multibyte mode, but a buffer index when not in a + multibyte locale. */ _rl_move_cursor_relative (od, old); +#if 1 +#if defined (HANDLE_MULTIBYTE) + /* We need to indicate that the cursor position is correct in the presence of + invisible characters in the prompt string. Let's see if setting this when + we make sure we're at the end of the drawn prompt string works. */ + if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_last_c_pos == prompt_physical_chars) + cpos_adjusted = 1; +#endif +#endif /* if (len (new) > len (old)) lendiff == difference in buffer @@ -1648,10 +1693,11 @@ rl_on_new_line_with_prompt () int rl_forced_update_display () { + register char *temp; + if (visible_line) { - register char *temp = visible_line; - + temp = visible_line; while (*temp) *temp++ = '\0'; } @@ -1686,8 +1732,14 @@ _rl_move_cursor_relative (new, data) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { dpos = _rl_col_width (data, 0, new); - if (dpos > woff) - dpos -= woff; + if (dpos > prompt_last_invisible) /* XXX - don't use woff here */ + { + dpos -= woff; + /* Since this will be assigned to _rl_last_c_pos at the end (more + precisely, _rl_last_c_pos == dpos when this function returns), + let the caller know. */ + cpos_adjusted = 1; + } } else #endif @@ -1706,7 +1758,7 @@ _rl_move_cursor_relative (new, data) else #endif i = _rl_last_c_pos - woff; - if (new == 0 || CR_FASTER (new, _rl_last_c_pos) || + if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) || (_rl_term_autowrap && i == _rl_screenwidth)) { #if defined (__MSDOS__) @@ -1728,19 +1780,27 @@ _rl_move_cursor_relative (new, data) sequence telling the terminal to move forward one character. That kind of control is for people who don't know what the data is underneath the cursor. */ -#if defined (HACK_TERMCAP_MOTION) - if (_rl_term_forward_char) - { - for (i = cpos; i < dpos; i++) - tputs (_rl_term_forward_char, 1, _rl_output_character_function); - } - else -#endif /* HACK_TERMCAP_MOTION */ + + /* However, we need a handle on where the current display position is + in the buffer for the immediately preceding comment to be true. + In multibyte locales, we don't currently have that info available. + Without it, we don't know where the data we have to display begins + in the buffer and we have to go back to the beginning of the screen + line. In this case, we can use the terminal sequence to move forward + if it's available. */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - tputs (_rl_term_cr, 1, _rl_output_character_function); - for (i = 0; i < new; i++) - putc (data[i], rl_outstream); + if (_rl_term_forward_char) + { + for (i = cpos; i < dpos; i++) + tputs (_rl_term_forward_char, 1, _rl_output_character_function); + } + else + { + tputs (_rl_term_cr, 1, _rl_output_character_function); + for (i = 0; i < new; i++) + putc (data[i], rl_outstream); + } } else for (i = cpos; i < new; i++) @@ -1889,6 +1949,7 @@ rl_message (va_alist) &prompt_invis_chars_first_line, &prompt_physical_chars); local_prompt_prefix = (char *)NULL; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; (*rl_redisplay_function) (); return 0; @@ -1912,6 +1973,7 @@ rl_message (format, arg1, arg2) &prompt_invis_chars_first_line, &prompt_physical_chars); local_prompt_prefix = (char *)NULL; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; (*rl_redisplay_function) (); return 0; @@ -1948,12 +2010,14 @@ rl_save_prompt () saved_local_prompt = local_prompt; saved_local_prefix = local_prompt_prefix; saved_prefix_length = prompt_prefix_length; + saved_local_length = local_prompt_len; saved_last_invisible = prompt_last_invisible; saved_visible_length = prompt_visible_length; saved_invis_chars_first_line = prompt_invis_chars_first_line; saved_physical_chars = prompt_physical_chars; local_prompt = local_prompt_prefix = (char *)0; + local_prompt_len = 0; prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; prompt_invis_chars_first_line = prompt_physical_chars = 0; } @@ -1966,6 +2030,7 @@ rl_restore_prompt () local_prompt = saved_local_prompt; local_prompt_prefix = saved_local_prefix; + local_prompt_len = saved_local_length; prompt_prefix_length = saved_prefix_length; prompt_last_invisible = saved_last_invisible; prompt_visible_length = saved_visible_length; @@ -1974,6 +2039,7 @@ rl_restore_prompt () /* can test saved_local_prompt to see if prompt info has been saved. */ saved_local_prompt = saved_local_prefix = (char *)0; + saved_local_length = 0; saved_last_invisible = saved_visible_length = saved_prefix_length = 0; saved_invis_chars_first_line = saved_physical_chars = 0; } @@ -2162,7 +2228,8 @@ _rl_update_final () char *last_line; last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; - _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); + cpos_buffer_position = -1; /* don't know where we are in buffer */ + _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */ _rl_clear_to_eol (0); putc (last_line[_rl_screenwidth - 1], rl_outstream); } @@ -2205,6 +2272,7 @@ redraw_prompt (t) &prompt_invis_chars_first_line, &prompt_physical_chars); local_prompt_prefix = (char *)NULL; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; rl_forced_update_display (); @@ -2307,12 +2375,14 @@ _rl_col_width (str, start, end) int start, end; { wchar_t wc; - mbstate_t ps = {0}; + mbstate_t ps; int tmp, point, width, max; if (end <= start) return 0; + memset (&ps, 0, sizeof (mbstate_t)); + point = 0; max = end; diff --git a/lib/readline/doc/history.texi b/lib/readline/doc/history.texi index f6a3d20..1af40c7 100644 --- a/lib/readline/doc/history.texi +++ b/lib/readline/doc/history.texi @@ -14,7 +14,7 @@ This document describes the GNU History library a programming tool that provides a consistent user interface for recalling lines of previously typed input. -Copyright @copyright{} 1988-2004 Free Software Foundation, Inc. +Copyright @copyright{} 1988-2006 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -22,7 +22,7 @@ are preserved on all copies. @quotation Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 or +under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' and with the Back-Cover Texts as in (a) below. A copy of the license is diff --git a/lib/readline/doc/hstech.texi b/lib/readline/doc/hstech.texi index 4fdda5f..47ba8a5 100644 --- a/lib/readline/doc/hstech.texi +++ b/lib/readline/doc/hstech.texi @@ -1,7 +1,7 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988-2002 Free Software Foundation, Inc. +Copyright (C) 1988-2006 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual diff --git a/lib/readline/doc/hsuser.texi b/lib/readline/doc/hsuser.texi index 6c89183..f98983b 100644 --- a/lib/readline/doc/hsuser.texi +++ b/lib/readline/doc/hsuser.texi @@ -1,7 +1,7 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988-2002 Free Software Foundation, Inc. +Copyright (C) 1988-2006 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual diff --git a/lib/readline/doc/rlman.texi b/lib/readline/doc/rlman.texi index f834b58..e14c655 100644 --- a/lib/readline/doc/rlman.texi +++ b/lib/readline/doc/rlman.texi @@ -14,7 +14,7 @@ This manual describes the GNU Readline Library consistency of user interface across discrete programs which provide a command line interface. -Copyright @copyright{} 1988-2004 Free Software Foundation, Inc. +Copyright @copyright{} 1988-2006 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -22,7 +22,7 @@ are preserved on all copies. @quotation Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 or +under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' and with the Back-Cover Texts as in (a) below. A copy of the license is diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index 6f2e2ee..ecff106 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -8,7 +8,7 @@ This document describes the GNU Readline Library, a utility for aiding in the consistency of user interface across discrete programs that need to provide a command line interface. -Copyright (C) 1988-2005 Free Software Foundation, Inc. +Copyright (C) 1988-2006 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -1033,8 +1033,10 @@ pending input has not already been read with @code{rl_read_key()}. @deftypefun int rl_set_keyboard_input_timeout (int u) While waiting for keyboard input in @code{rl_read_key()}, Readline will wait for @var{u} microseconds for input before calling any function -assigned to @code{rl_event_hook}. The default waiting period is -one-tenth of a second. Returns the old timeout value. +assigned to @code{rl_event_hook}. @var{u} must be greater than or equal +to zero (a zero-length timeout is equivalent to a poll). +The default waiting period is one-tenth of a second. +Returns the old timeout value. @end deftypefun @node Terminal Management @@ -1668,6 +1670,9 @@ the directory portion of the pathname the user typed. It returns an integer that should be non-zero if the function modifies its directory argument. It could be used to expand symbolic links or shell variables in pathnames. +At the least, even if no other expansion is performed, this function should +remove any quote characters from the directory name, because its result will +be passed directly to @code{opendir()}. @end deftypevar @deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index a689550..5c6467a 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -10,7 +10,7 @@ use these features. There is a document entitled "readline.texinfo" which contains both end-user and programmer documentation for the GNU Readline Library. -Copyright (C) 1988-2005 Free Software Foundation, Inc. +Copyright (C) 1988-2006 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. @@ -336,8 +336,9 @@ file is taken from the value of the shell variable @env{INPUTRC}. If @ifclear BashFeatures file is taken from the value of the environment variable @env{INPUTRC}. If @end ifclear -that variable is unset, Readline will read both @file{/etc/inputrc} and -@file{~/.inputrc}. +that variable is unset, the default is @file{~/.inputrc}. If that +file does not exist or cannot be read, the ultimate default is +@file{/etc/inputrc}. When a program which uses the Readline library starts up, the init file is read, and the key bindings are set. @@ -594,9 +595,11 @@ the command does. Once you know the name of the command, simply place on a line in the init file the name of the key you wish to bind the command to, a colon, and then the name of the -command. The name of the key -can be expressed in different ways, depending on what you find most -comfortable. +command. +There can be no space between the key name and the colon -- that will be +interpreted as part of the key name. +The name of the key can be expressed in different ways, depending on +what you find most comfortable. In addition to command names, readline allows keys to be bound to a string that is inserted when the key is pressed (a @var{macro}). diff --git a/lib/readline/doc/rluserman.texi b/lib/readline/doc/rluserman.texi index db80b31..086aa83 100644 --- a/lib/readline/doc/rluserman.texi +++ b/lib/readline/doc/rluserman.texi @@ -14,7 +14,7 @@ This manual describes the end user interface of the GNU Readline Library consistency of user interface across discrete programs which provide a command line interface. -Copyright @copyright{} 1988-2005 Free Software Foundation, Inc. +Copyright @copyright{} 1988-2006 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -22,7 +22,7 @@ are preserved on all copies. @quotation Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 or +under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' and with the Back-Cover Texts as in (a) below. A copy of the license is diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 99816bf..654e837 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -1,10 +1,10 @@ @ignore -Copyright (C) 1988-2005 Free Software Foundation, Inc. +Copyright (C) 1988-2006 Free Software Foundation, Inc. @end ignore -@set EDITION 5.1-beta1 -@set VERSION 5.1-beta1 -@set UPDATED 11 November 2005 -@set UPDATED-MONTH November 2005 +@set EDITION 5.2 +@set VERSION 5.2 +@set UPDATED 26 April 2006 +@set UPDATED-MONTH April 2006 -@set LASTCHANGE Fri Nov 11 19:50:51 EST 2005 +@set LASTCHANGE Wed Apr 26 09:22:57 EDT 2006 diff --git a/lib/readline/examples/excallback.c b/lib/readline/examples/excallback.c index 3d4bb18..385492b 100644 --- a/lib/readline/examples/excallback.c +++ b/lib/readline/examples/excallback.c @@ -32,6 +32,9 @@ Let me know what you think. Jeff */ +/* +Copyright (C) 1999 Jeff Solomon +*/ #if defined (HAVE_CONFIG_H) #include <config.h> diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c index 6847014..f46c0b2 100644 --- a/lib/readline/histexpand.c +++ b/lib/readline/histexpand.c @@ -56,8 +56,6 @@ typedef int _hist_search_func_t PARAMS((const char *, int)); -extern int rl_byte_oriented; /* declared in mbutil.c */ - static char error_pointer; static char *subst_lhs; @@ -564,12 +562,12 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - int c, l; + int ch, l; l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY); - c = string[l]; + ch = string[l]; /* XXX - original patch had i - 1 ??? If i == 0 it would fail. */ - if (i && (c == '\'' || c == '"')) - quoted_search_delimiter = c; + if (i && (ch == '\'' || ch == '"')) + quoted_search_delimiter = ch; } else #endif /* HANDLE_MULTIBYTE */ @@ -1430,6 +1428,8 @@ history_tokenize_word (string, ind) { if (peek == '<' && string[i + 2] == '-') i++; + else if (peek == '<' && string[i + 2] == '<') + i++; i += 2; return i; } diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c index 717bbee..2f051a3 100644 --- a/lib/readline/histfile.c +++ b/lib/readline/histfile.c @@ -256,7 +256,11 @@ read_history_range (filename, from, to) for (line_end = line_start; line_end < bufend; line_end++) if (*line_end == '\n') { - *line_end = '\0'; + /* Change to allow Windows-like \r\n end of line delimiter. */ + if (line_end > line_start && line_end[-1] == '\r') + line_end[-1] = '\0'; + else + *line_end = '\0'; if (*line_start) { diff --git a/lib/readline/history.c b/lib/readline/history.c index a538f91..1ccf4db 100644 --- a/lib/readline/history.c +++ b/lib/readline/history.c @@ -209,6 +209,22 @@ history_get (offset) : the_history[local_index]; } +HIST_ENTRY * +alloc_history_entry (string, ts) + char *string; + char *ts; +{ + HIST_ENTRY *temp; + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + + temp->line = string ? savestring (string) : string; + temp->data = (char *)NULL; + temp->timestamp = ts; + + return temp; +} + time_t history_get_time (hist) HIST_ENTRY *hist; @@ -290,11 +306,7 @@ add_history (string) } } - temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); - temp->line = savestring (string); - temp->data = (char *)NULL; - - temp->timestamp = hist_inittime (); + temp = alloc_history_entry (string, hist_inittime ()); the_history[history_length] = (HIST_ENTRY *)NULL; the_history[history_length - 1] = temp; @@ -328,6 +340,26 @@ free_history_entry (hist) free (hist); return (x); } + +HIST_ENTRY * +copy_history_entry (hist) + HIST_ENTRY *hist; +{ + HIST_ENTRY *ret; + char *ts; + + if (hist == 0) + return hist; + + ret = alloc_history_entry (hist->line, (char *)NULL); + + ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp; + ret->timestamp = ts; + + ret->data = hist->data; + + return ret; +} /* Make the history entry at WHICH have LINE and DATA. This returns the old entry so you can dispose of the data. In the case of an @@ -354,6 +386,51 @@ replace_history_entry (which, line, data) return (old_value); } +/* Replace the DATA in the specified history entries, replacing OLD with + NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace + all of the history entries where entry->data == OLD; WHICH == -2 means + to replace the `newest' history entry where entry->data == OLD; and + WHICH >= 0 means to replace that particular history entry's data, as + long as it matches OLD. */ +void +replace_history_data (which,old, new) + int which; + histdata_t *old, *new; +{ + HIST_ENTRY *entry; + register int i, last; + + if (which < -2 || which >= history_length || history_length == 0 || the_history == 0) + return; + + if (which >= 0) + { + entry = the_history[which]; + if (entry && entry->data == old) + entry->data = new; + return; + } + + last = -1; + for (i = 0; i < history_length; i++) + { + entry = the_history[i]; + if (entry == 0) + continue; + if (entry->data == old) + { + last = i; + if (which == -1) + entry->data = new; + } + } + if (which == -2 && last >= 0) + { + entry = the_history[last]; + entry->data = new; /* XXX - we don't check entry->old */ + } +} + /* Remove history element WHICH from the history. The removed element is returned to you so you can free the line, data, and containing structure. */ diff --git a/lib/readline/input.c b/lib/readline/input.c index 0ec507e..da5d771 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -179,6 +179,7 @@ rl_gather_tyi () struct timeval timeout; #endif + chars_avail = 0; tty = fileno (rl_instream); #if defined (HAVE_SELECT) @@ -220,6 +221,13 @@ rl_gather_tyi () } #endif /* O_NDELAY */ +#if defined (__MINGW32__) + /* Use getch/_kbhit to check for available console input, in the same way + that we read it normally. */ + chars_avail = isatty (tty) ? _kbhit () : 0; + result = 0; +#endif + /* If there's nothing available, don't waste time trying to read something. */ if (chars_avail <= 0) @@ -263,7 +271,7 @@ rl_set_keyboard_input_timeout (u) int o; o = _keyboard_input_timeout; - if (u > 0) + if (u >= 0) _keyboard_input_timeout = u; return (o); } @@ -305,6 +313,11 @@ _rl_input_available () #endif +#if defined (__MINGW32__) + if (isatty (tty)) + return (_kbhit ()); +#endif + return 0; } @@ -489,7 +502,7 @@ rl_getc (stream) this is simply an interrupted system call to read (). Otherwise, some error ocurred, also signifying EOF. */ if (errno != EINTR) - return (EOF); + return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); } } @@ -537,21 +550,21 @@ _rl_read_mbchar (mbchar, size) } /* Read a multibyte-character string whose first character is FIRST into - the buffer MB of length MBLEN. Returns the last character read, which + the buffer MB of length MLEN. Returns the last character read, which may be FIRST. Used by the search functions, among others. Very similar to _rl_read_mbchar. */ int -_rl_read_mbstring (first, mb, mblen) +_rl_read_mbstring (first, mb, mlen) int first; char *mb; - int mblen; + int mlen; { int i, c; mbstate_t ps; c = first; - memset (mb, 0, mblen); - for (i = 0; i < mblen; i++) + memset (mb, 0, mlen); + for (i = 0; i < mlen; i++) { mb[i] = (char)c; memset (&ps, 0, sizeof (mbstate_t)); diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index d7d8520..9f67bfc 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -68,8 +68,8 @@ static void _rl_isearch_fini PARAMS((_rl_search_cxt *)); static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); /* Last line found by the current incremental search, so we don't `find' - identical lines many times in a row. */ -static char *prev_line_found; + identical lines many times in a row. Now part of isearch context. */ +/* static char *prev_line_found; */ /* Last search string and its length. */ static char *last_isearch_string; diff --git a/lib/readline/kill.c b/lib/readline/kill.c index 1d3254c..031ddf4 100644 --- a/lib/readline/kill.c +++ b/lib/readline/kill.c @@ -582,6 +582,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip) if (!arg || !*arg) { rl_ding (); + FREE (arg); return -1; } diff --git a/lib/readline/macro.c b/lib/readline/macro.c index 2975bf1..00cd58d 100644 --- a/lib/readline/macro.c +++ b/lib/readline/macro.c @@ -113,7 +113,7 @@ _rl_next_macro_key () #if defined (READLINE_CALLBACKS) c = rl_executing_macro[executing_macro_index++]; - if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD) && rl_executing_macro[executing_macro_index] == 0) + if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0) _rl_pop_executing_macro (); return c; #else diff --git a/lib/readline/misc.c b/lib/readline/misc.c index d455832..94ecb25 100644 --- a/lib/readline/misc.c +++ b/lib/readline/misc.c @@ -212,6 +212,8 @@ rl_digit_loop () if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)) break; } + + return r; } /* Create a default argument. */ diff --git a/lib/readline/readline.c b/lib/readline/readline.c index 5eaaf47..c2b7400 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -49,6 +49,11 @@ #include <stdio.h> #include "posixjmp.h" +#include <errno.h> + +#if !defined (errno) +extern int errno; +#endif /* !errno */ /* System-specific feature definitions and include files. */ #include "rldefs.h" @@ -479,6 +484,20 @@ readline_internal_charloop () c = rl_read_key (); RL_UNSETSTATE(RL_STATE_READCMD); + /* look at input.c:rl_getc() for the circumstances under which this will + be returned; punt immediately on read error without converting it to + a newline. */ + if (c == READERR) + { +#if defined (READLINE_CALLBACKS) + RL_SETSTATE(RL_STATE_DONE); + return (rl_done = 1); +#else + eof_found = 1; + break; +#endif + } + /* EOF typed to a non-blank line is a <NL>. */ if (c == EOF && rl_end) c = NEWLINE; diff --git a/lib/readline/readline.h b/lib/readline/readline.h index fade6d4..b71bf98 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -40,9 +40,9 @@ extern "C" { #endif /* Hex-encoded Readline version number. */ -#define RL_READLINE_VERSION 0x0501 /* Readline 5.1 */ +#define RL_READLINE_VERSION 0x0502 /* Readline 5.2 */ #define RL_VERSION_MAJOR 5 -#define RL_VERSION_MINOR 1 +#define RL_VERSION_MINOR 2 /* Readline data structures. */ @@ -757,6 +757,10 @@ extern int rl_ignore_completion_duplicates; completion character will be inserted as any other. */ extern int rl_inhibit_completion; +/* Input error; can be returned by (*rl_getc_function) if readline is reading + a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */ +#define READERR (-2) + /* Definitions available for use by readline clients. */ #define RL_PROMPT_START_IGNORE '\001' #define RL_PROMPT_END_IGNORE '\002' diff --git a/lib/readline/rlconf.h b/lib/readline/rlconf.h index 090adb8..aa52b6d 100644 --- a/lib/readline/rlconf.h +++ b/lib/readline/rlconf.h @@ -37,10 +37,13 @@ /* Ugly but working hack for binding prefix meta. */ #define PREFIX_META_HACK -/* The final, last-ditch effort file name for an init file. */ +/* The next-to-last-ditch effort file name for a user-specific init file. */ #define DEFAULT_INPUTRC "~/.inputrc" #define SYSTEM_INPUTRC "/etc/inputrc" +/* The ultimate last-ditch filenname for an init file -- system-wide. */ +#define SYS_INPUTRC "/etc/inputrc" + /* If defined, expand tabs to spaces. */ #define DISPLAY_TABS diff --git a/lib/readline/rlmbutil.h b/lib/readline/rlmbutil.h index 11adacb..dd317e2 100644 --- a/lib/readline/rlmbutil.h +++ b/lib/readline/rlmbutil.h @@ -32,10 +32,19 @@ /* For platforms which support the ISO C amendement 1 functionality we support user defined character classes. */ /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ -#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) +#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H) # include <wchar.h> # include <wctype.h> -# if defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH) +# if defined (HAVE_ISWCTYPE) && \ + defined (HAVE_ISWLOWER) && \ + defined (HAVE_ISWUPPER) && \ + defined (HAVE_MBSRTOWCS) && \ + defined (HAVE_MBRTOWC) && \ + defined (HAVE_MBRLEN) && \ + defined (HAVE_TOWLOWER) && \ + defined (HAVE_TOWUPPER) && \ + defined (HAVE_WCHAR_T) && \ + defined (HAVE_WCWIDTH) /* system is supposed to support XPG5 */ # define HANDLE_MULTIBYTE 1 # endif diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index 1c216ea..64aa7bd 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -309,6 +309,10 @@ extern int _rl_char_search_internal PARAMS((int, int, int)); #endif extern int _rl_set_mark_at_pos PARAMS((int)); +/* undo.c */ +extern UNDO_LIST *_rl_copy_undo_entry PARAMS((UNDO_LIST *)); +extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *)); + /* util.c */ extern int _rl_abort_internal PARAMS((void)); extern char *_rl_strindex PARAMS((const char *, const char *)); @@ -404,6 +408,7 @@ extern char *_rl_term_up; extern char *_rl_term_dc; extern char *_rl_term_cr; extern char *_rl_term_IC; +extern char *_rl_term_forward_char; extern int _rl_screenheight; extern int _rl_screenwidth; extern int _rl_screenchars; diff --git a/lib/readline/rltty.c b/lib/readline/rltty.c index 9a0326e..0a570f8 100644 --- a/lib/readline/rltty.c +++ b/lib/readline/rltty.c @@ -933,7 +933,6 @@ rltty_set_default_bindings (kmap) #if !defined (NO_TTY_DRIVER) TIOTYPE ttybuff; int tty; - static int called = 0; tty = fileno (rl_instream); diff --git a/lib/readline/search.c b/lib/readline/search.c index 8013916..33cc4fc 100644 --- a/lib/readline/search.c +++ b/lib/readline/search.c @@ -70,7 +70,6 @@ static int rl_history_search_pos; static char *history_search_string; static int history_string_size; -static UNDO_LIST *noninc_saved_undo_list; static void make_history_line_current PARAMS((HIST_ENTRY *)); static int noninc_search_from_pos PARAMS((char *, int, int)); static int noninc_dosearch PARAMS((char *, int)); @@ -212,7 +211,7 @@ _rl_nsearch_init (dir, pchar) rl_end = rl_point = 0; p = _rl_make_prompt_for_search (pchar ? pchar : ':'); - rl_message (p, 0, 0); + rl_message ("%s", p, 0); free (p); RL_SETSTATE(RL_STATE_NSEARCH); diff --git a/lib/readline/signals.c b/lib/readline/signals.c index f344ed8..54f2a64 100644 --- a/lib/readline/signals.c +++ b/lib/readline/signals.c @@ -160,6 +160,7 @@ rl_signal_handler (sig) rl_cleanup_after_signal (); #if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&set); sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); sigdelset (&set, sig); #else /* !HAVE_POSIX_SIGNALS */ @@ -288,9 +289,44 @@ rl_set_signals () { sighandler_cxt dummy; SigHandler *oh; +#if defined (HAVE_POSIX_SIGNALS) + static int sigmask_set = 0; + static sigset_t bset, oset; +#endif + +#if defined (HAVE_POSIX_SIGNALS) + if (rl_catch_signals && sigmask_set == 0) + { + sigemptyset (&bset); + + sigaddset (&bset, SIGINT); + sigaddset (&bset, SIGINT); +#if defined (SIGQUIT) + sigaddset (&bset, SIGQUIT); +#endif +#if defined (SIGALRM) + sigaddset (&bset, SIGALRM); +#endif +#if defined (SIGTSTP) + sigaddset (&bset, SIGTSTP); +#endif +#if defined (SIGTTIN) + sigaddset (&bset, SIGTTIN); +#endif +#if defined (SIGTTOU) + sigaddset (&bset, SIGTTOU); +#endif + sigmask_set = 1; + } +#endif /* HAVE_POSIX_SIGNALS */ if (rl_catch_signals && signals_set_flag == 0) { +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&oset); + sigprocmask (SIG_BLOCK, &bset, &oset); +#endif + rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); #if defined (SIGQUIT) @@ -324,6 +360,10 @@ rl_set_signals () #endif /* SIGTTIN */ signals_set_flag = 1; + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); +#endif } #if defined (SIGWINCH) @@ -390,8 +430,8 @@ rl_cleanup_after_signal () _rl_clean_up_for_exit (); if (rl_deprep_term_function) (*rl_deprep_term_function) (); - rl_clear_signals (); rl_clear_pending_input (); + rl_clear_signals (); } /* Reset the terminal and readline state after a signal handler returns. */ diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c index eb72c19..547f6f5 100644 --- a/lib/readline/terminal.c +++ b/lib/readline/terminal.c @@ -1,6 +1,6 @@ /* terminal.c -- controlling the terminal with termcap. */ -/* Copyright (C) 1996-2005 Free Software Foundation, Inc. +/* Copyright (C) 1996-2006 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -66,10 +66,24 @@ #include "rlshell.h" #include "xmalloc.h" +#if defined (__MINGW32__) +# include <windows.h> +# include <wincon.h> + +static void _win_get_screensize PARAMS((int *, int *)); +#endif + +#if defined (__EMX__) +static void _emx_get_screensize PARAMS((int *, int *)); +#endif + #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) -int rl_prefer_env_winsize; +/* If the calling application sets this to a non-zero value, readline will + use the $LINES and $COLUMNS environment variables to set its idea of the + window size before interrogating the kernel. */ +int rl_prefer_env_winsize = 0; /* **************************************************************** */ /* */ @@ -111,9 +125,7 @@ char *_rl_term_IC; char *_rl_term_dc; char *_rl_term_DC; -#if defined (HACK_TERMCAP_MOTION) char *_rl_term_forward_char; -#endif /* HACK_TERMCAP_MOTION */ /* How to go up a line. */ char *_rl_term_up; @@ -184,6 +196,26 @@ _emx_get_screensize (swp, shp) } #endif +#if defined (__MINGW32__) +static void +_win_get_screensize (swp, shp) + int *swp, *shp; +{ + HANDLE hConOut; + CONSOLE_SCREEN_BUFFER_INFO scr; + + hConOut = GetStdHandle (STD_OUTPUT_HANDLE); + if (hConOut != INVALID_HANDLE_VALUE) + { + if (GetConsoleScreenBufferInfo (hConOut, &scr)) + { + *swp = scr.dwSize.X; + *shp = scr.srWindow.Bottom - scr.srWindow.Top + 1; + } + } +} +#endif + /* Get readline's idea of the screen size. TTY is a file descriptor open to the terminal. If IGNORE_ENV is true, we do not pay attention to the values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being @@ -208,7 +240,9 @@ _rl_get_screen_size (tty, ignore_env) #endif /* TIOCGWINSZ */ #if defined (__EMX__) - _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); + _emx_get_screensize (&wc, &wr); +#elif defined (__MINGW32__) + _win_get_screensize (&wc, &wr); #endif if (ignore_env || rl_prefer_env_winsize == 0) @@ -358,9 +392,7 @@ static struct _tc_string tc_strings[] = { "le", &_rl_term_backspace }, { "mm", &_rl_term_mm }, { "mo", &_rl_term_mo }, -#if defined (HACK_TERMCAP_MOTION) { "nd", &_rl_term_forward_char }, -#endif { "pc", &_rl_term_pc }, { "up", &_rl_term_up }, { "vb", &_rl_visible_bell }, @@ -457,9 +489,7 @@ _rl_init_terminal_io (terminal_name) _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL; _rl_term_mm = _rl_term_mo = (char *)NULL; _rl_term_ve = _rl_term_vs = (char *)NULL; -#if defined (HACK_TERMCAP_MOTION) - term_forward_char = (char *)NULL; -#endif + _rl_term_forward_char = (char *)NULL; _rl_terminal_can_insert = term_has_meta = 0; /* Reasonable defaults for tgoto(). Readline currently only uses diff --git a/lib/readline/text.c b/lib/readline/text.c index bb87604..399a48c 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -1071,6 +1071,8 @@ int rl_delete (count, key) int count, key; { + int xpoint; + if (count < 0) return (_rl_rubout_char (-count, key)); @@ -1082,21 +1084,19 @@ rl_delete (count, key) if (count > 1 || rl_explicit_arg) { - int orig_point = rl_point; + xpoint = rl_point; if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) rl_forward_char (count, key); else rl_forward_byte (count, key); - rl_kill_text (orig_point, rl_point); - rl_point = orig_point; + rl_kill_text (xpoint, rl_point); + rl_point = xpoint; } else { - int new_point; - - new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); - rl_delete_text (rl_point, new_point); + xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + rl_delete_text (rl_point, xpoint); } return 0; } @@ -1237,8 +1237,8 @@ rl_change_case (count, op) #if defined (HANDLE_MULTIBYTE) wchar_t wc, nwc; char mb[MB_LEN_MAX+1]; - int mblen, p; - mbstate_t ps; + int mlen; + mbstate_t mps; #endif start = rl_point; @@ -1255,7 +1255,7 @@ rl_change_case (count, op) SWAP (start, end); #if defined (HANDLE_MULTIBYTE) - memset (&ps, 0, sizeof (mbstate_t)); + memset (&mps, 0, sizeof (mbstate_t)); #endif /* We are going to modify some text, so let's prepare to undo it. */ @@ -1290,15 +1290,15 @@ rl_change_case (count, op) #if defined (HANDLE_MULTIBYTE) else { - mbrtowc (&wc, rl_line_buffer + start, end - start, &ps); + mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); if (nwc != wc) /* just skip unchanged characters */ { - mblen = wcrtomb (mb, nwc, &ps); - if (mblen > 0) - mb[mblen] = '\0'; + mlen = wcrtomb (mb, nwc, &mps); + if (mlen > 0) + mb[mlen] = '\0'; /* Assume the same width */ - strncpy (rl_line_buffer + start, mb, mblen); + strncpy (rl_line_buffer + start, mb, mlen); } } #endif diff --git a/lib/readline/tilde.c b/lib/readline/tilde.c index d757f7a..1b76c9f 100644 --- a/lib/readline/tilde.c +++ b/lib/readline/tilde.c @@ -404,17 +404,17 @@ tilde_expand_word (filename) free (expansion); } } - free (username); /* If we don't have a failure hook, or if the failure hook did not expand the tilde, return a copy of what we were passed. */ if (dirname == 0) dirname = savestring (filename); } +#if defined (HAVE_GETPWENT) else - { - free (username); - dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); - } + dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); +#endif + + free (username); #if defined (HAVE_GETPWENT) endpwent (); #endif diff --git a/lib/readline/undo.c b/lib/readline/undo.c index fedfa12..9d9bd25 100644 --- a/lib/readline/undo.c +++ b/lib/readline/undo.c @@ -1,7 +1,7 @@ /* readline.c -- a general facility for reading lines of input with emacs style editing and completion. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987, 1989, 1992, 2006 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -50,6 +50,8 @@ #include "rlprivate.h" #include "xmalloc.h" +extern void replace_history_data PARAMS((int, histdata_t *, histdata_t *)); + /* Non-zero tells rl_delete_text and rl_insert_text to not add to the undo list. */ int _rl_doing_an_undo = 0; @@ -66,19 +68,35 @@ UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; /* */ /* **************************************************************** */ -/* Remember how to undo something. Concatenate some undos if that - seems right. */ -void -rl_add_undo (what, start, end, text) +static UNDO_LIST * +alloc_undo_entry (what, start, end, text) enum undo_code what; int start, end; char *text; { - UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); + UNDO_LIST *temp; + + temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); temp->what = what; temp->start = start; temp->end = end; temp->text = text; + + temp->next = (UNDO_LIST *)NULL; + return temp; +} + +/* Remember how to undo something. Concatenate some undos if that + seems right. */ +void +rl_add_undo (what, start, end, text) + enum undo_code what; + int start, end; + char *text; +{ + UNDO_LIST *temp; + + temp = alloc_undo_entry (what, start, end, text); temp->next = rl_undo_list; rl_undo_list = temp; } @@ -87,9 +105,12 @@ rl_add_undo (what, start, end, text) void rl_free_undo_list () { + UNDO_LIST *release, *orig_list; + + orig_list = rl_undo_list; while (rl_undo_list) { - UNDO_LIST *release = rl_undo_list; + release = rl_undo_list; rl_undo_list = rl_undo_list->next; if (release->what == UNDO_DELETE) @@ -98,6 +119,43 @@ rl_free_undo_list () free (release); } rl_undo_list = (UNDO_LIST *)NULL; + replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL); +} + +UNDO_LIST * +_rl_copy_undo_entry (entry) + UNDO_LIST *entry; +{ + UNDO_LIST *new; + + new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL); + new->text = entry->text ? savestring (entry->text) : 0; + return new; +} + +UNDO_LIST * +_rl_copy_undo_list (head) + UNDO_LIST *head; +{ + UNDO_LIST *list, *new, *roving, *c; + + list = head; + new = 0; + while (list) + { + c = _rl_copy_undo_entry (list); + if (new == 0) + roving = new = c; + else + { + roving->next = c; + roving = roving->next; + } + list = list->next; + } + + roving->next = 0; + return new; } /* Undo the next thing in the list. Return 0 if there @@ -161,6 +219,8 @@ rl_do_undo () release = rl_undo_list; rl_undo_list = rl_undo_list->next; + replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list); + free (release); } while (waiting_for_begin); diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index ac5fd74..d0b7e33 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -109,12 +109,16 @@ static int vi_mark_chars['z' - 'a' + 1]; static void _rl_vi_stuff_insert PARAMS((int)); static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); +static void _rl_vi_backup PARAMS((void)); + static int _rl_vi_arg_dispatch PARAMS((int)); static int rl_digit_loop1 PARAMS((void)); static int _rl_vi_set_mark PARAMS((void)); static int _rl_vi_goto_mark PARAMS((void)); +static void _rl_vi_append_forward PARAMS((int)); + static int _rl_vi_callback_getchar PARAMS((char *, int)); #if defined (READLINE_CALLBACKS) @@ -205,7 +209,16 @@ rl_vi_redo (count, c) _rl_vi_stuff_insert (count); /* And back up point over the last character inserted. */ if (rl_point > 0) - rl_point--; + _rl_vi_backup (); + } + /* Ditto for redoing an insert with `a', but move forward a character first + like the `a' command does. */ + else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_append_forward ('a'); + _rl_vi_stuff_insert (count); + if (rl_point > 0) + _rl_vi_backup (); } else r = _rl_dispatch (_rl_vi_last_command, _rl_keymap); @@ -575,23 +588,32 @@ rl_vi_insert_beg (count, key) return (0); } -int -rl_vi_append_mode (count, key) - int count, key; +static void +_rl_vi_append_forward (key) + int key; { + int point; + if (rl_point < rl_end) { if (MB_CUR_MAX == 1 || rl_byte_oriented) rl_point++; else { - int point = rl_point; + point = rl_point; rl_forward_char (1, key); if (point == rl_point) rl_point = rl_end; } } - rl_vi_insertion_mode (1, key); +} + +int +rl_vi_append_mode (count, key) + int count, key; +{ + _rl_vi_append_forward (key); + rl_vi_start_inserting (key, 1, rl_arg_sign); return (0); } @@ -631,7 +653,7 @@ _rl_vi_save_insert (up) { int len, start, end; - if (up == 0) + if (up == 0 || up->what != UNDO_INSERT) { if (vi_insert_buffer_size >= 1) vi_insert_buffer[0] = '\0'; @@ -716,7 +738,7 @@ _rl_vi_change_mbchar_case (count) { wchar_t wc; char mb[MB_LEN_MAX+1]; - int mblen, p; + int mlen, p; mbstate_t ps; memset (&ps, 0, sizeof (mbstate_t)); @@ -740,9 +762,9 @@ _rl_vi_change_mbchar_case (count) if (wc) { p = rl_point; - mblen = wcrtomb (mb, wc, &ps); - if (mblen >= 0) - mb[mblen] = '\0'; + mlen = wcrtomb (mb, wc, &ps); + if (mlen >= 0) + mb[mlen] = '\0'; rl_begin_undo_group (); rl_vi_delete (1, 0); if (rl_point < p) /* Did we retreat at EOL? */ @@ -820,6 +842,15 @@ rl_vi_put (count, key) return (0); } +static void +_rl_vi_backup () +{ + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + else + rl_point--; +} + int rl_vi_check () { @@ -1111,7 +1142,7 @@ int rl_vi_rubout (count, key) int count, key; { - int p, opoint; + int opoint; if (count < 0) return (rl_vi_delete (-count, key)); @@ -1426,9 +1457,9 @@ _rl_vi_change_char (count, c, mb) } static int -_rl_vi_callback_getchar (mb, mblen) +_rl_vi_callback_getchar (mb, mlen) char *mb; - int mblen; + int mlen; { int c; @@ -1438,7 +1469,7 @@ _rl_vi_callback_getchar (mb, mblen) #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - c = _rl_read_mbstring (c, mb, mblen); + c = _rl_read_mbstring (c, mb, mlen); #endif return c; |