3

I am trying to create an alias that builds upon my previous command.

Say I run

ag foo

After looking at the list I want to be able to use those results in vim so I do

vim -q<(!! --vimgrep)

The alias I want is

alias edit-last='vim -q<(!! --vimgrep)'

But I can't seem to use !! in my alias. I'm having a hard time finding info about what the !! is, a built-in, an alias

2
  • It must be possible with some combination of fc command
    – balki
    Apr 8 '15 at 17:41
  • 1
    fc -ln -1 is what you want, !! is history expansion and is explained in zshexpn. the very first page gives you the order of operations when it comes to expansions.
    – llua
    Apr 8 '15 at 20:33
2

!! is history expansion. The first ! starts a history expansion; !! has the event designator meaning the previous command.

You can access the command history via the fc and history builtins and via the history variable.

Since --vimgrep only makes sense with ag, your alias would be more useful if it applied to the last ag command. You can locate the previous ag command like this:

${${(M)history:#ag *}[1]}

Furthermore you'll need to inject the --vimgrep into the command.

alias edit-last='vim -q<(eval "${${(M)history:#ag *}[1]} --vimgrep")'

The last ag command won't make sense anymore if you've changed the current directory. This is difficult to detect. You may want to whitelist acceptable commands instead. This isn't a perfect test of course.

edit-last () {
  local cmd
  setopt local_options extended_glob
  for cmd in $history; do
    case $cmd in
      ((ls|(cvs|git|hg|svn) status)(| *)) :;;
      ("ag "*) vim -q<(eval "$cmd --vimgrep"); return;;
      (edit-last) :;;
      (*) echo >&2 "The previous ag command is too old."; return 125;;
    esac
  done
}
1
  • Absolutlely amazing! I learned more reading this sample than I did in 2 hours of googling. Thank you Apr 10 '15 at 20:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.