/* bashline.c -- Bash's interface to the readline library. */
-/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
rl_bind_key_if_unbound_in_map ('@', posix_edit_macros, vi_movement_keymap);
# endif
+ rl_add_defun ("bash-vi-complete", bash_vi_complete, -1);
rl_bind_key_in_map ('\\', bash_vi_complete, vi_movement_keymap);
rl_bind_key_in_map ('*', bash_vi_complete, vi_movement_keymap);
rl_bind_key_in_map ('=', bash_vi_complete, vi_movement_keymap);
char *temp, buffer[256], name[256];
register int i, start;
+#ifdef __MSYS__
+ file = fopen (filename, "rt");
+#else
file = fopen (filename, "r");
+#endif
if (file == 0)
return;
if (rl_explicit_arg)
{
- command = (char *)xmalloc (strlen (edit_command) + 8);
- sprintf (command, "%s %d", edit_command, count);
+ size_t clen;
+ /* 32 exceeds strlen (itos (INTMAX_MAX)) (19) */
+ clen = strlen (edit_command) + 32;
+ command = (char *)xmalloc (clen);
+ snprintf (command, clen, "%s %d", edit_command, count);
}
else
{
static inline int
check_redir (int ti)
{
- register int this_char, prev_char;
+ int this_char, prev_char, next_char;
/* Handle the two character tokens `>&', `<&', and `>|'.
We are not in a command position after one of these. */
this_char = rl_line_buffer[ti];
prev_char = (ti > 0) ? rl_line_buffer[ti - 1] : 0;
+ next_char = (ti < rl_end) ? rl_line_buffer[ti + 1] : 0;
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
(this_char == '|' && prev_char == '>'))
return (1);
- else if (this_char == '{' && prev_char == '$') /*}*/
+ else if (this_char == '{' && prev_char == '$' && FUNSUB_CHAR (next_char) == 0) /*}*/
return (1);
#if 0 /* Not yet */
else if (this_char == '(' && prev_char == '$') /*)*/
{
if (qc != '\'' && text[1] == '(') /* ) */
matches = rl_completion_matches (text, command_subst_completion_function);
+ else if (qc != '\'' && text[1] == '{' && FUNSUB_CHAR (text[2])) /* } */
+ matches = rl_completion_matches (text, command_subst_completion_function);
else
{
matches = rl_completion_matches (text, variable_completion_function);
text++;
else if (*text == '$' && text[1] == '(') /* ) */
text += 2;
+ else if (*text == '$' && text[1] == '{' && FUNSUB_CHAR (text[2])) /*}*/
+ text += 3; /* nofork command substitution */
/* If the text was quoted, suppress any quote character that the
readline completion code would insert. */
rl_completion_suppress_quote = 1;
int r;
fn = bash_tilde_expand (name, 0);
+
+#if __CYGWIN
+ /* stat("//server") can only be successful as a directory, but can take
+ seconds to time out on failure. It is much faster to assume that
+ "//server" is a valid name than it is to wait for a stat, even if it
+ gives false positives on bad names. */
+ if (fn[0] == '/' && fn[1] == '/' && ! strchr (&fn[2], '/'))
+ {
+ free (fn);
+ return 1;
+ }
+#endif
+
r = file_isdir (fn);
free (fn);
#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
#if defined (VI_MODE)
+/* This does pretty much what _rl_vi_advance_point does. */
+static inline int
+vi_advance_point (void)
+{
+ int point;
+ DECLARE_MBSTATE;
+
+ point = rl_point;
+ if (rl_point < rl_end)
+#if defined (HANDLE_MULTIBYTE)
+ {
+ if (locale_mb_cur_max == 1)
+ rl_point++;
+ else
+ {
+ point = rl_point;
+ ADVANCE_CHAR (rl_line_buffer, rl_end, rl_point);
+ if (point == rl_point || rl_point > rl_end)
+ rl_point = rl_end;
+ }
+ }
+#else
+ rl_point++:
+#endif
+ return point;
+}
+
/* Completion, from vi mode's point of view. This is a modified version of
rl_vi_complete which uses the bash globbing code to implement what POSIX
- specifies, which is to append a `*' and attempt filename generation (which
- has the side effect of expanding any globbing characters in the word). */
+ specifies, which is to optinally append a `*' and attempt filename
+ generation (which has the side effect of expanding any globbing characters
+ in the word). */
static int
bash_vi_complete (int count, int key)
{
{
if (!whitespace (rl_line_buffer[rl_point + 1]))
rl_vi_end_word (1, 'E');
- rl_point++;
+ vi_advance_point ();
}
/* Find boundaries of current word, according to vi definition of a