Personally I like to use the terminal as much as possible, and by doing so I have a few useful tools in my 'toolbox' for my day-to-day work as a developer. This blog is the first in a trilogy, covering all the tools that I use almost daily. This first part will be all about the terminal itself. Which terminal I use, which shell I use, and how I have customized its looks.

iTerm2

Although iTerm2 is for MacOS only, I still want to mention it as it is usually the first thing I install. The biggest benefit of using iTerm2 is its configurability. It has tons of things you can configure from a visual perspective, so you can make it look however you want. But its best feature is its 'Hotkey window', which shows a terminal window on the top of your window whenever you press the hotkey for it:

iterm2 hotkey window

I use the ±§ key, which is left of the 1 key on my keyboard. This way I have fast access to my terminal whenever I need to do something, which definitely makes my workflow much more efficient.

For other features see the iTerm2 website.

If you use a Linux distro, I would recommend one of the following terminals: Guake, Tilda, Konsole.

fish shell

Usually a unix based system comes with bash, or in the case of MacOS it now comes with zshell by default. Personally I like to use fish shell. The main reason is its ease to create functions, and its autocomplete. To install it run brew install fish, and for other systems see the fish website. And don’t forget to set it as your default shell.

Let me explain how the autocomplete works. In my case, I have certain commands I run in specific directories. For example, I use mvn clean package very often. When I am in a directory where I have used that command, fish already suggests the full command when I type m:

fish autocomplete

However, if I run the command mvn clean package -Psome-profile often for another project, it will suggest that instead when I type m:

fish autocomplete2

So the autocomplete is context aware, making it a very useful feature for me, especially since I have a lot of projects that I work on.

fish functions

With fish it is easy to create new functions/scripts to automate or simplify your workflow. Fish does not support aliases, so creating a function is the way to create an alias.

You can create any function in the directory ~/.config/fish/functions. Here is a simple function that I use myself httpserver.fish:

function httpserver
  python3 -m http.server
end

The function has to have the same name as the file, httpserver in this case. After creating the file you can directly run it by using the name of the function httpserver. This function starts a HTTP server, serving the files from the current directory.

Another example is my check-port.fish function:

function check-port
    if contains -- --help $argv
        echo 'Checks wether a given port is in use. Usage: check-port 8080'
    else
        lsof -i TCP:$argv | grep LISTEN
    end
end

This function will check if a certain port is in use. If it fails, the port is unused. If the port is used, it will print the details of the port.

You can use fish functions to also temporarily set some environment variables. In my case it is useful for Android development for example. It uses an older Java version, so I have to set JAVA_HOME to a different java version. To load all android tooling I created the following fish function android-env.fish:

function android-env
  set -x JAVA_HOME /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home
  set -x ANDROID_HOME /usr/local/Caskroom/android-sdk/4333796
  set -x PATH $PATH $ANDROID_HOME/tools $ANDROID_HOME/platform-tools
end

This will set the variables for your current window of your terminal only, so it does not change your java version for your whole system.

One final example is loading a file which contains tons of environment variables, making it easy to switch settings. You could have a file for local, and one for test, one for prod for example. load-env.fish:

function load-env
    if contains -- --help $argv
        echo 'Loads environment variables from a file, which should contain one variable per line:'
        echo 'MY_VARIABLE=bla'
        echo ''
        echo 'Example usage: load-env ~/Documents/my-env-file'
    else
	      for i in (cat $argv)
		        set line (echo $i |tr = \n)
  		      set -gx $line[1] $line[2]
	      end
    end
end

These were just a few examples that I use myself. You can create any function you want, also see the fish tutorial page for more information about fish functions.

Changing how it looks

As you might have noticed, I have a certain theme for my fish shell. It shows the current branch for git, and color codes it if there are changes for example:

fish visuals

To install the same theme, first we have to install oh-my-fish: curl -L https://get.oh-my.fish | fish. When oh-my-fish is installed, you can install any theme it supports. I use the agnoster theme, so run omf install agnoster.

The agnoster theme also uses symbols from the Powerline fonts, so install a font you like. I use Roboto Mono for Powerline.ttf.

Last step is configuring the colors for your terminal. In the case of iTerm2 you can select the theme 'Solarized Dark', and select the font you just installed, and you should be done.

shadow-left