DEV Community

Debopam Gupta
Debopam Gupta

Posted on

Dotfiles and how i manage them

Dotfiles are the configuration files for your system. It is what makes your $HOME, to $HOME sweet $HOME, basically your personalised settings.

In this blog, I will try to explain how my dotfiles are setup, and some settings/configurations I have. You can find a current copy of my dotfiles here, https://github.com/w3dg/dotfiles


Shell

As for the shell i am using bash. I am working on windows for the while and the standard installation of Git Bash or WSL works fine for me. As well as i have picked up and learnt my way through bash and the command line in general and hence i stick to it.

I have tried out ZSH and oh-my-zsh and its great as well. Some suggestions are to use with zsh-autosuggestions package and zsh-syntaxhighlighting package.

Bash Config

Customising bash requires you to edit your .bashrc file located in your home directory typically denoted by ~.

Here's a top level view of what i have in my .bashrc

eval "$(dircolors -b ~/.dircolors)"
Enter fullscreen mode Exit fullscreen mode

This evaluates dircolors for the ls command.

source ~/.bash/bindings.bash       # Bindings
source ~/.bash/shopts.bash         # Shopts
source ~/.bash/exports.bash        # Exports
source ~/.bash/functions.bash      # Custom functions
source ~/.bash/aliases.bash        # Aliases
source ~/.bash/git_aliases.bash    # Git aliases
Enter fullscreen mode Exit fullscreen mode

These are various keybindings, shell options, exports of environment variables, custom functions and aliases which i have enabled.

Useful Bindings

bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
Enter fullscreen mode Exit fullscreen mode

These will allow you to press the up key after typing a command to search your history to let you see the previous ways you had used it which is useful if you forgot the certain way you used a command before.

There are more, check out my dotfiles or anyone else's or research on the interet to find more!

Useful functions

ex()
{
  if [ -f "$1" ] ; then
    case $1 in
      *.tar.bz2)   tar xjf $1   ;;
      *.tar.gz)    tar xzf $1   ;;
      *.bz2)       bunzip2 $1   ;;
      *.rar)       unrar x $1   ;;
      *.gz)        gunzip $1    ;;
      *.tar)       tar xf $1    ;;
      *.tbz2)      tar xjf $1   ;;
      *.tgz)       tar xzf $1   ;;
      *.zip)       unzip $1     ;;
      *.Z)         uncompress $1;;
      *.7z)        7z x $1      ;;
      *.deb)       ar x $1      ;;
      *.tar.xz)    tar xf $1    ;;
      *.tar.zst)   unzstd $1    ;;
      *)           echo "'$1' cannot be extracted via ex()" ;;
    esac
  else
    echo "'$1' is not a valid file"
  fi
}
Enter fullscreen mode Exit fullscreen mode

This allows to extract given almost any sort of compressed file which is useful as I do not need to remember which command to use specifically.

mkcd() {
  mkdir $1 && cd $1
}
Enter fullscreen mode Exit fullscreen mode

This function makes a directory and drops you into it all at once.

A great resource I had found for my git aliases is the oh-my-zsh repo - https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/git/git.plugin.zsh

For some bling in the terminal, this line displays a ascii cow saying a random quote each time i open a terminal. This uses the fortune and cowsay programs.

fortune | cowsay
Enter fullscreen mode Exit fullscreen mode

The next 3 lines allow for utf8 input and output in the terminal.

# Allow UTF-8 input and output, instead of showing stuff like $'\0123\0456'
set input-meta on
set output-meta on
set convert-meta off
Enter fullscreen mode Exit fullscreen mode

A typical prompt of mine looks something like this -

My Prompt

Given all this custom settings and more you would obviously want to back them up and use it across machines or if you have a new machine.


How to manage the various dotfiles across machines?

Typically on Linux, people will symlink their dotfiles kept in some other directory, generally under version control, to their home directory where everything should exist to allow the programs to pick the settings up.

So, you will see people doing this,

DOTFILES=(.bash_profile .gitconfig .gitignore)

#Remove old dotfiles and replace them
for dotfile in $(echo ${DOTFILES[*]});
do
    rm ~/$(echo $dotfile)
    ln -s ~/dotfiles/$(echo $dotfile) ~/$(echo $dotfile)
done
Enter fullscreen mode Exit fullscreen mode

This code snippet above is a for loop in bash which loops through the given array of dotfiles and links them to the home directory.

Given on linux, this works very fine.

So granted I'm using Git Bash on Windows, it should work on Windows as well right?

The sad answer is no, even though there is a ln command, it doesn't seem to do anything.

So the other day, I decided to tackle this and write powershell script which does the same for me.

Heres that script,

#!/usr/bin/env pwsh

# New-Item -path $HOME\.bashrc -itemType SymbolicLink -target $HOME\code\dotfiles\.bashrc

# .bashrc .bash_profile .gitconfig .inputrc .npmrc .gitignore .dircolors
$dotfiles = (".bashrc", ".bash_profile", ".dircolors", ".gitconfig", ".gitconfig", ".inputrc", ".npmrc", ".bash")

foreach ($element in $dotfiles) {
  echo Linking $element
  New-Item -path $HOME\$element -itemType SymbolicLink -target $HOME\code\dotfiles\$element
}

Enter fullscreen mode Exit fullscreen mode

This does the same thing and now the files are correctly linked to the other directory under version control. And that directory is very much my dotfiles repository.

Top comments (0)