/* Variables exported by this file. */
Keymap rl_binding_keymap;
+/* Functions exported by this file. */
+rl_macro_print_func_t *rl_macro_display_hook = (rl_macro_print_func_t *)NULL;
+
static int _rl_skip_to_delim (char *, int, int);
static void _rl_init_file_error (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
/* When there are incomplete prefixes \C- or \M- (has_control || has_meta)
without base character at the end of SEQ, they are processed as the
- prefixes for '\0'.
- */
+ prefixes for '\0'. */
for (i = l = 0; (c = seq[i]) || has_control || has_meta; i++)
{
/* Only backslashes followed by a non-null character are handled
has_meta = 0;
}
- /* If convert-meta is turned on, convert a meta char to a key sequence */
+ /* If convert-meta is turned on, convert a meta char to a key sequence */
if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
{
- array[l++] = ESC; /* ESC is meta-prefix */
- array[l++] = UNMETA (c);
+ int x = UNMETA (c);
+ if (x)
+ {
+ array[l++] = ESC; /* ESC is meta-prefix */
+ array[l++] = x;
+ }
+ else
+ array[l++] = c; /* just do the best we can without sticking a NUL in there. */
}
else
array[l++] = (c);
rl_untranslate_keyseq (int seq)
{
static char kseq[16];
- int i, c;
+ int i;
+ unsigned char c;
i = 0;
c = seq;
kseq[i++] = '-';
c = UNMETA (c);
}
- else if (c == ESC)
+
+ if (c == ESC)
{
kseq[i++] = '\\';
c = 'e';
}
- else if (CTRL_CHAR (c))
+ else if (CTRL_CHAR (c) || c == RUBOUT)
{
kseq[i++] = '\\';
kseq[i++] = 'C';
kseq[i++] = '-';
- c = _rl_to_lower (UNCTRL (c));
- }
- else if (c == RUBOUT)
- {
- kseq[i++] = '\\';
- kseq[i++] = 'C';
- kseq[i++] = '-';
- c = '?';
+ c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
}
- if (c == ESC)
- {
- kseq[i++] = '\\';
- c = 'e';
- }
- else if (c == '\\' || c == '"')
- {
- kseq[i++] = '\\';
- }
+ if (c == '\\' || c == '"')
+ kseq[i++] = '\\';
kseq[i++] = (unsigned char) c;
kseq[i] = '\0';
_rl_untranslate_macro_value (char *seq, int use_escapes)
{
char *ret, *r, *s;
- int c;
+ unsigned char c;
- r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
+ r = ret = (char *)xmalloc (8 * strlen (seq) + 1);
for (s = seq; *s; s++)
{
c = *s;
*r++ = '-';
c = UNMETA (c);
}
- else if (c == ESC)
+
+ /* We want to keep from printing literal control chars */
+ if (c == ESC)
{
*r++ = '\\';
c = 'e';
c = '?';
}
- if (c == ESC)
- {
- *r++ = '\\';
- c = 'e';
- }
- else if (c == '\\' || c == '"')
+ if (c == '\\' || c == '"')
*r++ = '\\';
- *r++ = (unsigned char)c;
+ *r++ = c;
}
*r = '\0';
return ret;
char *keyname;
int i, c;
- keyname = (char *)xmalloc (8);
+ keyname = (char *)xmalloc (9);
c = key;
/* Since this is going to be used to write out keysequence-function
pairs for possible inclusion in an inputrc file, we don't want to
do any special meta processing on KEY. */
-#if 1
- /* XXX - Experimental */
- /* We might want to do this, but the old version of the code did not. */
-
/* If this is an escape character, we don't want to do any more processing.
Just add the special ESC key sequence and return. */
if (c == ESC)
keyname[2] = '\0';
return keyname;
}
-#endif
- /* RUBOUT is translated directly into \C-? */
- if (key == RUBOUT)
+ if (key == ANYOTHERKEY)
{
- keyname[0] = '\\';
- keyname[1] = 'C';
- keyname[2] = '-';
- keyname[3] = '?';
- keyname[4] = '\0';
+ keyname[0] = '\0';
return keyname;
}
i = 0;
+
/* Now add special prefixes needed for control characters. This can
potentially change C. */
- if (CTRL_CHAR (c))
+ if (CTRL_CHAR (c) || c == RUBOUT)
{
keyname[i++] = '\\';
keyname[i++] = 'C';
keyname[i++] = '-';
- c = _rl_to_lower (UNCTRL (c));
+ c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
}
/* XXX experimental code. Turn the characters that are not ASCII or
{
char **seqs;
register int i;
+ char *keyname;
+ size_t knlen;
/* Find the list of keyseqs in this map which have FUNCTION as
their target. Add the key sequences found to RESULT. */
- if (map[key].function)
- seqs =
- rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
- else
+ if (map[key].function == 0)
break;
+ seqs = rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
if (seqs == 0)
break;
+ keyname = _rl_get_keyname (key);
+ knlen = RL_STRLEN (keyname);
+
for (i = 0; seqs[i]; i++)
{
- char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
-
- if (key == ESC)
- {
- /* 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
- {
- int c = key, l = 0;
- if (CTRL_CHAR (c) || c == RUBOUT)
- {
- keyname[l++] = '\\';
- keyname[l++] = 'C';
- keyname[l++] = '-';
- c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
- }
-
- if (c == '\\' || c == '"')
- keyname[l++] = '\\';
-
- keyname[l++] = (char) c;
- keyname[l++] = '\0';
- }
-
- strcat (keyname, seqs[i]);
- xfree (seqs[i]);
+ char *x;
if (result_index + 2 > result_size)
{
result = (char **)xrealloc (result, result_size * sizeof (char *));
}
- result[result_index++] = keyname;
+ x = xmalloc (knlen + RL_STRLEN (seqs[i]) + 1);
+ strcpy (x, keyname);
+ strcpy (x + knlen, seqs[i]);
+ xfree (seqs[i]);
+
+ result[result_index++] = x;
result[result_index] = (char *)NULL;
}
+ xfree (keyname);
xfree (seqs);
}
break;
return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
}
-/* Print all of the functions and their bindings to rl_outstream. If
- PRINT_READABLY is non-zero, then print the output in such a way
- that it can be read back in. */
void
-rl_function_dumper (int print_readably)
+rl_print_keybinding (const char *name, Keymap kmap, int print_readably)
{
- register int i;
- const char **names;
- const char *name;
+ rl_command_func_t *function;
+ char **invokers;
- names = rl_funmap_names ();
+ function = rl_named_function (name);
+ invokers = rl_invoking_keyseqs_in_map (function, kmap ? kmap : _rl_keymap);
- fprintf (rl_outstream, "\n");
-
- for (i = 0; name = names[i]; i++)
+ if (print_readably)
{
- rl_command_func_t *function;
- char **invokers;
-
- function = rl_named_function (name);
- invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
-
- if (print_readably)
+ if (!invokers)
+ fprintf (rl_outstream, "# %s (not bound)\n", name);
+ else
{
- if (!invokers)
- fprintf (rl_outstream, "# %s (not bound)\n", name);
- else
- {
- register int j;
-
- for (j = 0; invokers[j]; j++)
- {
- fprintf (rl_outstream, "\"%s\": %s\n",
- invokers[j], name);
- xfree (invokers[j]);
- }
+ register int j;
- xfree (invokers);
+ for (j = 0; invokers[j]; j++)
+ {
+ fprintf (rl_outstream, "\"%s\": %s\n", invokers[j], name);
+ xfree (invokers[j]);
}
+
+ xfree (invokers);
}
+ }
+ else
+ {
+ if (!invokers)
+ fprintf (rl_outstream, "%s is not bound to any keys\n", name);
else
{
- if (!invokers)
- fprintf (rl_outstream, "%s is not bound to any keys\n",
- name);
- else
- {
- register int j;
+ register int j;
- fprintf (rl_outstream, "%s can be found on ", name);
+ fprintf (rl_outstream, "%s can be found on ", name);
- for (j = 0; invokers[j] && j < 5; j++)
- {
- fprintf (rl_outstream, "\"%s\"%s", invokers[j],
- invokers[j + 1] ? ", " : ".\n");
- }
+ for (j = 0; invokers[j] && j < 5; j++)
+ fprintf (rl_outstream, "\"%s\"%s", invokers[j], invokers[j + 1] ? ", " : ".\n");
- if (j == 5 && invokers[j])
- fprintf (rl_outstream, "...\n");
+ if (j == 5 && invokers[j])
+ fprintf (rl_outstream, "...\n");
- for (j = 0; invokers[j]; j++)
- xfree (invokers[j]);
+ for (j = 0; invokers[j]; j++)
+ xfree (invokers[j]);
- xfree (invokers);
- }
+ xfree (invokers);
}
}
+}
+
+/* Print all of the functions and their bindings to rl_outstream. If
+ PRINT_READABLY is non-zero, then print the output in such a way
+ that it can be read back in. */
+void
+rl_function_dumper (int print_readably)
+{
+ register int i;
+ const char **names;
+ const char *name;
+
+ names = rl_funmap_names ();
+
+ fprintf (rl_outstream, "\n");
+
+ for (i = 0; name = names[i]; i++)
+ rl_print_keybinding (name, _rl_keymap, print_readably);
xfree (names);
}
keyname = _rl_get_keyname (key);
out = _rl_untranslate_macro_value ((char *)map[key].function, 0);
+ /* If the application wants to print macros, let it. Give it the
+ ascii-fied value with backslash escapes, so it will have to use
+ rl_macro_bind (with its call to rl_translate_keyseq) to get the
+ same value back. */
+ if (rl_macro_display_hook)
+ {
+ (*rl_macro_display_hook) (keyname, out, print_readably, prefix);
+ break;
+ }
+
if (print_readably)
fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
keyname,
static char *
_rl_get_string_variable_value (const char *name)
{
- static char numbuf[32];
+ static char numbuf[64];
char *ret;
- if (_rl_stricmp (name, "bell-style") == 0)
+ if (_rl_stricmp (name, "active-region-start-color") == 0)
+ {
+ if (_rl_active_region_start_color == 0)
+ return 0;
+ ret = _rl_untranslate_macro_value (_rl_active_region_start_color, 0);
+ if (ret)
+ {
+ strncpy (numbuf, ret, sizeof (numbuf) - 1);
+ xfree (ret);
+ numbuf[sizeof(numbuf) - 1] = '\0';
+ }
+ else
+ numbuf[0] = '\0';
+ return numbuf;
+ }
+ else if (_rl_stricmp (name, "active-region-end-color") == 0)
+ {
+ if (_rl_active_region_end_color == 0)
+ return 0;
+ ret = _rl_untranslate_macro_value (_rl_active_region_end_color, 0);
+ if (ret)
+ {
+ strncpy (numbuf, ret, sizeof (numbuf) - 1);
+ xfree (ret);
+ numbuf[sizeof(numbuf) - 1] = '\0';
+ }
+ else
+ numbuf[0] = '\0';
+ return numbuf;
+ }
+ else if (_rl_stricmp (name, "bell-style") == 0)
{
switch (_rl_bell_preference)
{
return (rl_get_keymap_name_from_edit_mode ());
else if (_rl_stricmp (name, "history-size") == 0)
{
- sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : 0);
+ sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : -1);
return (numbuf);
}
else if (_rl_stricmp (name, "isearch-terminators") == 0)
#define largest_char 255 /* Largest character value. */
#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
-#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
+#define META_CHAR(c) ((unsigned char)(c) > meta_character_threshold && (unsigned char)(c) <= largest_char)
#define CTRL(c) ((c) & control_character_mask)
#define META(c) ((c) | meta_character_bit)
char *
rl_username_completion_function (const char *text, int state)
{
-#if defined (_WIN32) || defined (__OPENNT)
+#if defined (_WIN32) || defined (__OPENNT) || !defined (HAVE_GETPWENT)
return (char *)NULL;
-#else /* !_WIN32 && !__OPENNT) */
+#else /* !_WIN32 && !__OPENNT) && HAVE_GETPWENT */
static char *username = (char *)NULL;
static struct passwd *entry;
static int namelen, first_char, first_char_loc;
username = savestring (&text[first_char_loc]);
namelen = strlen (username);
-#if defined (HAVE_GETPWENT)
setpwent ();
-#endif
}
-#if defined (HAVE_GETPWENT)
while (entry = getpwent ())
{
/* Null usernames should result in all users as possible completions. */
if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
break;
}
-#endif
if (entry == 0)
{
-#if defined (HAVE_GETPWENT)
endpwent ();
-#endif
return ((char *)NULL);
}
else
return (value);
}
-#endif /* !_WIN32 && !__OPENNT */
+#endif /* !_WIN32 && !__OPENNT && HAVE_GETPWENT */
}
/* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
}
filename_len = strlen (filename);
+ /* Normalize the filename if the application has set a rewrite hook. */
+ if (*filename && rl_filename_rewrite_hook)
+ {
+ temp = (*rl_filename_rewrite_hook) (filename, filename_len);
+ if (temp != filename)
+ {
+ xfree (filename);
+ filename = temp;
+ filename_len = strlen (filename);
+ }
+ }
+
rl_filename_completion_desired = 1;
}
if (filename_len == 0)
{
if (_rl_match_hidden_files == 0 && HIDDEN_FILE (convfn))
- continue;
+ {
+ if (convfn != dentry)
+ xfree (convfn);
+ continue;
+ }
if (convfn[0] != '.' ||
(convfn[1] && (convfn[1] != '.' || convfn[2])))
break;
}
- else
- {
- if (complete_fncmp (convfn, convlen, filename, filename_len))
- break;
- }
+ else if (complete_fncmp (convfn, convlen, filename, filename_len))
+ break;
+ else if (convfn != dentry)
+ xfree (convfn);
}
if (entry == 0)
char *prompt_this_line;
char cur_face;
int hl_begin, hl_end;
+ int short_circuit;
int mb_cur_max = MB_CUR_MAX;
#if defined (HANDLE_MULTIBYTE)
WCHAR_T wc;
norm_face (INV_LINE_FACE(linenum), INV_LLEN (linenum));
}
+ /* XXX - experimental new code */
+ /* Now that _rl_last_v_pos is a logical count, not bounded by the
+ number of physical screen lines, this is a start at being able
+ to redisplay lines that consume more than the number of physical
+ screen lines in more than a simple `move-to-the-next-line' way.
+
+ If the new line has more lines than there are physical screen
+ lines, and the cursor would be off the top of the screen if we
+ displayed all the new lines, clear the screen without killing
+ the scrollback buffer, clear out the visible line so we do a
+ complete redraw, and make the loop break when we have displayed
+ a physical screen full of lines. Do the same if we are going to
+ move the cursor to a line that's greater than the number of
+ physical screen lines when we weren't before.
+
+ SHORT_CIRCUIT says where to break the loop. Pretty simple right now. */
+ short_circuit = -1;
+ if (inv_botlin >= _rl_screenheight)
+ {
+ int extra;
+
+ extra = inv_botlin - _rl_screenheight; /* lines off the top */
+ /* cursor in portion of line that would be off screen or in
+ the lines that exceed the number of physical screen lines. */
+ if (cursor_linenum <= extra ||
+ (cursor_linenum >= _rl_screenheight && _rl_vis_botlin <= _rl_screenheight))
+ {
+ if (cursor_linenum <= extra)
+ short_circuit = _rl_screenheight;
+ _rl_clear_screen (0);
+ if (visible_line)
+ memset (visible_line, 0, line_size);
+ rl_on_new_line ();
+ }
+ /* The cursor is beyond the number of lines that would be off
+ the top, but we still want to display only the first
+ _RL_SCREENHEIGHT lines starting at the beginning of the line. */
+ else if (cursor_linenum > extra && cursor_linenum <= _rl_screenheight &&
+ _rl_vis_botlin <= _rl_screenheight)
+ short_circuit = _rl_screenheight;
+ }
+
/* For each line in the buffer, do the updating display. */
for (linenum = 0; linenum <= inv_botlin; linenum++)
{
+ if (short_circuit >= 0 && linenum == short_circuit)
+ break;
+
/* 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;
((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
}
}
- _rl_vis_botlin = inv_botlin;
+ _rl_vis_botlin = (short_circuit >= 0) ? short_circuit : inv_botlin;
/* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
different screen line during this redisplay. */
int
rl_forced_update_display (void)
{
- register char *temp;
-
if (visible_line)
memset (visible_line, 0, line_size);
{
register int delta, i;
- if (_rl_last_v_pos == to || to > _rl_screenheight)
+ if (_rl_last_v_pos == to)
return;
+#if 0
+ /* If we're being asked to move to a line beyond the screen height, and
+ we're currently at the last physical line, issue a newline and let the
+ terminal take care of scrolling the display. */
+ if (to >= _rl_screenheight)
+ {
+ if (_rl_last_v_pos == _rl_screenheight)
+ {
+ putc ('\n', rl_outstream);
+ _rl_cr ();
+ _rl_last_c_pos = 0;
+ }
+ return;
+ }
+#endif
+
if ((delta = to - _rl_last_v_pos) > 0)
{
for (i = 0; i < delta; i++)
If \fIstring\fP is missing, the string from the most recent search is used;
it is an error if there is no previous search string.
.TP
-.B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u
+.B \d\s+2\(ha\s-2\u\fIstring1\fP\d\s+2\(ha\s-2\u\fIstring2\fP\d\s+2\(ha\s-2\u
Quick substitution. Repeat the last command, replacing
.I string1
with
.IR string2 .
Equivalent to
-``!!:s\d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u''
+``!!:s\d\s+2\(ha\s-2\u\fIstring1\fP\d\s+2\(ha\s-2\u\fIstring2\fP\d\s+2\(ha\s-2\u''
(see \fBModifiers\fP below).
.TP
.B !#
.B :
separates the event specification from the word designator.
It may be omitted if the word designator begins with a
-.BR ^ ,
+.BR \(ha ,
.BR $ ,
.BR * ,
.BR \- ,
.I n
The \fIn\fRth word.
.TP
-.B ^
+.B \(ha
The first argument. That is, word 1.
.TP
.B $
.Fn1 int read_history "const char *filename"
Add the contents of \fIfilename\fP to the history list, a line at a time.
-If \fIfilename\fP is \fBNULL\fP, then read from \fI~/.history\fP.
+If \fIfilename\fP is \fBNULL\fP, then read from \fI\(ti/.history\fP.
Returns 0 if successful, or \fBerrno\fP if not.
.Fn3 int read_history_range "const char *filename" "int from" "int to"
Start reading at line \fIfrom\fP and end at \fIto\fP.
If \fIfrom\fP is zero, start at the beginning. If \fIto\fP is less than
\fIfrom\fP, then read until the end of the file. If \fIfilename\fP is
-\fBNULL\fP, then read from \fI~/.history\fP. Returns 0 if successful,
+\fBNULL\fP, then read from \fI\(ti/.history\fP. Returns 0 if successful,
or \fBerrno\fP if not.
.Fn1 int write_history "const char *filename"
Write the current history to \fIfilename\fP, overwriting \fIfilename\fP
if necessary.
-If \fIfilename\fP is \fBNULL\fP, then write the history list to \fI~/.history\fP.
+If \fIfilename\fP is \fBNULL\fP, then write the history list to \fI\(ti/.history\fP.
Returns 0 on success, or \fBerrno\fP on a read or write error.
.Fn2 int append_history "int nelements" "const char *filename"
Append the last \fInelements\fP of the history list to \fIfilename\fP.
-If \fIfilename\fP is \fBNULL\fP, then append to \fI~/.history\fP.
+If \fIfilename\fP is \fBNULL\fP, then append to \fI\(ti/.history\fP.
Returns 0 on success, or \fBerrno\fP on a read or write error.
.Fn2 int history_truncate_file "const char *filename" "int nlines"
Truncate the history file \fIfilename\fP, leaving only the last
\fInlines\fP lines.
-If \fIfilename\fP is \fBNULL\fP, then \fI~/.history\fP is truncated.
+If \fIfilename\fP is \fBNULL\fP, then \fI\(ti/.history\fP is truncated.
Returns 0 on success, or \fBerrno\fP on failure.
.SS History Expansion
.Vb char history_subst_char
The character that invokes word substitution if found at the start of
-a line. The default is \fB^\fP.
+a line. The default is \fB\(ha\fP.
.Vb char history_comment_char
During tokenization, if this character is seen as the first character
.SH FILES
.PD 0
.TP
-.FN ~/.history
+.FN \(ti/.history
Default filename for reading and writing saved history
.PD
.SH "SEE ALSO"
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
the lines are appended to the history file,
otherwise the history file is overwritten.
-If @env{HISTFILE}
-is unset, or if the history file is unwritable, the history is not saved.
+If @env{HISTFILE} is unset or null,
+or if the history file is unwritable, the history is not saved.
After saving the history, the history file is truncated
to contain no more than @env{$HISTFILESIZE} lines.
If @env{HISTFILESIZE} is unset, or set to null, a non-numeric value, or
comment character followed immediately by a digit are interpreted
as timestamps for the following history entry.
-The builtin command @code{fc} may be used to list or edit and re-execute
+The @code{fc} builtin command may be used to list or edit and re-execute
a portion of the history list.
The @code{history} builtin may be used to display or modify the history
list and manipulate the history file.
history list (@pxref{Commands For History}).
The shell allows control over which commands are saved on the history
-list. The @env{HISTCONTROL} and @env{HISTIGNORE}
-variables may be set to cause the shell to save only a subset of the
+list.
+The @env{HISTCONTROL} and @env{HISTIGNORE}
+variables are used to cause the shell to save only a subset of the
commands entered.
The @code{cmdhist}
shell option, if enabled, causes the shell to attempt to save each
when any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options
is used, Bash uses @var{filename} as the history file.
If not, then the value of the @env{HISTFILE} variable is used.
+If @env{HISTFILE} is unset or null, these options have no effect.
The return value is 0 unless an invalid option is encountered, an
error occurs while reading or writing the history file, an invalid
History expansion takes place in two parts. The first is to determine
which line from the history list should be used during substitution.
The second is to select portions of that line for inclusion into the
-current one. The line selected from the history is called the
-@dfn{event}, and the portions of that line that are acted upon are
-called @dfn{words}. Various @dfn{modifiers} are available to manipulate
-the selected words. The line is broken into words in the same fashion
+current one.
+
+The line selected from the history is called the @dfn{event},
+and the portions of that line that are acted upon are called @dfn{words}.
+The dfn{event designator} selects the event, the optional
+@dfn{word designator} selects words from the event, and
+various optional @dfn{modifiers} are available to manipulate the
+selected words.
+
+The line is broken into words in the same fashion
that Bash does, so that several words
surrounded by quotes are considered one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
+History expansions may appear anywhere in the input, but do not nest.
History expansion implements shell-like quoting conventions:
a backslash can be used to remove the special handling for the next character;
history list.
Unless the reference is absolute, events are relative to the current
position in the history list.
+The event designator consists of the portion of the word beginning
+with the history expansion character, and ending with the word designator
+if one is present, or the end of the word.
@cindex history events
@table @asis
@item @code{!}
@ifset BashFeatures
Start a history substitution, except when followed by a space, tab,
-the end of the line, @samp{=} or @samp{(} (when the
-@code{extglob} shell option is enabled using the @code{shopt} builtin).
+the end of the line, @samp{=},
+or the rest of the shell metacharacters defined above
+(@pxref{Definitions}).
@end ifset
@ifclear BashFeatures
Start a history substitution, except when followed by a space, tab,
@subsection Word Designators
Word designators are used to select desired words from the event.
+They are optional; if the word designator isn't supplied, the history
+expansion uses the entire event.
A @samp{:} separates the event specification from the word designator. It
may be omitted if the word designator begins with a @samp{^}, @samp{$},
@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Fri Feb 17 10:59:58 EST 2023
+.\" Last Change: Mon Jul 17 16:46:23 EDT 2023
.\"
-.TH READLINE 3 "2023 February 17" "GNU Readline 8.2"
+.TH READLINE 3 "2023 July 17" "GNU Readline 8.3"
.\"
.\" File Name macro. This used to be `.PN', for Path Name,
.\" but Sun doesn't seem to like that very much.
The name of this file is taken from the value of the
.B INPUTRC
environment variable. If that variable is unset, the default is
-.IR ~/.inputrc .
+.IR \(ti/.inputrc .
If that file does not exist or cannot be read, the ultimate default is
.IR /etc/inputrc .
When a program which uses the readline library starts up, the
.br
"\eC\-x\eC\-r": re\-read\-init\-file
.br
-"\ee[11~": "Function Key 1"
+"\ee[11\(ti": "Function Key 1"
.RE
.PP
In this example,
is bound to the function
.BR re\-read\-init\-file ,
and
-.I "ESC [ 1 1 ~"
+.I "ESC [ 1 1 \(ti"
is bound to insert the text
.if t \f(CWFunction Key 1\fP.
.if n ``Function Key 1''.
.TP
.B bind\-tty\-special\-chars (On)
If set to \fBOn\fP (the default), readline attempts to bind the control
-characters treated specially by the kernel's terminal driver to their
+characters that are
+treated specially by the kernel's terminal driver to their
readline equivalents.
+These override the default readline bindings described here.
+Type \f(CWstty -a\fP at a bash prompt to see your current terminal settings,
+including the special control characters (usually \fBcchars\fP).
.TP
.B blink\-matching\-paren (Off)
If set to \fBOn\fP, readline attempts to briefly move the cursor to an
.BR Bash ,
for instance, attempts completion treating the text as a variable
(if the text begins with \fB$\fP), username (if the text begins with
-\fB~\fP), hostname (if the text begins with \fB@\fP), or
+\fB\(ti\fP), hostname (if the text begins with \fB@\fP), or
command (including aliases and functions) in turn. If none
of these produces a match, filename completion is attempted.
.BR Gdb ,
"C-_" undo
"\^ " to "/" self-insert
"0" to "9" self-insert
-":" to "~" self-insert
+":" to "\(ti" self-insert
"C-?" backward-delete-char
.PP
Emacs Meta bindings
"M-U" upcase-word
"M-Y" yank-pop
"M-\e" delete-horizontal-space
-"M-~" tilde-expand
+"M-\(ti" tilde-expand
"M-C-?" backward-kill-word
"M-_" yank-last-arg
.PP
"C-Y" yank
"C-[" vi-movement-mode
"C-_" undo
-"\^ " to "~" self-insert
+"\^ " to "\(ti" self-insert
"C-?" backward-delete-char
.PP
VI Command Mode functions
"X" backward-delete-char
"Y" vi-yank-to
"\e" vi-complete
-"^" vi-first-print
+"\(ha" vi-first-print
"_" vi-yank-arg
"`" vi-goto-mark
"a" vi-append-mode
"x" vi-delete
"y" vi-yank-to
"|" vi-column
-"~" vi-change-case
+"\(ti" vi-change-case
.RE
.SH "SEE ALSO"
.PD 0
.SH FILES
.PD 0
.TP
-.FN ~/.inputrc
+.FN \(ti/.inputrc
Individual \fBreadline\fP initialization file
.PD
.SH AUTHORS
(@pxref{Terminal Management}).
@end deftypevar
+@deftypevar {void} rl_macro_display_hook
+If set, this points to a function that @code{rl_macro_dumper} will call to
+display a key sequence bound to a macro.
+It is called with the key sequence, the "untranslated" macro value (i.e.,
+with backslash escapes included, as when passed to @code{rl_macro_bind}),
+the @code{readable} argument passed to @code{rl_macro_dumper}, and any
+prefix to display before the key sequence.
+@end deftypevar
+
@deftypevar {Keymap} rl_executing_keymap
This variable is set to the keymap (@pxref{Keymaps}) in which the
currently executing Readline function was found.
invoke @var{function} in the keymap @var{map}.
@end deftypefun
+@deftypefun void rl_print_keybinding (const char *name, Keymap map, int readable)
+Print key sequences bound to Readline function name @var{name} in
+keymap @var{map}.
+If @var{map} is NULL, this uses the current keymap.
+If @var{readable} is non-zero,
+the list is formatted in such a way that it can be made part of an
+@code{inputrc} file and re-read.
+@end deftypefun
+
@deftypefun void rl_function_dumper (int readable)
Print the Readline function names and the key sequences currently
-bound to them to @code{rl_outstream}. If @var{readable} is non-zero,
+bound to them to @code{rl_outstream}.
+If @var{readable} is non-zero,
the list is formatted in such a way that it can be made part of an
@code{inputrc} file and re-read.
@end deftypefun
Bind the key sequence @var{keyseq} to invoke the macro @var{macro}.
The binding is performed in @var{map}. When @var{keyseq} is invoked, the
@var{macro} will be inserted into the line. This function is deprecated;
-use @code{rl_generic_bind()} instead.
+use @code{rl_generic_bind} instead.
@end deftypefun
@deftypefun void rl_macro_dumper (int readable)
Print the key sequences bound to macros and their values, using
the current keymap, to @code{rl_outstream}.
-If @var{readable} is non-zero, the list is formatted in such a way
+If the application has assigned a value to @code{rl_macro_display_hook},
+@code{rl_macro_dumper} calls it instead of printing anything.
+If @var{readable} is greater than zero, the list is formatted in such a way
that it can be made part of an @code{inputrc} file and re-read.
+
@end deftypefun
@deftypefun int rl_variable_bind (const char *variable, const char *value)
@item bind-tty-special-chars
@vindex bind-tty-special-chars
If set to @samp{on} (the default), Readline attempts to bind the control
-characters treated specially by the kernel's terminal driver to their
+characters that are
+treated specially by the kernel's terminal driver to their
Readline equivalents.
+These override the default Readline bindings described here.
+Type @samp{stty -a} at a Bash prompt to see your current terminal settings,
+including the special control characters (usually @code{cchars}).
@item blink-matching-paren
@vindex blink-matching-paren
If the insertion point is at the end of the line, this transposes
the last two words on the line.
+@ifset BashFeatures
+@item shell-transpose-words (M-C-t)
+Drag the word before point past the word after point,
+moving point past that word as well.
+If the insertion point is at the end of the line, this transposes
+the last two words on the line.
+Word boundaries are the same as @code{shell-forward-word} and
+@code{shell-backward-word}.
+@end ifset
+
@item upcase-word (M-u)
Uppercase the current (or following) word. With a negative argument,
uppercase the previous word, but do not move the cursor.
Word boundaries are the same as @code{shell-backward-word}.
@end ifset
-@item shell-transpose-words (M-C-t)
-Drag the word before point past the word after point,
-moving point past that word as well.
-If the insertion point is at the end of the line, this transposes
-the last two words on the line.
-Word boundaries are the same as @code{shell-forward-word} and
-@code{shell-backward-word}.
-
@item unix-word-rubout (C-w)
Kill the word behind point, using white space as a word boundary.
The killed text is saved on the kill-ring.
Copyright (C) 1988-2023 Free Software Foundation, Inc.
@end ignore
-@set EDITION 8.2
-@set VERSION 8.2
+@set EDITION 8.3
+@set VERSION 8.3
-@set UPDATED 15 June 2023
-@set UPDATED-MONTH June 2023
+@set UPDATED 31 July 2023
+@set UPDATED-MONTH July 2023
-@set LASTCHANGE Thu Jun 15 14:37:40 EDT 2023
+@set LASTCHANGE Mon Jul 31 10:09:09 EDT 2023
/* List the file(s) named in arg. */
int
-com_list (arg)
- char *arg;
+com_list (char *arg)
{
if (!arg)
arg = "";
}
int
-com_view (arg)
- char *arg;
+com_view (char *arg)
{
if (!valid_argument ("view", arg))
return 1;
}
int
-com_rename (arg)
- char *arg;
+com_rename (char *arg)
{
too_dangerous ("rename");
return (1);
}
int
-com_stat (arg)
- char *arg;
+com_stat (char *arg)
{
struct stat finfo;
}
int
-com_delete (arg)
- char *arg;
+com_delete (char *arg)
{
too_dangerous ("delete");
return (1);
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int
-com_help (arg)
- char *arg;
+com_help (char *arg)
{
register int i;
int printed = 0;
/* Change to the directory ARG. */
int
-com_cd (arg)
- char *arg;
+com_cd (char *arg)
{
if (chdir (arg) == -1)
{
/* Print out the current working directory. */
int
-com_pwd (ignore)
- char *ignore;
+com_pwd (char *ignore)
{
char dir[1024], *s;
/* The user wishes to quit using this program. Just set DONE non-zero. */
int
-com_quit (arg)
- char *arg;
+com_quit (char *arg)
{
done = 1;
return (0);
/* Function which tells you that you can't do this. */
void
-too_dangerous (caller)
- char *caller;
+too_dangerous (char *caller)
{
fprintf (stderr,
"%s: Too dangerous for me to distribute. Write it yourself.\n",
/* Return non-zero if ARG is a valid argument for CALLER, else print
an error message and return zero. */
int
-valid_argument (caller, arg)
- char *caller, *arg;
+valid_argument (char *caller, char *arg)
{
if (!arg || !*arg)
{
# codeset.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019 Free Software
+dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2022 Free Software
dnl Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
extern void rl_list_funmap_names (void);
extern char **rl_invoking_keyseqs_in_map (rl_command_func_t *, Keymap);
extern char **rl_invoking_keyseqs (rl_command_func_t *);
-
+
+extern void rl_print_keybinding (const char *, Keymap, int);
+
extern void rl_function_dumper (int);
extern void rl_macro_dumper (int);
extern void rl_variable_dumper (int);
extern rl_vintfunc_t *rl_prep_term_function;
extern rl_voidfunc_t *rl_deprep_term_function;
+extern rl_macro_print_func_t *rl_macro_display_hook;
+
/* Dispatch variables. */
extern Keymap rl_executing_keymap;
extern Keymap rl_binding_keymap;
typedef void rl_compdisp_func_t (char **, int, int);
+/* Functions for displaying key bindings. Currently only one. */
+typedef void rl_macro_print_func_t (const char *, const char *, int, const char *);
+
/* Type for input and pre-read hook functions like rl_event_hook */
typedef int rl_hook_func_t (void);