Re: Changing the way bash expands associative array subscripts

2021-04-16 Thread Koichi Murase
2021年4月16日(金) 1:04 Chet Ramey :
> On 4/13/21 11:11 PM, Koichi Murase wrote:
> > 2021年4月14日(水) 0:24 Chet Ramey :
> >> On 4/13/21 5:01 AM, Koichi Murase wrote:
> >>> But I expected some design consideration enabling a[$key] for an
> >>> arbitrary key in the indirect expansions and namerefs.
> >>
> >> Why? Why should the shell carry around (and expect the user to remember)
> >> information about the original value assigned to a variable pre-expansion?
> >
> > I didn't mean we should preserve the syntactic information, which I
> > don't either think is a good idea.  Maybe we could always treat
> > `assoc[@]' as a single element reference.
>
> Do you mean, for example, in assignment statements?

In that paragraph, I was just thinking of indirect expansions, name
references, and unset, but this was a subset of my suggestion in
https://lists.gnu.org/archive/html/bug-bash/2021-04/msg00123.html
where I thought of changing 'assoc[@]' to a single element reference
in indirect expansions, namerefs, `unset -v', `test -v', `printf -v',
etc., while keeping the current interpretation in assignments,
parameter expansions, and arithmetic expressions (see the above link
for details).  But this is of course not a perfect solution.

> I can see it in that
> case, and for  `unset', and maybe for `test', because of the semantics of
> builtin commands.
>
> But if you take it farther than that, then there is no way to get the
> elements of an associative array without introducing yet more syntax. My
> guess is there are many, many more cases where ${assoc[@]} is intended to
> mean "all the array elements" instead of "the element '@'", and I'm not
> interested in that kind of incompatibility.

I agree that we shouldn't change the current behavior of ${assoc[@]}
being expanded to all the elements.

> >> Under what circumstances should they not be expanded? Because the
> >> indirect expansions of array subscripts still undergo a single set
> >> of word expansions.
> >
> >  From the users' point of view, indirect expansions and name references
> > currently undergo "double expansions" in assigning time and in
> > reference time; I mean naive users will write as « iref=a[$key] »
> > instead of « iref='a[$key]' » and run « echo "${!iref}" » to find that
> > the original right-hand side of the assignment is finally
> > double-expanded until the reference time.
>
> That's the point of indirect expansions! Even in the most basic use case:
>
> foo=bar
> bar=qux
> v=$foo
> echo ${!v}
>
> nobody should be surprised to see a `double expansion'.

In that case, I agree that no one would be surprised by the double
expansion of the *variable names* because it's the purpose of the
namerefs.  But I don't think everyone would necessarily expect the
*subscripts* would also be double-expanded.

> I suppose you can't protect people from their bad assumptions,

Right.

> Don't limit yourself to `unset'. The same thing happens with test and
> other builtin commands because of the set of word expansions they undergo
> before the builtin even sees its arguments.

