will eventually be split and we need to preserve the null to
produce an empty word. From a discussion on bug-bash started by
sunnycemetery@gmail.com
+
+ 2/22
+ ----
+bashline.c
+ - completion_glob_pattern: make sure to skip over a character quoted
+ by a backslash. Fixes bug reported by John Van Sickle
+ <john.vansickle@gmail.com>
+
+ 2/23
+ ----
+lib/readline/complete.c
+ - last_completion_failed: keep track of whether the last completion
+ attempt generated any matches
+ - rl_complete: if the last readline command was completion, but the
+ completion attempt didn't generate any matches, don't regenerate
+ and display the match list. Treat it as a new completion attempt.
+ Suggested by Richard Stallman <rms@gnu.org>
+
+bashhist.c
+ - maybe_append_history: try to handle the case where the number of
+ history entries in the current shell session is greater than the
+ number of entries in the history list. Based on a report from
+ <airat_vi@mail.ru>
tests/quote.right f
tests/quote1.sub f
tests/quote2.sub f
+tests/quote3.sub f
tests/read.tests f
tests/read.right f
tests/read1.sub f
maybe_append_history (filename)
char *filename;
{
- int fd, result;
+ int fd, result, histlen;
struct stat buf;
result = EXECUTION_SUCCESS;
- if (history_lines_this_session > 0 && (history_lines_this_session <= where_history ()))
+ if (history_lines_this_session > 0)
{
/* If the filename was supplied, then create it if necessary. */
if (stat (filename, &buf) == -1 && errno == ENOENT)
}
close (fd);
}
+ /* cap the number of lines we write at the length of the history list */
+ histlen = where_history ();
+ if (histlen > 0 && history_lines_this_session > histlen)
+ history_lines_this_session = histlen; /* reset below anyway */
result = append_history (history_lines_this_session, filename);
/* Pretend we already read these lines from the file because we just
added them */
continue;
case '\\':
- if (*string == 0)
+ if (*string++ == 0)
return (0);
}
/* Local variable states what happened during the last completion attempt. */
static int completion_changed_buffer;
+static int last_completion_failed = 0;
/* The result of the query to the user about displaying completion matches */
static int completion_y_or_n;
if (rl_inhibit_completion)
return (_rl_insert_char (ignore, invoking_key));
- else if (rl_last_func == rl_complete && !completion_changed_buffer)
+ else if (rl_last_func == rl_complete && completion_changed_buffer == 0 && last_completion_failed == 0)
return (rl_complete_internal ('?'));
else if (_rl_complete_show_all)
return (rl_complete_internal ('!'));
/* */
/************************************/
-/* Reset readline state on a signal or other event. */
+/* Reset public readline state on a signal or other event. */
void
_rl_reset_completion_state (void)
{
rl_ding ();
FREE (saved_line_buffer);
completion_changed_buffer = 0;
+ last_completion_failed = 1;
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
return (0);
rl_ding ();
FREE (saved_line_buffer);
completion_changed_buffer = 0;
+ last_completion_failed = 1;
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
return (0);
}
+ if (matches && matches[0] && *matches[0])
+ last_completion_failed = 0;
+
switch (what_to_do)
{
case TAB:
argv[1] = <>
argv[2] = <>
argv[1] = <>
+argv[1] = <4>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab ''>
+argv[1] = <ab >
+argv[1] = <ab ''>
+argv[1] = <ab >
${THIS_SH} ./quote1.sub
${THIS_SH} ./quote2.sub
+${THIS_SH} ./quote3.sub
--- /dev/null
+# new tests
+x=4
+sp=' '
+
+# word
+recho ${x}${sp}''
+
+# unquoted
+recho ${x+ab "$y"}
+recho ${x+ab ''}
+recho ${x+ab "$( : )"}
+recho ${x+ab "${yy}"}
+
+# quoted
+recho "${x+ab ''}"
+recho "${x+ab ""}"
+recho "${x+ab '${yy}'}"
+recho "${x+ab "${yy}"}"