Fish Shell Function
Tags: fish, shell, function
Published: 2022-04-21 11:03:13

## My PATH has so duplicated paths

I was cleaning up my PATH environment value yesterday
and I found my path has so many duplicated paths inside.

## My duplicated PATH env.
```fish
~> set -S PATH
$PATH: set in global scope, exported, a path variable with 27 elements
$PATH[1]: |/home/myoungjin/.local/share/go/bin|
$PATH[2]: |/home/myoungjin/.local/share/rakudo/share/perl6/site/bin|
$PATH[3]: |/home/myoungjin/.local/share/rakudo/bin|
$PATH[4]: |/home/myoungjin/.rakudo/install/share/perl6/site/bin|
$PATH[5]: |/home/myoungjin/.rakudo/install/bin|
$PATH[6]: |/home/myoungjin/.ghcup/bin|
$PATH[7]: |/home/myoungjin/.local/bin|
$PATH[8]: |/home/myoungjin/perl5/bin|
$PATH[9]: |/home/myoungjin/sbin|
$PATH[10]: |/home/myoungjin/bin|
$PATH[11]: |/home/myoungjin/perl5/bin|
$PATH[12]: |/home/myoungjin/bin|
$PATH[13]: |/home/myoungjin/.local/share/go/bin|
$PATH[14]: |/home/myoungjin/.local/share/rakudo/share/perl6/site/bin|
$PATH[15]: |/home/myoungjin/.local/share/rakudo/bin|
$PATH[16]: |/home/myoungjin/.rakudo/install/share/perl6/site/bin|
$PATH[17]: |/home/myoungjin/.rakudo/install/bin|
$PATH[18]: |/home/myoungjin/.ghcup/bin|
$PATH[19]: |/home/myoungjin/.local/bin|
$PATH[20]: |/home/myoungjin/perl5/bin|
$PATH[21]: |/home/myoungjin/sbin|
$PATH[22]: |/home/myoungjin/bin|
$PATH[23]: |/usr/local/bin|
$PATH[24]: |/usr/bin|
$PATH[25]: |/usr/bin/site_perl|
$PATH[26]: |/usr/bin/vendor_perl|
$PATH[27]: |/usr/bin/core_perl|
```

## Starting making block of code (function)
So I found that when I added some new path for my apps in new PATH, I hadn't check its possibility of existence already in there.

There are *millions* of way to check. A famous way maybe done
by external programme.
```sh
function elem_ -d 'find first value is in the list of rest values'
    # note: fish index start from 1
    for p in $argv[2..-1]; echo $p; end | grep -q $argv[1]
end
```

But how about just using pure fish shell script by using basic
array that fish provides. so my first try was like:

```sh
function elem -d 'find first value is in the list of rest values'
    set found 0
    for arg in $argv[2..-1]
        if test $found -eq 0 && test $arg = $argv[1]
            set found 1
            break
        end
    end

    if test $found -eq 1
        true
    else
        false
    end
end


~> elem 1 1 2 3
~> echo $status
0
```

## Add A function in your fish shell permanently
now you can make a file which has file path of
**`~/.config/fish/functions/elem.fish`**

so that you can use it whenever you want to use it.

Now, we did make how to check, we could make `append_to_path` or `prepend_to_path` function like this.


## ~/.config/functions/fish/append_to_path.fish
```sh
function append_to_path -d 'append given path into PATH environment variable with checking '
    if ! elem $argv[1] $PATH
        set -x --append PATH $argv[1]
    end
end
```
So, we can append a path safely now.

```sh
# middle of ~/.config/fish/config.fish
for p in ~/perl5/bin ~/.local/share/go/bin ~/.ghcup/bin \ 
        ~/.cabal/bin

    append_to_path $p
end
```

Thank you for reading!

If you would like to know more about fish function
please visit my blog post.

- [Good, So so, Bad about Fish Shell](https://jeongoon.github.io/posts/2022-04-16-about-fish-shell.html)
- [DRY(Do not Repeat Yourself) in fish](https://jeongoon.github.io/posts/2022-04-21-make-a-fish-function.html)