help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to save/restore (all?) bindings


From: Koichi Murase
Subject: Re: how to save/restore (all?) bindings
Date: Sat, 7 Oct 2023 12:44:59 +0900

2023年10月2日(月) 9:40 Christoph Anton Mitterer <calestyo@scientia.org>:
> [...] the question on how one can save&restore the state of
> (all?) bindings of a bash instance.

Although I doubt these can be used to implement your mycdfunc, I have
functions to save and restore keybindings in my project:[1]. I
extracted the functions and modified them to be standalone [2].

- [1] https://github.com/akinomyoga/ble.sh/blob/master/src/decode.sh#L2846-L2968
- [2] https://github.com/akinomyoga/bug-report/blob/master/bash/reply20231007.sh

> 2) mycdfunc would then cause:
>    - save the current bindings
>    - set the key bindings as needed (e.g. either manually to something,
>      or back to their default with bind -r)
>    - do the __fzf_cd__ magic
>    - restore the previous bindings, in order to get any user
>      customisations back

So, looking at an example in another email, I guess you are trying to
chain the sequences by sending \e[5n and receiving \e[0n. Then, what
happens when a user quickly inputs the sequences \ecxxxx (where xxxx
might contain conflicting sequences) before the terminal receives
\e[5n from mycdfunc? Also, this causes unnecessary roundtrip
communications between the shell and the terminal, which can be slow
in remote environments.

If it were me, I'd use a technique similar to the one described in
[3], which uses invalid UTF-8 sequences to avoid conflicts. This could
in principle conflict with users' keybindings, but it is unlikely that
the user sets up invalid UTF-8 sequences for their practical
keybindings because such a sequence should never appear in the
terminal-to-application stream. In case the user might use the same
trick of using UTF-8 sequences, you could choose invalid sequences of
larger code points.

- [3] https://lists.gnu.org/archive/html/help-bash/2022-02/msg00023.html

--
Koichi







>
>
> So a function is needed, that saves the current bindings so that they
> can be brought back with eval, and that's what this mail is about.
>
> My own "solution" would be this:
> save_binds()
> {
>         local keymap="$1"
>         local line=''
>
>
>         bind ${keymap:+-m} ${keymap:+"${keymap}"} -p -s  |
>         while IFS='' read -r line; do
>                 [ -n "${line###*}" ]  &&
>                 { [ -n "${keymap}" ]  &&  printf 'bind -m %q %q\n' 
> "${keymap}" "${line}"  ||
>                                           printf 'bind %q\n' "${line}"
>                 }
>         done
>
>         bind ${keymap:+-m} ${keymap:+"${keymap}"} -X  |
>         while IFS='' read -r line; do
>                 [ -n "${line###*}" ]  &&
>                 { [ -n "${keymap}" ]  &&  printf 'bind -m %q -x %q\n' 
> "${keymap}" "${line}"  ||
>                                           printf 'bind -x %q\n' "${line}"
>                 }
>         done
> }
>
> which, as far as my limited understanding of bash goes, works.
>
> It's idea is to print a number of bind commands, one per line, so that
> any changes of the bindings made via either of:
>        bind [-m keymap] -x keyseq:shell-command
>        bind [-m keymap] keyseq:function-name
>        bind [-m keymap] keyseq:readline-command
>        bind [-m keymap] [-q function] [-u function] [-r keyseq]
> would be restored when `eval`ed.
>
> It tries to not call non-built-in utilities for performance reasons
> (though I haven't really tested, whether it would be actually even
> faster to e.g. remove the comment lines from bind -p via grep, rather
> than [ -n "${line###*}" ] .
> I'm open for suggestions in terms of performance.
>
> Similarly, the function tries to simply save the whole state, whereas
> for my purpose it might be enough to just save&restore the state for
> certain keyseqs.
> Not really sure what would be better. At least it would make the
> function more complex, if one could select certain keyseqs via
> parameters.
>
>
> It takes 0-1 arguments, if $1 is given it's the value to `bind`’s -m
> option, if not, no -m option is used.
> Quite some code above went into just differentiating between with -m
> and no -m option.
>
> I couldn't find what it means if no -m is given?
>
> Also, some code went into allowing keymap's value to contain spaces...
> yeah, it most likely never will, so that's probably stupid. ^^
>
>
> I'd be happy to get any feedback on my function:
> - improvements (performance, functionality)
> - whether it's all wrong or I miss saving some statuses or could be
>   done simpler
> - or whether I've overseen any pitfalls in quoting, using %q, IFS and
>   so on
> - etc.
>
>
>
> Thanks,
> Chris.
>
>
> [0] https://github.com/junegunn/fzf/
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]