2

In Fish shell I have two functions:

function be
  bundle exec $argv
end

function rdbm
  rake db:migrate
end

I typically use them together, i.e. bundle exec rake db:migrate but not always, so I'd like to keep them separate.

The problem is that I cannot do this with the aliases I have currently defined:

To say be rdbm expands the first function (be) but passes rdbm as a literal string (non-expanded).

I have also tried abbr:

abbr be 'bundle exec'
abbr rdbm 'rake db:migrate'

But only the first expands.

I've figured out that it's possible to call functions from other functions:

function be_rdbm
  echo (be rake db:migrate)
end

but this doesn't decouple the two functions, since the second is not being used.

By the way, I'd like to know if that last example can be improved. I don't see why the echo should be necessary (or what alternatives there are), but I cannot put the parenthesis as the entire content of the function.

2 Answers 2

2

Personally I would just define another abbreviation for the combined case. However, you can define your rdbms function as follows to allow you to combine it with your be function as be (rdbm):

function rdbm
    if status --is-command-substitution
        echo rake db:migrate
    else
        rake db:migrate
    end
end

You could also modify your be function so that you can type just type be rdbm when used with the previous change:

function be
    if test "$argv" = "rdbm"
        bundle exec (rdbm)
    else
        bundle exec $argv
    end
end
7
  • This is cool and thanks. But its not true concatenation of the commands. Its not necessarily sufficient to pass the second result through echo. What if its an interactive script for instance. Commented Dec 20, 2016 at 21:00
  • It's impossible to concatenate commands in the manner you're suggesting in any shell without using a trick like I posted. Commented Dec 21, 2016 at 22:51
  • Oh, thats too bad. Thats just what I was wondering Commented Dec 21, 2016 at 22:53
  • To be honest I really hoped that would be possible though. Like after all this time terminals still lack this functionality. Is there a reason its not done? Commented Dec 21, 2016 at 22:55
  • By "terminal" I assume you mean shell since your terminal has nothing to do with this. As Glenn Jackman pointed out in his answer zsh does allow this if you enable its "global alias" feature. But that behavior is dangerous so fish does not have an equivalent. Note that what zsh calls an alias fish calls an abbreviation. In fish abbreviations are only expanded in the command position (which is the default zsh behavior). Commented Dec 22, 2016 at 0:28
1

zsh has a "global alias" feature, where the alias is substituted anywhere in the line. But fish only substitutes the first word in the command line.

You could do this:

function rdbm
  if [ (count $argv) = 1 ]; and [ $argv[1] = "-n" ]
    echo "rake db:migrate"
  else
    rake db:migrate
  end
end

Then you would have to type

be (rdbm -n)
1
  • Thanks very much. But like the other answer, this isnt true concatenation of commands. What if the second command is an interactive script? Then echo wont work Commented Dec 20, 2016 at 21:48

You must log in to answer this question.

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