Yes. I think the other builtins that take variable names should also
behave the same as `unset', i.e., they should expand the variable
names by itself so that « test -v 'a[$key]' », « printf -v 'a[$key]'
... », « read 'a[$key]' », etc. would work.

> > I actually agree with konsolebox that assoc_expand_once for unset
> > shouldn't be defaulted.  The option `assoc_expand_once' is incomplete
> > in the sense that the behavior of `a[@]' and `a[*]' are subtle.  I see
> > the current default behavior (with `assoc_expand_once' turned off)
> > more consistent and clean.
>
> Yeah, maybe. But explaining the requirements for quoting things in multiple
> ways is confusing, even to experienced users, and leads to knee-jerk
> overreactions like "don't use associative arrays ever" that don't help
> anyone. That's one of the motivations for this entire discussion.

Yes, but if `unset' is defaulted to `assoc_expand_once' behavior while
indirect expansions and namerefs aren't changed, users still need to
do two different ways of quoting: « unset "a[$key]" » versus «
iref='a[$key]'; echo "${!iref}" » and « declare -n nref='a[$key]';
echo "$nref" ». My initial understanding was that indirect expansions
and namerefs would also be changed to unify the quoting rules to «
"a[$key]" » but not to « 'a[$key]' ».

> > and we can tell users to always write « unset 'a[$key]' », «
> > iref='a[$key]'; echo "${!iref}" » and « declare -n nref='a[$key]';
> > echo "$nref" ».
>
> That's what I thought people would do with arrays in the first place. It
> obviously hasn't worked out the way I anticipated.
>
> So the current state has people doing
>
> declare -A assoc
> key='x]'
>
> assoc[$key]=hello
> declare -p assoc
>
> unset assoc["$key"]

Those whom I called ``naive users'' in previous replies include people
writing `unset' in the above way.  In this sense, to me, making «
unset "assoc[$key]" » safer seems the change to make the be

Re: Mysterious error after rebinding keys in Bash 5.1.4

2021-04-16 Thread Chet Ramey

On 4/16/21 1:15 AM, Dale Sedivec wrote:


Bash Version: 5.1
Patch Level: 4
Release Status: release

Description:

Rebinding a key seems to break the key that was bound before it.  (That sounds 
bizarre, but read ahead.)

Repeat-By:

Run the following:

```
bash --norc --noprofile
bind -m emacs -x '"\C-r": echo one'
bind -m emacs -x '"\C-t": echo two'
bind -m emacs '"\C-t": transpose-chars'
```

Then press C-r.

Expected behavior: Bash runs "echo one"

Observed behavior: I get an error message and nothing else:

 bash: bash_execute_unix_command: cannot find keymap for command


Thanks for the report.


--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: Mysterious error after rebinding keys in Bash 5.1.4

2021-04-16 Thread Koichi Murase
2021年4月16日(金) 22:08 Dale Sedivec :
> Bash Version: 5.1
> Patch Level: 4
> Release Status: release
>
> Description:
>
> Rebinding a key seems to break the key that was bound before it.  (That 
> sounds bizarre, but read ahead.)

I attach a patch. This was introduced by the commit 3a7c642e after
https://lists.gnu.org/archive/html/bug-bash/2019-12/msg00050.html
> commit 3a7c642e223ec260042bfecc12da49717ae77d76
> Author: Chet Ramey 
> Date:   Mon Dec 16 09:43:38 2019 -0500
>
>commit bash-20191213 snapshot
>
>12/13
>   -
> builtins/bind.def
>   - bind_builtin: check the number of bindings to bash_execute_unix_command
> before and after a call to rl_parse_and_bind and if there are fewer
> after binding, we know that the bind has re-bound one of the key
> sequences that was bound to execute a shell command. We unbind any
> key sequences from the list before the call to rl_parse_and_bind that
> don't appear in the list after the call using unbind_unix_command

--
Koichi


0001-fix-incorrect-unbind_unix_command-on-overwriting-key.patch
Description: Binary data


Mysterious error after rebinding keys in Bash 5.1.4

2021-04-16 Thread Dale Sedivec
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: darwin19.6.0
Compiler: /usr/bin/clang
Compilation CFLAGS: -pipe -Os -DSSH_SOURCE_BASHRC 
-isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -arch x86_64
uname output: Darwin dale-work.caliginous.net 19.6.0 Darwin Kernel Version 
19.6.0: Tue Jan 12 22:13:05 PST 2021; root:xnu-6153.141.16~1/RELEASE_X86_64 
x86_64
Machine Type: x86_64-apple-darwin19.6.0

Bash Version: 5.1
Patch Level: 4
Release Status: release

Description:

Rebinding a key seems to break the key that was bound before it.  (That sounds 
bizarre, but read ahead.)

Repeat-By:

Run the following:

```
bash --norc --noprofile
bind -m emacs -x '"\C-r": echo one'
bind -m emacs -x '"\C-t": echo two'
bind -m emacs '"\C-t": transpose-chars'
```

Then press C-r.

Expected behavior: Bash runs "echo one"

Observed behavior: I get an error message and nothing else:

bash: bash_execute_unix_command: cannot find keymap for command

I believe this worked fine in Bash 5.0.17.

The above is a simplified version of my real use case: I load the key bindings 
that are shipped with the tool fzf[1], but then I want to revert C-t to the 
default behavior, transpose-chars.

And thank you for Bash!

Dale

[1]: https://github.com/junegunn/fzf/blob/master/shell/key-bindings.bash