akinomyoga / ble.sh

Bash Line Editor―a line editor written in pure Bash with syntax highlighting, auto suggestions, vim modes, etc. for Bash interactive sessions.
BSD 3-Clause "New" or "Revised" License
2.33k stars 77 forks source link

If I use history substring search with empty string and press up, how do I make it so I only need to press Enter once? #398

Closed mcarans closed 5 months ago

mcarans commented 5 months ago

I have history substring search from bash-it. When I press up arrow, I get the nsearch and I have to press Enter twice to run the command. I understand from here that this behaviour can be changed. I don't know where to change it. Please can you advise.

akinomyoga commented 5 months ago

You can read https://github.com/akinomyoga/ble.sh/issues/101#issuecomment-828541531.

I have history substring search from bash-it.

Are you talking about this?

Then, you can instead have the following settings:

ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-forward immediate-accept'

edit: Or, if you would like to accept the line by a single Enter only when up is pressed for the empty command line, maybe this:

ble-bind -f up 'history-substring-search-backward empty=history-move'
ble-bind -f down 'history-substring-search-forward empty=history-move'
mcarans commented 5 months ago

Both of those seem to do what I want, so I was wondering what is the difference between them?

Also if I want to make this permanent, which configuration file should I change? I see mention of ~/.blerc or ~/.config/blesh/init.sh here. Neither file exists at the moment.

akinomyoga commented 5 months ago

Both of those seem to do what I want, so I was wondering what is the difference between them?

With the latter, the history search doesn't start with the empty command line. When the command line is empty (or the cursor is at the beginning of the command line), it moves to the previous history entry just the same as the default binding to up.

To talk about the superficial behavioral difference, with the former, the command is always executed by a single Enter. With the latter, the command is executed by a single Enter only with the empty command line.

Neither file exists at the moment.

You need to create one. Either one is fine. ble.sh doesn't try to change the content of the user's data directory.

mcarans commented 5 months ago

Thank you, that's helpful! Sorry if this is a dumb question, but why wouldn't I always want it to be a single ENTER (ie. immediate-accept) or to put it another way, what can I do between the two ENTER keypresses in the non-empty case?

akinomyoga commented 5 months ago

why wouldn't I always want it to be a single ENTER (ie. immediate-accept) or to put it another way, what can I do between the two ENTER keypresses in the non-empty case?

So that one can edit the command found in the history. You can continue to edit the command line after pressing the first Enter. In particular, one can use isearch (C-r/C-s) and cursor movements (up/down) only after the first Enter.

But maybe it's not so useful in your case because you override up and down by nsearch. By overriding up and down, you cannot move between lines in the multiline mode. Actually, nsearch is bound to PageUp and PageDown by default, with which up and down after pressing the first Enter are still useful.

I also wanted to make the behavior consistent with isearch (incremental search) called by C-r and C-s, and the isearch behavior is modified to be consistent with the original implementation of Emacs. It's a tiny difference in how Enter behaves, but the tiny difference between the command line and the editor would be troublesome because it induces mistakes. It is a problem, especially for the command execution that can be destructive.

Also, it would be good to put a pose before running the command quickly picked up. If you are sure that the picked command is correct, you can press Ctrl+Enter to immediately accept the command. To use Ctrl+Enter (C-RET), please refer to konsole - Manual A2 for the key configuration in Konsole.

mcarans commented 5 months ago

Thanks for the explanation. I'm not sure what I'm doing wrong, but I can't seem to make the change permanent. I made a file .blerc in $HOME with:

ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-forward immediate-accept'

At the top of my .bashrc I put:

source $HOME/.local/share/blesh/ble.sh  --rcfile "$HOME/.blerc" --attach=none

At the bottom, I put:

ble-attach

When I open Konsole, the behaviour is as if there were no .blerc file. What am I missing?

EDIT: I have tried many options but nothing seems to set the bindings (except doing it manually in the terminal). For example, I tried without specifying --rcfile, and also putting the two lines in ~/.config/blesh/init.sh instead of .blerc.

