gabrielgio.me @ master

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