--- title: "Shortcutting with fish shell" date: 2022-02-23 tags: ['fish', 'linux', 'shell'] --- For some time now I have been using fish shell[^1] as my default shell and it has been a great experience. It has sane defaults and with almost no work I have a perfectly function shell with a great auto completion engine. I have also tried zsh before and although it is great shell it require some work to come to same level of fish, even after you include oh-my-zsh[^2] (which I'd highly recommend to use if you are starting to use zsh). One thing to keep in mind is that fish is far from sh or bash compatible, so if you have something built in sh or bash it won't work with fish. Anyhow, what I want to show here is how much you can optimize your workflow with just a couple lines of shell. ## The use case As an assiduous user of terminal I constantly need to jump from folder to folder between projects I’m working on whether to run an editor or to use git. Normally I'd just type `cd ~/Git/gabrielgio` and from there to another folder, but we can do better with fish (or any other shell actually) by assigning this action to a keystroke. However before we can add the shortcut itself lets first create a function to jump into the folder, to do so we will be using the `fzf` where the man page states: > a command-line fuzzy finder That will provide a nice way to search and pick from arbitrary list. You can get quick glance of how it work just type `find . | fzf` and it will open the fuzzy finder buffer interactively search for input keyword. To expose this functions of ours we are going to use a nice feature from fish which autoloads function[^3] from all the `.fish` files from all folders listed in `$fish_function_path`. So we will be using the `~/.config/fish/functions` folder. Add a new file called `jumpin.fish` with the following content: ```fish # ~/.config/fish/functions/jumpin.fish function jumpin end ``` Now lets plug `fzf` into that function. ```fish # ~/.config/fish/functions/jumpin.fish function jumpin set selected (ls ~/Git | fzf) pushd ~/Git/$selected end ``` We are going to pip `ls` result into `fzf` then `set`[^4] result of `fzf` into a variable. The return value of `fzf` is the value you have selected. As you can infer from the script I'm listing all my folder from `Git` folder where I store all my projects which are the folder I, most of the time, want to jump right in. It can be literally anything you may find useful, you may want to try to search using a broader scope by: ```sh find ~/ -type d | fzf ``` Whatever fits you better, the end goal here is to get start customizing and optimizing your workflow so you can more comfortably moving around. Now, it is almost done we just need the check if the `selected` has value. The user can cancel the selection (e.g.: by pressing esc) and then the `selected` variable would be empty. To check that we just need an if: ```fish # ~/.config/fish/functions/jumpin.fish function jumpin set selected (ls ~/Git | fzf) if [ "$selected" ] cd ~/Git/$selected end end ``` You will need to reopen your terminal emulator or if you source it so the function become available. ```fish # how to source it source ~/.config/fish/functions/jumpin.fish ``` Then type `jumpin` and let `fzf` do the work. Now we can jump to a folder even faster by assigning a shortcut to a function and again fish comes to rescue to make our life easier. It provider a bind[^5] function to bind (duh) sequence of characters to a function. Inside of you `~/.config/fish/` there will be a `config.fish` with a function called `fish_user_key_bindings` which fish will automatically execute. We will use that function (as the name implies) to bind our command to a keystroke. To do so use the bind function: ```fish # ~/.config/fish/config.fish function fish_user_key_bindings # ... bind \ck 'jumpin' end ``` Once again reopen the terminal or source the configuration file. Now once you press `Ctrl+k` it will pop the `fzf` list picker and after you select something you will jump right into the folder. Due to the fuzzy finder algorithm you won't need to type more then a couple of char making the whole process really fast. This is just a jump start to using script to make your life easier. Shell scripting is a powerful tool for a programmer and it will definitely pay some dividends if you spend time to master it. [^1]: https://fishshell.com/ [^2]: https://ohmyz.sh [^3]: https://fishshell.com/docs/current/language.html#autoloading-functions [^4]: https://fishshell.com/docs/current/cmds/set.html [^5]: https://fishshell.com/docs/current/cmds/bind.html