1

I have [left arrow] [right arrow] mapped to backward/forward char, and [ctrl-left-arrow] [ctrl-right-arrow] mapped to backward/forward word"

Sometimes I want to move back and forward to the previous/next occurance of any of a list of characters. For example in a long command or long path, it's useful to move back/forward to the previous or next [ / | ; _ ] as these are common major separators.

Looking at man zshzle it looks like it should be possible, but what would the appropriate commands look like?

Stilez
  • 1,825

1 Answers1

1

jump-target

is a tool for such moves -- very versatile, but on the cost of some additional key-strokes.

Let's assume, it is bound to CTRL+Y. Then you press CTRL+Y, release and press ; and release. jump-target then highlights all occurences of ; in the commandline and labels them with a through z:

 # this; is; a; nonsense; command; line

becomes

enter image description here

Now just press a, b, c,... to jump with your cursor to the respective position.

shell function

However, it's also easy to write a specific function which is doing what you want. Credits for the original idea are going to the author of this blogpost, I adapted the code to your demands:

    function backward-shell-block()          # original code from http://www.longhaired.org/blogg/individuell/2007-04-29-zsh
    {                                        # adapted by mpy at https://superuser.com/a/1407146/195224
      local blocks block colons commandline
      commandline=${LBUFFER//[\[\]\/|;_]/;}  # replace al disired block separators with ;
      blocks=("${(s:;:)commandline/\~/_}")   # split at ; and replace ~ to prevent FILENAME EXPANSION messing things up
      block=$blocks[-1]
      colons=-1
      while [[ $commandline[$colons] == ";" ]]; do
        (( colons-- ))
      done
      (( CURSOR -= $#block - $colons ))
    }
    function forward-shell-block()
    {
      local blocks block colons commandline
      commandline=${RBUFFER//[\[\]\/|;_]/;}
      blocks=("${(s:;:)commandline/\~/_}")
      if [[ $commandline[1] == ";" ]]; then
        block=$blocks[2]
      else
        block=$blocks[1]
      fi
      colons=1
      while [[ $commandline[$colons] == ";" ]]; do
        (( colons++ ))
      done
      (( CURSOR += $#block + $colons -1 ))
    }

    zle -N backward-shell-block
    zle -N forward-shell-block
    bindkey '^W' backward-shell-block
    bindkey '^E' forward-shell-block

Here I bound the left and right jumping functions to CTRL+W and CTRL+E, resp.

mpy
  • 28,816