sebastiandaschner blog


Increasing Shell Productivity With Zsh Aliases

#productivity #linux #commandline sunday, june 24, 2018

The zsh shell, such as many others, supports aliases to minimize the amount of typing required. Beside simple command aliases, zsh comes with a multitude of extended alias features.

Normal, or command aliases are very helpful for commands that you keep typing all over again. How often do you type git status, mvn clean install, or docker build yourself, manually? (And how often do you swear at yourself for misspelling them?)

Command alias definitions, such as alias gst='git status', make your command line life much easier. The oh-my-zsh extension for example already ships with many required Git aliases.

Alias Expansion

To know with which command the typed alias is being substituted it helps a lot to actually see the expanded command once you hit the space bar. However, there are also commands that you deliberately don’t want to expand with a space at the end, such as curl localhost:, to be able to continue typing right away. And also, there are commands that you might not want to expand at all, such as l which I aliased to exa -ahl, an alternative to ls.

zsh autocompletion

I’ve included an extra functionality into my zsh configuration that handles these cases. The following shows my the current configuration code; I’m not a zsh scripting expert, so please don’t judge the code too hard :-)

# blank aliases
typeset -a baliases
baliases=()

balias() {
  alias $@
  args="$@"
  args=${args%%\=*}
  baliases+=(${args##* })
}

# ignored aliases
typeset -a ialiases
ialiases=()

ialias() {
  alias $@
  args="$@"
  args=${args%%\=*}
  ialiases+=(${args##* })
}

# functionality
expand-alias-space() {
  [[ $LBUFFER =~ "\<(${(j:|:)baliases})\$" ]]; insertBlank=$?
  if [[ ! $LBUFFER =~ "\<(${(j:|:)ialiases})\$" ]]; then
    zle _expand_alias
  fi
  zle self-insert
  if [[ "$insertBlank" = "0" ]]; then
    zle backward-delete-char
  fi
}
zle -N expand-alias-space

bindkey " " expand-alias-space
bindkey -M isearch " " magic-space

Another thing to take into account are global aliases. Normally command aliases are only substituted if they’re at the beginning of the line. Global aliases are substituted anywhere on the line.

That is, I have now following methods to define aliases that are supposed to be expanded:

# command aliases
alias jj='java -jar'
alias mcp='mvn clean package'
...

# blank aliases, without trailing whitespace
balias clh='curl localhost:'
...

# "ignored" aliases, not expanded
ialias l='exa -al'
ialias curl='curl --silent --show-error'
...

# global aliases
alias -g L='| less'
alias -g G='| grep'
ialias -g grep='grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn}'

Suffix Aliases

Zsh also supports suffix aliases, another very helpful feature that allows to open specific programs for files that are typed into the command line, depending on their extensions.

$> file.pdf
# will open PDF viewer with file.pdf in background

I included a zsh functionality that opens a program with the file loaded in background:

# starts one or multiple args as programs in background
background() {
  for ((i=2;i<=$#;i++)); do
    ${@[1]} ${@[$i]} &> /dev/null &
  done
}

This enables to define suffix aliases that open programs in the background.

alias -s html='background chromium'
alias -s {pdf,PDF}='background mupdf'
alias -s {mp4,MP4,mov,MOV}='background vlc'
alias -s {zip,ZIP}="unzip -l"
...

 

I hope you’ll enjoy replacing your most commonly used commands with aliases. I, for now, have defined more than 300 of these little helpers :-) Over time, you’ll save yourself a lot of time and typing.

 

Found the post useful? Then you might enjoy my Developer Productivity Masterclass.