7

I was reading the git.fish completion script (/usr/local/Cellar/fish/2.1.2/share/fish/completions) for fish shell and I ran into some problems with understanding what the syntax means.

In the block,

function __fish_git_needs_command
  set cmd (commandline -opc)
  if [ (count $cmd) -eq 1 -a $cmd[1] = 'git' ]
    return 0
  end
  return 1
end

I understand that cmd is set as commandline -opc. But in the next statement (count $cmd) -eq 1 -a $cmd[1] = 'git', what do -eq and -a mean?

I am new to fish shell and I am trying to understand the syntax by trying to write my own completion script for a program. Help would be greatly appreciated.

Thank you.

Hasit Mistry
  • 329
  • 1
  • 4
  • 18

3 Answers3

10

In fact -eq and -a are not part of fish syntax. They are ordinary arguments!

if [ (count $cmd) -eq 1 -a $cmd[1] = 'git' ]

The opening square bracket here is actually a command, like cat or grep. You really do have a file /bin/[. It may be easier to understand via the test command, which is the same thing:

if test (count $cmd) -eq 1 -a $cmd[1] = 'git'

Now it's easy to see that -eq and -a are just ordinary arguments being passed to test, with no syntactic significance to fish.

test has its own little language like awk or sed. See man test to learn about it.

ridiculous_fish
  • 17,273
  • 1
  • 54
  • 61
2

The -eq is an integer comparison function.

The -a is a logical and.

So the logical equivalent would be something like:

if [ (count $cmd) == 1 && $cmd[1] == 'git' ]

(in Java pseudo-syntax).

Background

The reason why -eq is used is because a shell normally works with text processing only. As a result numbers are stored in "strings". Sometimes two numbers are equivalent, but not string-equivalent. For instance the following example:

if [ "01" -eq "1" ]
then
    echo "integer equal"
fi
if [ "01" = "1" ]
then
    echo "string equal"
fi

Will only print integer equal.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

From the Fish documentation :

  • NUM1 -eq NUM2 returns true if NUM1 and NUM2 are numerically equal.
  • COND1 -a COND2 returns true if both COND1 and COND2 are true.

It tests that (count $cmd) = 1 and that $cmd[1] = 'git'.
(= here being equality, not an assignment).

Marth
  • 23,920
  • 3
  • 60
  • 72
  • 1
    Thank you. I was looking for that exact link. I looked all around the place using different search terms but just couldn't find it. – Hasit Mistry May 26 '15 at 05:52