5

When I iterate over previous commands in bash history, cursor position always jumps at the end of the command. I want some way of remembering current cursor position of last executed command.

This can be useful when trying different command line options for some command. Now I have to press up key and move cursor backwards to where the option was typed to edit it. I want to eliminate this second step if it is possible.

I am using bash, but solutions for other shells are also interesting.

3
  • You can use Ctrl-R and Ctrl-S to search backwards/forward, or Ctrl-A, Ctrl-E, Alt-F, Alt-N for faster movement.
    – choroba
    Commented Dec 9, 2016 at 16:37
  • Also, you can change the command to o=-a script.sh $o -other -options and only change the value of $o.
    – choroba
    Commented Dec 9, 2016 at 16:39
  • 1
    You replace specific parts of a previous command with carets. echo "Hello" will print Hello afterwards you can do ^Hello^World^to replace Hello with Worldand now the command will be echo "World" You can use that to switch command line options. Commented Dec 9, 2016 at 16:43

4 Answers 4

1

Maybe this is the option you're looking for?

history-preserve-point (Off)
        If  set to On, the history code attempts to place point at the
        same location on each history line retrieved 
        with previous-history or next-history.

To turn it on, add this to your ~/.inputrc:

set history-preserve-point on
1
  • Yes, it works, thanks.
    – ks1322
    Commented Feb 15, 2021 at 19:06
1

This almost works.

__insert_last_history_entry() {

    READLINE_LINE=$(history -p '!!')
}

bind -x '"\ea" : __insert_last_history_entry'   # Alt-a

Save this in a file (say, insertLastHistory) and source it on the command line:

. insertLastHistory

(or, alternatively, insert its contents into your ~/.bashrc and restart the shell).

Alt-a triggers the new behaviour.

It doesn't change the cursor position 🎉🎉🎉, but it inserts the penultimate entry instead of the last one. Don't know why. Wasn't able to fix it.

Maybe someone else can build on this and crack the last piece of the puzzle.

1

In zsh, to remember the cursor position for each history entry and recall it each time you recall a history entry, you'd add to your ~/.zshrc:

typeset -A cursor_history
save-cursor()    cursor_history[$HISTNO]=$CURSOR
restore-cursor() CURSOR=${cursor_history[$HISTNO]-$CURSOR}

autoload -Uz add-zle-hook-widget
add-zle-hook-widget line-finish      save-cursor
add-zle-hook-widget history-line-set restore-cursor

(note that that history is not preserved between shell invocations, only within the current shell session).

It also doesn't save the current cursor position when you leave the currently edited line. For that, you'd also need to wrap at least all history motion widgets so they do a save-cursor first:

for w (${(Mk)widgets:#.*hist*}) {
  functions[${w#.}]='save-cursor; zle '$w
  zle -N ${w#?}
}
0

Caveats:

  • This solution involves tmux
  • It doesn't actually remember the cursor position: it just positions the cursor at the beggining of the line instead of the end.

  1. Add this to your ~/.tmux.conf:

    ###############################################
    ## Last command line + Home
    
    bind -n 'C-a'    send-keys Up \; send-keys Home
    
  2. Reload the tmux configuration

    tmux source-file ~/.tmux.conf
    

Then when you press Ctrl+a, bash will receive Up, followed by Home.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .