gabrielgio.me @ a1371930d5d3e44fc11078f697f82ac607476faa

  1---
  2title:  "Shortcutting with fish shell"
  3date:   2022-02-23
  4tags: ['fish', 'linux', 'shell']
  5---
  6
  7For some time now I have been using fish shell[^1] as my default shell and it
  8has been a great experience. It has sane defaults and with almost no work I
  9have a perfectly function shell with a great auto completion engine. I have
 10also tried zsh before and although it is great shell it require some work to
 11come to same level of fish, even after you include oh-my-zsh[^2] (which I'd
 12highly recommend to use if you are starting to use zsh). One thing to keep in
 13mind is that  fish is far from sh or bash compatible, so if you have something
 14built in sh or bash it won't work with fish. Anyhow, what I want to show here
 15is how much you can optimize your workflow with just a couple lines of shell.
 16
 17## The use case
 18
 19As an assiduous user of terminal I constantly need to jump from folder to
 20folder between projects I’m working on whether to run an editor or to use git.
 21
 22Normally I'd just type `cd ~/Git/gabrielgio` and from there to another folder,
 23but we can do better with fish (or any other shell actually) by assigning this
 24action to a keystroke. However before we can add the shortcut itself lets first
 25create a function to jump into the folder, to do so we will be using the `fzf`
 26where the man page states:
 27
 28> a command-line fuzzy finder
 29
 30That will provide a nice way to search and pick from arbitrary list. You can
 31get quick glance of how it work just type `find . | fzf` and it will open the
 32fuzzy finder buffer interactively search for input keyword. To expose this
 33functions of ours we are going to use a nice feature from fish which autoloads
 34function[^3]  from all the `.fish` files from all folders listed in
 35`$fish_function_path`. So we will be using the `~/.config/fish/functions`
 36folder. Add a new file called `jumpin.fish` with the following content:
 37
 38```fish
 39# ~/.config/fish/functions/jumpin.fish
 40function jumpin
 41end
 42```
 43
 44Now lets plug `fzf` into that function.
 45
 46
 47```fish
 48# ~/.config/fish/functions/jumpin.fish
 49function jumpin
 50    set selected (ls ~/Git | fzf)
 51    pushd ~/Git/$selected
 52end
 53```
 54
 55We are going to pip `ls` result into `fzf` then `set`[^4]  result of `fzf` into
 56a variable. The return value of `fzf` is the value you have selected. As you
 57can infer from the script I'm listing all my folder from `Git` folder where I
 58store all my projects which are the folder I, most of the time, want to jump
 59right in. It can be literally anything you may find useful, you may want to try
 60to search using a broader scope by:
 61
 62```sh
 63find ~/ -type d | fzf
 64```
 65
 66Whatever fits you better, the end goal here is to get start customizing and
 67optimizing your workflow so you can more comfortably moving around.
 68
 69Now, it is almost done we just need the check if the `selected` has value. The
 70user can cancel the selection (e.g.: by pressing esc) and then the `selected`
 71variable would be empty. To check that we just need an if:
 72
 73```fish
 74# ~/.config/fish/functions/jumpin.fish
 75function jumpin
 76    set selected (ls ~/Git | fzf)
 77    if [ "$selected" ]
 78        cd ~/Git/$selected
 79    end
 80end
 81```
 82
 83You will need to  reopen your terminal emulator or if you source it so the
 84function become available.
 85
 86```fish
 87# how to source it
 88source ~/.config/fish/functions/jumpin.fish
 89```
 90
 91Then type `jumpin` and let `fzf` do the work.
 92
 93Now we can jump to a folder even faster by assigning a shortcut to a function
 94and again fish comes to rescue to make our life easier. It provider a bind[^5]
 95function to bind (duh) sequence of characters to a function. Inside of you
 96`~/.config/fish/` there will be a `config.fish` with a function called
 97`fish_user_key_bindings` which fish will automatically execute. We will use
 98that function (as the name implies) to bind our command to a keystroke. To do
 99so use the bind function:
100
101```fish
102# ~/.config/fish/config.fish
103function fish_user_key_bindings
104  # ...
105  bind \ck 'jumpin'
106end
107```
108
109Once again reopen the terminal or source the configuration file. Now once you
110press `Ctrl+k` it will pop the `fzf` list picker and after you select something
111you will jump right into the folder. Due to the fuzzy finder algorithm you
112won't need to type more then a couple of char making the whole process really
113fast.
114
115This is just a jump start to using script to make your life easier. Shell
116scripting is a powerful tool for a programmer and it will definitely pay some
117dividends if you spend time to master it.
118
119[^1]: https://fishshell.com/
120[^2]: https://ohmyz.sh
121[^3]: https://fishshell.com/docs/current/language.html#autoloading-functions
122[^4]: https://fishshell.com/docs/current/cmds/set.html
123[^5]: https://fishshell.com/docs/current/cmds/bind.html