views:

39

answers:

3

I'm trying to write an alias for cd !!:1, which takes the 2nd word of the previous command, and changes to the directory of that name. For instance, if I type

rails new_project  
cd !!:1  

the second line will cd into the "new_project" directory.

Since !!:1 is awkward to type (even though it's short, it requires three SHIFTed keys, on opposite sides of of the keyboard, and then an unSHIFTed version of the key that was typed twice SHIFTed), I want to just type something like

cd-  

but since the !!:1 is evaluated on the command line, I (OBVIOUSLY) can't just do

alias cd-=!!:1  

or I'd be saving an alias that contained "new_project" hard-coded into it. So I tried

alias cd-='!!:1'  

The problem with this is that the !!:1 is NEVER evaluated, and I get a message that no directory named !!:1 exists. How can I make an alias where the history substitution is evaluated AT THE TIME I ISSUE THE ALIAS COMMAND, not when I define the alias, and not never?

(I've tried this in both bash and zsh, and get the same results in both.)

+2  A: 
alias cd-='cd $(history -p !!:1)'
Teddy
Very nice in bash: thank you! It unfortunately doesn't work in zsh. man history and history --help are useless, and I haven't been able to find anything via Googling... any ideas?
Brandon
`history` is a built-in zsh command. Use `man zshbuiltins`.
ZyX
+1  A: 

Another way to accomplish the same thing:

For the last argument:

cd Alt-.

or

cd Esc .

For the first argument:

cd Alt-Ctrl-y

or

cd Esc Ctrl-y

Dennis Williamson
+1  A: 

For zsh:

alias cd-='cd ${${(z)$(fc -l -1)}[3]}'

How this works:

  1. $(fc -l -1) is evaluated. fc -l {start} [{end}] means «list history commands from {start} till {end} or last if {end} is not present».
  2. ${(z)...} must split ... into an array just like the shell does (see «Parameter Expansion Flags» in man zshexpn), but in fact it splits on blanks. Maybe it is only my bug.
  3. ${...[3]} takes third value from the array. First value is a number of a command, second is command and third and later are arguments.
ZyX
Awesome. Thanks! I tried voting it up (and would do the same for the bash version as well) but I lack the necessary 15 reputation points. But thanks for sharing your expertise, and especially for breaking it down.
Brandon