akinomyoga commented 5 months ago

One possibility is that those bindings are applied to a different keymap. Do you use the vi editing mode?

If you use the vi editing mode

ble-bind without specifying the keymap applies to the currently selected keymap, so if you put the settings of ble-bind before calling set -o vi, those bindings are defined in the emacs keymap.

There are three options that I can come up with immediately. One is to enable the vi editing mode before calling ble-bind.

# blerc

set -o vi
ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-forward immediate-accept'

Another option is to explicitly specify the keymap:

# blerc

ble-bind -m vi_imap -f up 'history-substring-search-backward immediate-accept'
ble-bind -m vi_imap -f down 'history-substring-search-forward immediate-accept'

The other is to define the binding in the startup hook of the vi editing mode as described at the beginning of §6.3:

# blerc

function my/vim-load-hook {
  ble-bind -f up 'history-substring-search-backward immediate-accept'
  ble-bind -f down 'history-substring-search-forward immediate-accept'
}
blehook/eval-after-load keymap_vi my/vim-load-hook
mcarans commented 5 months ago

I haven't to my knowledge set up vi editing. If I put the lines at the end of my .bashrc, they work:

...
ble-attach
ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-forward immediate-accept'

It is as if the .blerc and .config/blesh/init.sh files are ignored.

EDIT: They are not ignored though, because I tried the set -o vi line in .blerc and it caused a change in behaviour in the terminal (which means I wasn't using vi mode). It shows:

-- INSERT --

It didn't show that before.

EDIT 2: I think I worked out the problem. Sourcing ble.sh at the top happens before sourcing bash-it and so the key bindings in .blerc are loaded before bash-it is set up. The .blerc needs to be loaded after sourcing bash-it somehow.

ie. this works:

...
source "$BASH_IT"/bash_it.sh
ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-forward immediate-accept'

source ~/.local/share/konsole/bash-preexec.sh
source ~/.local/share/konsole/shell-integration.bash
ble-attach

This does not work:

ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-forward immediate-accept'
source "$BASH_IT"/bash_it.sh

source ~/.local/share/konsole/bash-preexec.sh
source ~/.local/share/konsole/shell-integration.bash
ble-attach
akinomyoga commented 5 months ago

Hmm, I don't have an idea for now. In my environment it works with the following setup:

# bashrc
source out/ble.sh --rcfile gh398.blerc --attach=none
ble-attach
# gh398.blerc
ble-bind -f up 'history-substring-search-backward immediate-accept'
ble-bind -f down 'history-substring-search-backward immediate-accept'
mcarans commented 5 months ago

Is there any way to get the .blerc file to be loaded in the ble-attach call rather than in the source ~/.local/share/blesh/ble.sh --noattach call? If not, I guess I can just source it at the end of my .bashrc.

akinomyoga commented 5 months ago

EDIT 2: I think I worked out the problem. Sourcing ble.sh at the top happens before sourcing bash-it and so the key bindings in .blerc are loaded before bash-it is set up. The .blerc needs to be loaded after sourcing bash-it somehow.

ie. this works:

Do you still have Bash-it's history-substring-search plugin enabled? Then, this is understandable because those ble-bind settings are overwritten by the history-substring-search plugin. You need to turn off Bash-it's history-substring-search plugin by running

$ bash-it disable plugin history-substring-search
akinomyoga commented 5 months ago

Is there any way to get the .blerc file to be loaded in the ble-attach call rather than in the source ~/.local/share/blesh/ble.sh --noattach call?

No. By design, the users can call ble-attach and ble-detach multiple times anytime later, so it is strange to run initialization codes in ble-attach, which can be called multiple times at an arbitrary timing.

mcarans commented 5 months ago

Ah brilliant, that's it! I misunderstood - I had thought that ble.sh used bash-it's history substring search. Thanks for all your help.

akinomyoga commented 5 months ago

Let me close the issue as you seem to have solved the problem. If you haven't been satisfied, please reopen it. Thank you.