Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding a key sequence to a macro #50

Closed
hokuda opened this issue Jul 25, 2016 · 4 comments
Closed

Binding a key sequence to a macro #50

hokuda opened this issue Jul 25, 2016 · 4 comments

Comments

@hokuda
Copy link
Contributor

hokuda commented Jul 25, 2016

This is relevant with the issue #47.
I have used peco for history expansion on bash for the last years. Adding the following code in my .bashrc, my ctrl-r invokes peco:

_complete_history() {
    local l=$(HISTTIMEFORMAT= history | tac | sed -e 's/^\s*[0-9]*  //' | peco --query "$READLINE_LINE")
    if [ "${l}x" != "x" ]; then
        READLINE_LINE="$l"
        READLINE_POINT=${#l}
    fi
}
bind -x '"\C-r": _complete_history'

If the rlwrap has the feature like the bind command of bash to bind a key sequence to a macro, it augments the rlwrap's history expansion feature and gives the rlwrap more flexibility.

@hanslub42
Copy link
Owner

There has been some discussion on bug-readline, about doing this for readine itself, where the conclusion was that this is not so simple. rlwraps hotkey is very similar, however: CTRL+R could be bound to rlwrap-hotkey, where the hotkey handler could do something along the lines of your example.

Problem: in bash, the hotkey handler is a shell function that can "see" everything because it runs in the same process as the shell itself. A filter is a separate, lonely process that can not look into rlwrap nor the rlwrapped command. cloak_and_dagger() can pry some information from the latter, but rlwrap itself is a black box.

A possible solution would be to send as much information as possible in a HOTKEY message: not only the current input line, but e.g. also the current history. The handler would have to be something like this

$filter -> hotkey_handler(sub {
   my($key, $input_line, $cursor_position, $history, $history_position, ....) = @_
   if ($key == control('R')) {
         my ($new_line, $new_cursorpos) = use_peco_to_get_a_line($history);
         return("", $new_line, $new_cursorpos, $history, $history_position,....);
   }
}

This would subsume the current rlwrap-edit-history function as well, and thus get rid of some code (at the expense of a slightly more complex hotkey handler)

If sending the complete history for every hotkey keystroke is a bit too much, I could also implement a rlwrap-hotkey-without-history function, for those hotkeys that don't need the complete history

@hanslub42
Copy link
Owner

I worked this out in branch hash_history, and this looks quite promising. History edit is now done in a few lines of perl (or python), and the existing --multi-line support could also easily be subsumed under rlwrap-hotkey. I cannot easily try peco on my linux machine, but I don't see why this wouldn't be straightforward as well.

One little twist should/will be added to the hotkey handler: if the returned input line ends with a newline, immediately accept the result, otherwise keep editing. So, if (and only if) we e.g. put two empty lines before a history line (or e.g. end a multi-line edit with a '!') accept the result

@hokuda
Copy link
Contributor Author

hokuda commented Jul 29, 2016

Thanks a lot for the great work! That is what I really want! I added peco handler to the handle_hotkeys script and it works fine! Please review my pull request which has a peco handler and a minor bug fix.

@hanslub42
Copy link
Owner

All merged and done. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants