From: Chet Ramey Date: Fri, 23 Aug 2024 19:08:31 +0000 (-0400) Subject: add bindable readline variable `force-meta-prefix' to allow users to tell readline... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e01122fe78eb5a42c9b9f3ca46b91f895959675;p=thirdparty%2Fbash.git add bindable readline variable `force-meta-prefix' to allow users to tell readline how their Meta key works --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 630f37ab..2d9026cb 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -10043,3 +10043,30 @@ shell.c interactive shell in case it was set at invocation, but not in cases where it was forced with -i Report from Milana <94888u@riseup.net> + + 8/22 + ---- +lib/readline/bind.c + - force-meta-prefix: new bindable variable, used to determine whether + to convert a meta character (>= 0x80) to an escape-prefixed key + sequence (using ESC as the meta prefix). If set, do the conversion + unconditionally; if unset, use the value of convert-meta as in + previous bash/readline versions + Suggestion from Reuben Thomas + - _rl_function_of_keyseq_internal: if we encounter a character/byte + with the eighth bit set, use force-meta-prefix to decide whether + to translate it to an escape-prefixed key sequence + - rl_bind_key: if we have a meta character, assume it was generated by + Meta- and honor the setting of force-meta-prefix + - rl_translate_keyseq: if we have \M-, use force-meta-prefix to decide + whether or not to translate it to an escape-prefixed key sequence + +lib/readline/doc/rluser.texi,lib/readline/doc/readline.3,doc/bash.1 + - force-meta-prefix: document new bindable variable and defaults + - convert-meta, enable-meta-key, input-meta, output-meta: update + description with better explanation of Meta key and meta characters, + and locale character encoding + - Key Bindings: expand description of \M- and Meta- modifiers + - Readline Introduction: expand description of the Meta key and the + various things it can do, reference force-meta-prefix and + enable-meta-key diff --git a/doc/bash.1 b/doc/bash.1 index e8210085..d52c089f 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -5,14 +5,14 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Fri Aug 16 17:06:12 EDT 2024 +.\" Last Change: Fri Aug 23 09:09:35 EDT 2024 .\" .\" bash_builtins, strip all but Built-Ins section .\" avoid a warning about an undefined register .\" .if !rzY .nr zY 0 .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2024 August 16" "GNU Bash 5.3" +.TH BASH 1 "2024 August 23" "GNU Bash 5.3" .\" .ie \n(.g \{\ .ds ' \(aq @@ -5959,18 +5959,32 @@ Control keys are denoted by C\-\fIkey\fP, e.g., C\-n means Control\-N. Similarly, .I meta keys are denoted by M\-\fIkey\fP, so M\-x means Meta\-X. -(On keyboards without a -.I meta +.PP +On keyboards without a +.I Meta key, M\-\fIx\fP means ESC \fIx\fP, i.e., press the Escape key then the .I x -key. This makes ESC the \fImeta prefix\fP. +key. +This makes ESC the \fImeta prefix\fP. The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP, or press the Escape key then hold the Control key while pressing the .I x key.) .PP +On some keyboards, the Meta key modifier produces meta characters with +the eighth bit (0200) set (you can use the \fBenable\-meta\-key\fP variable +to control whether or not it does this, if the keyboard allows it). +On many others, the terminal or terminal emulator converts the metafied +key to a key sequence beginning with ESC as described in the +preceding paragraph. +.PP +If the \fIMeta\fP key produces a key sequence with the ESC meta prefix, +you can make M-\fIkey\fP key bindings you specify (see +.B "Readline Key Bindings" +below) do the same thing by setting the \fBforce\-meta\-prefix\fP variable. +.PP Readline commands may be given numeric .IR arguments , which normally act as a repeat count. @@ -6122,7 +6136,8 @@ The full set of GNU Emacs style escape sequences is control prefix .TP .B \eM\- -meta prefix +adding the meta prefix or converting the following character to a meta +character, as described below under \fBforce-meta-prefix\fP .TP .B \ee an escape character @@ -6343,14 +6358,17 @@ A zero value means readline should never ask; negative values are treated as zero. .TP .B convert\-meta (On) -If set to \fBOn\fP, readline will convert characters with the -eighth bit set to an ASCII key sequence -by stripping the eighth bit and prefixing an -escape character (in effect, using escape as the \fImeta prefix\fP). -The default is \fIOn\fP, but readline will set it to \fIOff\fP if the -locale contains eight-bit characters. +If set to \fBOn\fP, readline will convert characters it reads +with the eighth bit set to an ASCII key sequence +by stripping the eighth bit and prefixing it with an escape character +(converting the character to have the \fImeta prefix\fP). +The default is \fIOn\fP, but readline will set it to \fIOff\fP +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the \fBLC_CTYPE\fP locale category, and may change if the locale is changed. +This variable also affects key bindings; see the description of +\fBforce\-meta\-prefix\fP below. .TP .B disable\-completion (Off) If set to \fBOn\fP, readline will inhibit word completion. Completion @@ -6408,8 +6426,29 @@ arrow keys. .TP .B enable\-meta\-key (On) When set to \fBOn\fP, readline will try to enable any meta modifier -key the terminal claims to support when it is called. On many terminals, -the meta key is used to send eight-bit characters. +key the terminal claims to support when it is called. +On many terminals, the Meta key is used to send eight-bit characters; +this variable checks for the terminal capability that indicates the +terminal can enable and disable a mode that sets the eighth bit of a +character (0200) if the Meta key is held down when the character is +typed (a meta character). +.TP +.B force\-meta\-prefix (Off) +If set to \fBOn\fP, readline modifies its behavior when binding key +sequences containing \eM- or Meta- +(see \fBKey Bindings\fP above) by converting a key sequence of the form +\eM-\fIC\fP or Meta-\fIC\fP to the two-character sequence +\fBESC\fP\fIC\fP (adding the meta prefix). +If +.B force\-meta\-prefix +is set to \fBOff\fP (the default), +readline uses the value of the +.B convert\-meta +variable to determine whether to perform this conversion: +if \fBconvert\-meta\fP is \fBOn\fP, +readline performs the conversion described above; +if it is \fBOff\fP, Readline converts \fIC\fP to a meta character by +setting the eighth bit (0200). .TP .B expand\-tilde (Off) If set to \fBOn\fP, tilde expansion is performed when readline @@ -6440,11 +6479,13 @@ This setting is automatically enabled for terminals of height 1. .B input\-meta (Off) If set to \fBOn\fP, readline will enable eight-bit input (that is, it will not strip the eighth bit from the characters it reads), -regardless of what the terminal claims it can support. The name +regardless of what the terminal claims it can support. +The name .B meta\-flag is a synonym for this variable. -The default is \fIOff\fP, but readline will set it to \fIOn\fP if the -locale contains eight-bit characters. +The default is \fIOff\fP, but readline will set it to \fIOn\fP +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the \fBLC_CTYPE\fP locale category, and may change if the locale is changed. .TP @@ -6511,8 +6552,9 @@ the list. If set to \fBOn\fP, readline will display characters with the eighth bit set directly rather than as a meta-prefixed escape sequence. -The default is \fIOff\fP, but readline will set it to \fIOn\fP if the -locale contains eight-bit characters. +The default is \fIOff\fP, but readline will set it to \fIOn\fP +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the \fBLC_CTYPE\fP locale category, and may change if the locale is changed. .TP @@ -7244,7 +7286,7 @@ enclosed within braces so the list is available to the shell (see .B Brace Expansion above). .PD -.SS Keyboard Macros +.SS "Keyboard Macros" .PD 0 .TP .B start\-kbd\-macro (C\-x (\^) diff --git a/lib/readline/bind.c b/lib/readline/bind.c index b4f8004f..21cfdf56 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -98,6 +98,15 @@ static int currently_reading_init_file; /* used only in this file */ static int _rl_prefer_visible_bell = 1; +/* Currently confined to this file for key bindings. If enabled (> 0), we + force meta key bindings to use the meta prefix (ESC). If unset (-1) or + disabled (0), we use the current value of _rl_convert_meta_chars_to_ascii + as in previous readline versions. */ +static int _rl_force_meta_prefix = 0; + +/* Do we want to force binding "\M-C" to the meta prefix (ESC-C)? */ +#define FORCE_META_PREFIX() (_rl_force_meta_prefix > 0 ? 1 : _rl_convert_meta_chars_to_ascii) + #define OP_EQ 1 #define OP_NE 2 #define OP_GT 3 @@ -137,7 +146,7 @@ rl_bind_key (int key, rl_command_func_t *function) return (key); /* Want to make this a multi-character key sequence with an ESC prefix */ - if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) + if (META_CHAR (key) && FORCE_META_PREFIX()) { if (_rl_keymap[ESC].type == ISKMAP) { @@ -418,19 +427,8 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) return -1; } - /* We now rely on rl_translate_keyseq to do this conversion, so this - check is superfluous. */ -#if 0 - if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) - { - ic = UNMETA (ic); - if (map[ESC].type == ISKMAP) - { - prevmap = map; - map = FUNCTION_TO_KEYMAP (map, ESC); - } - } -#endif + /* We rely on rl_translate_keyseq to do convert meta-chars to key + sequences with the meta prefix (ESC). */ if ((i + 1) < keys_len) { @@ -617,14 +615,13 @@ rl_translate_keyseq (const char *seq, char *array, int *len) c = (c == '?') ? RUBOUT : CTRL (_rl_to_upper (c)); has_control = 0; } + if (has_meta) - { - c = META (c); - has_meta = 0; - } + c = META (c); - /* If convert-meta is turned on, convert a meta char to a key sequence */ - if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii) + /* If force-meta-prefix is turned on, convert a meta char to a key + sequence, but only if it uses the \M- syntax. */ + if (META_CHAR (c) && has_meta && FORCE_META_PREFIX()) { int x = UNMETA (c); if (x) @@ -638,6 +635,8 @@ rl_translate_keyseq (const char *seq, char *array, int *len) else array[l++] = (c); + has_meta = 0; + /* Null characters may be processed for incomplete prefixes at the end of sequence */ if (seq[i] == '\0') @@ -698,7 +697,7 @@ rl_untranslate_keyseq (int seq) c = UNMETA (c); } - if (c == ESC) + if (c == ESC) /* look at _rl_force_meta_prefix here? */ { kseq[i++] = '\\'; c = 'e'; @@ -805,7 +804,7 @@ _rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int { unsigned char ic = keyseq[i]; - if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) + if (META_CHAR (ic) && FORCE_META_PREFIX()) /* XXX - might not want this */ { if (map[ESC].type == ISKMAP) { @@ -1888,6 +1887,7 @@ static const struct { { "enable-keypad", &_rl_enable_keypad, 0 }, { "enable-meta-key", &_rl_enable_meta, 0 }, { "expand-tilde", &rl_complete_with_tilde_expansion, 0 }, + { "force-meta-prefix", &_rl_force_meta_prefix, 0 }, { "history-preserve-point", &_rl_history_preserve_point, 0 }, { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 }, { "input-meta", &_rl_meta_flag, 0 }, diff --git a/lib/readline/doc/readline.3 b/lib/readline/doc/readline.3 index b36333d3..3dbc8596 100644 --- a/lib/readline/doc/readline.3 +++ b/lib/readline/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Sat May 11 12:44:56 EDT 2024 +.\" Last Change: Fri Aug 23 09:04:51 EDT 2024 .\" -.TH READLINE 3 "2024 May 11" "GNU Readline 8.3" +.TH READLINE 3 "2024 August 23" "GNU Readline 8.3" .\" .ie \n(.g \{\ .ds ' \(aq @@ -106,17 +106,31 @@ Control keys are denoted by C\-\fIkey\fP, e.g., C\-n means Control\-N. Similarly, .I meta keys are denoted by M\-\fIkey\fP, so M\-x means Meta\-X. -(On keyboards without a -.I meta +.PP +On keyboards without a +.I Meta key, M\-\fIx\fP means ESC \fIx\fP, i.e., press the Escape key then the .I x -key. This makes ESC the \fImeta prefix\fP. +key. +This makes ESC the \fImeta prefix\fP. The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP, or press the Escape key then hold the Control key while pressing the .I x -key.) +key. +.PP +On some keyboards, the Meta key modifier produces meta characters with +the eighth bit (0200) set (you can use the \fBenable\-meta\-key\fP variable +to control whether or not it does this, if the keyboard allows it). +On many others, the terminal or terminal emulator converts the metafied +key to a key sequence beginning with ESC as described in the +preceding paragraph. +.PP +If the \fIMeta\fP key produces a key sequence with the ESC meta prefix, +you can make M-\fIkey\fP key bindings you specify (see +.B "Readline Key Bindings" +below) do the same thing by setting the \fBforce\-meta\-prefix\fP variable. .PP Readline commands may be given numeric .IR arguments , @@ -268,7 +282,8 @@ key sequences is control prefix .TP .B \eM\- -meta prefix +adding the meta prefix or converting the following character to a meta +character, as described below under \fBforce-meta-prefix\fP .TP .B \ee an escape character @@ -486,14 +501,17 @@ on the terminal. A negative value causes readline to never ask. .TP .B convert\-meta (On) -If set to \fBOn\fP, readline will convert characters with the -eighth bit set to an ASCII key sequence -by stripping the eighth bit and prefixing it with an -escape character (in effect, using escape as the \fImeta prefix\fP). -The default is \fIOn\fP, but readline will set it to \fIOff\fP if the -locale contains eight-bit characters. +If set to \fBOn\fP, readline will convert characters it reads +with the eighth bit set to an ASCII key sequence +by stripping the eighth bit and prefixing it with an escape character +(converting the character to have the \fImeta prefix\fP). +The default is \fIOn\fP, but readline will set it to \fIOff\fP +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the \fBLC_CTYPE\fP locale category, and may change if the locale is changed. +This variable also affects key bindings; see the description of +\fBforce\-meta\-prefix\fP below. .TP .B disable\-completion (Off) If set to \fBOn\fP, readline will inhibit word completion. Completion @@ -551,13 +569,34 @@ arrow keys. .TP .B enable\-meta\-key (On) When set to \fBOn\fP, readline will try to enable any meta modifier -key the terminal claims to support when it is called. On many terminals, -the meta key is used to send eight-bit characters. +key the terminal claims to support when it is called. +On many terminals, the Meta key is used to send eight-bit characters; +this variable checks for the terminal capability that indicates the +terminal can enable and disable a mode that sets the eighth bit of a +character (0200) if the Meta key is held down when the character is +typed (a meta character). .TP .B expand\-tilde (Off) If set to \fBOn\fP, tilde expansion is performed when readline attempts word completion. .TP +.B force\-meta\-prefix (Off) +If set to \fBOn\fP, readline modifies its behavior when binding key +sequences containing \eM- or Meta- +(see \fBKey Bindings\fP above) by converting a key sequence of the form +\eM-\fIC\fP or Meta-\fIC\fP to the two-character sequence +\fBESC\fP\fIC\fP (adding the meta prefix). +If +.B force\-meta\-prefix +is set to \fBOff\fP (the default), +readline uses the value of the +.B convert\-meta +variable to determine whether to perform this conversion: +if \fBconvert\-meta\fP is \fBOn\fP, +readline performs the conversion described above; +if it is \fBOff\fP, Readline converts \fIC\fP to a meta character by +setting the eighth bit (0200). +.TP .B history\-preserve\-point (Off) If set to \fBOn\fP, the history code attempts to place point at the same location on each history line retrieved with \fBprevious-history\fP @@ -582,11 +621,13 @@ This setting is automatically enabled for terminals of height 1. .B input\-meta (Off) If set to \fBOn\fP, readline will enable eight-bit input (that is, it will not clear the eighth bit in the characters it reads), -regardless of what the terminal claims it can support. The name +regardless of what the terminal claims it can support. +The name .B meta\-flag is a synonym for this variable. -The default is \fIOff\fP, but readline will set it to \fIOn\fP if the -locale contains eight-bit characters. +The default is \fIOff\fP, but readline will set it to \fIOn\fP +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the \fBLC_CTYPE\fP locale category, and may change if the locale is changed. .TP @@ -653,8 +694,9 @@ the list. If set to \fBOn\fP, readline will display characters with the eighth bit set directly rather than as a meta-prefixed escape sequence. -The default is \fIOff\fP, but readline will set it to \fIOn\fP if the -locale contains eight-bit characters. +The default is \fIOff\fP, but readline will set it to \fIOn\fP +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the \fBLC_CTYPE\fP locale category, and may change if the locale is changed. .TP @@ -1275,7 +1317,7 @@ end of the line (like \fBdelete-char\fP). If at the end of the line, behaves identically to \fBpossible-completions\fP. .PD -.SS Keyboard Macros +.SS "Keyboard Macros" .PD 0 .TP .B start\-kbd\-macro (C\-x (\^) diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index bc57ccf7..5bcbaa29 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -91,7 +91,7 @@ is depressed. The text @kbd{M-k} is read as `Meta-K' and describes the character produced when the Meta key (if you have one) is depressed, and the @key{k} -key is pressed. +key is pressed (a @dfn{meta character}). The Meta key is labeled @key{ALT} on many keyboards. On keyboards with two keys labeled @key{ALT} (usually to either side of the space bar), the @key{ALT} on the left side is generally set to @@ -100,13 +100,22 @@ The @key{ALT} key on the right may also be configured to work as a Meta key or may be configured as some other modifier, such as a Compose key for typing accented characters. +On some keyboards, the Meta key modifier produces meta characters with +the eighth bit (0200) set (you can use the @code{enable-meta-key} variable +to control whether or not it does this, if the keyboard allows it). +On many others, the terminal or terminal emulator converts the metafied +key to a key sequence beginning with @key{ESC} as described in the +next paragraph. + If you do not have a Meta or @key{ALT} key, or another key working as -a Meta key, the identical keystroke can be generated by typing @key{ESC} +a Meta key, you can generally achieve the latter effect by typing @key{ESC} @emph{first}, and then typing @key{k}. +The @key{ESC} character is known as the @dfn{meta prefix}). + Either process is known as @dfn{metafying} the @key{k} key. The text @kbd{M-C-k} is read as `Meta-Control-k' and describes the -character produced by @dfn{metafying} @kbd{C-k}. +character produced by metafying @kbd{C-k}. In addition, several keys have their own names. Specifically, @key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all @@ -541,15 +550,17 @@ The default limit is @code{100}. @item convert-meta @vindex convert-meta -If set to @samp{on}, Readline will convert characters with the -eighth bit set to an @sc{ascii} key sequence by stripping the eighth -bit and prefixing an @key{ESC} character, converting them to a -meta-prefixed key sequence. -The default value is @samp{on}, but -will be set to @samp{off} if the locale is one that contains -eight-bit characters. +If set to @samp{on}, Readline will convert characters it reads +with the eighth bit set to an @sc{ascii} key sequence +by stripping the eighth bit and prefixing an @key{ESC} character, +converting them to a meta-prefixed key sequence. +The default value is @samp{on}, but Readline will set it to @samp{off} +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the @code{LC_CTYPE} locale category, and may change if the locale is changed. +This variable also affects key bindings; see the description of +@code{force-meta-prefix} below. @item disable-completion @vindex disable-completion @@ -615,8 +626,12 @@ arrow keys. The default is @samp{off}. @item enable-meta-key When set to @samp{on}, Readline will try to enable any meta modifier -key the terminal claims to support when it is called. On many terminals, -the meta key is used to send eight-bit characters. +key the terminal claims to support when it is called. +On many terminals, the Meta key is used to send eight-bit characters; +this variable checks for the terminal capability that indicates the +terminal can enable and disable a mode that sets the eighth bit of a +character (0200) if the Meta key is held down when the character is +typed (a meta character). The default is @samp{on}. @item expand-tilde @@ -624,6 +639,22 @@ The default is @samp{on}. If set to @samp{on}, tilde expansion is performed when Readline attempts word completion. The default is @samp{off}. +@item force-meta-prefix +@vindex force-meta-prefix +If set to @samp{on}, Readline modifies its behavior when binding key +sequences containing @kbd{\M-} or @code{Meta-} +(@pxref{Key Bindings}) by converting a key sequence of the form +@kbd{\M-}@var{C} or @code{Meta-}@var{C} to the two-character sequence +@kbd{ESC}@var{C} (adding the meta prefix). +If @code{force-meta-prefix} is set to @samp{off} (the default), +Readline uses the value of the @code{convert-meta} variable to determine +whether to perform this conversion: +if @code{convert-meta} is @samp{on}, +Readline performs the conversion described above; +if it is @samp{off}, Readline converts @var{C} to a meta character by +setting the eighth bit (0200). +The default is @samp{off}. + @item history-preserve-point @vindex history-preserve-point If set to @samp{on}, the history code attempts to place the point (the @@ -657,8 +688,9 @@ By default, this variable is set to @samp{off}. If set to @samp{on}, Readline will enable eight-bit input (it will not clear the eighth bit in the characters it reads), regardless of what the terminal claims it can support. The -default value is @samp{off}, but Readline will set it to @samp{on} if the -locale contains eight-bit characters. +default value is @samp{off}, but Readline will set it to @samp{on} +if the locale contains +characters whose encodings may include bytes with the eighth bit set. The name @code{meta-flag} is a synonym for this variable. This variable is dependent on the @code{LC_CTYPE} locale category, and may change if the locale is changed. @@ -742,8 +774,9 @@ the list. The default is @samp{off}. If set to @samp{on}, Readline will display characters with the eighth bit set directly rather than as a meta-prefixed escape sequence. -The default is @samp{off}, but Readline will set it to @samp{on} if the -locale contains eight-bit characters. +The default is @samp{off}, but Readline will set it to @samp{on} +if the locale contains +characters whose encodings may include bytes with the eighth bit set. This variable is dependent on the @code{LC_CTYPE} locale category, and may change if the locale is changed. @@ -929,7 +962,9 @@ specifying key sequences: @item @kbd{\C-} control prefix @item @kbd{\M-} -meta prefix +adding the meta prefix or converting the following character to a meta +character, as described above under @code{force-meta-prefix} +(@pxref{Variable Settings}). @item @kbd{\e} an escape character @item @kbd{\\} diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 4b59487c..9093f371 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -5,7 +5,7 @@ Copyright (C) 1988-2024 Free Software Foundation, Inc. @set EDITION 8.3 @set VERSION 8.3 -@set UPDATED 13 August 2024 +@set UPDATED 23 August 2024 @set UPDATED-MONTH August 2024 -@set LASTCHANGE Tue Aug 13 14:31:23 EDT 2024 +@set LASTCHANGE Fri Aug 23 09:46:18 EDT 2024