Why dotfiles? How to manage them?

Intro

You definitely have configured something on your machine, be it your OS, a software program or a toolbox you are using. Sometimes we are looking for a customization that makes us more productive and sometimes we just tinker with the appearance of the tool to make it the way we want. In other cases, configuring is necessary to work with the tool (e.g. Ngnix). Different programs have different ways of giving these options to the user. In this article, I only focus on config files in which you specify your configs in a text format.
Β 
πŸ“’
This article assumes you have familiarity with some basic Linux and Git commands. Otherwise, this article wouldn’t be that useful to you.

Config files

To make sure we are on the same page, I will start with an example. Since VS Code is one of the most popular IDE out there, I assume most of you at least once have come across it. Let’s see a simple example of VS Code config file.
{
  "workbench.iconTheme": "material-icon-theme",
  "editor.fontFamily": "'FiraCode Nerd Font', 'monospace'",
  "editor.fontLigatures": true,
  "workbench.colorTheme": "Panda Syntax",
  "editor.tabSize": 2,
  "vim.easymotion": true,
  "vim.incsearch": true,
  "vim.useSystemClipboard": true,
  "vim.useCtrlKeys": true,
  "vim.hlsearch": true,
  "vim.insertModeKeyBindings": [
    {
      "before": ["j", "j"],
      "after": ["<Esc>"]
    }
  ],
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "window.zoomLevel": 1
}
As you can see here you can specify various configs in a JSON format. Just looking at some of these configs you can guess what they are doing, while others might be a little hard to guess. A bunch of these are related to the editor, some are customizing the plugins that have been installed. Most tools have thorough documentation about all the options available.
Here is another example for vim config. This config is written in Vimscript.
" Disable compatibility with vi which can cause unexpected issues.
set nocompatible

" Enable type file detection. Vim will be able to try to detect the type of file in use.
filetype on

" Enable plugins and load plugin for the detected file type.
filetype plugin on

" Load an indented file for the detected file type.
filetype indent on
Β 
So far you hopefully understood the objective of these files. One thing that might be puzzling here is why on earth we should use these files? For example, in the case of VS Code, you can also use UI to change the setting. Well, YES you can, but you compromise on some factors:
  • Control
  • Management
Β 
With greater power comes greater responsibility
Β 
Till this point, If you feel that you are OK with these and you don’t care to lose the factors mentioned. The next section is not for you. On the other hand, if you are those types of people who like to tinker with different tools and might have some config files and boilerplate codes, you will highly benefit from the next section.

Beginning of the story

As I’ve been in Linux and opensource ecosystems for a couple of years. I’ve seen this pattern of storing configs in clear text more and more. As I started to tinker with them, I realized the benefit and powerful control they provide for their users. But soon I noticed a problem. As I liked to jump around between different Linux distros, the time I had to spend to restore my config in new installed Linux became larger and larger. Or even worse, consider a scenario you tinker with a config and things breaks, but you forget the line you have changed to revert back.

First solution

Here is where dot/config files management comes in. If we somehow leverage a version control system like git we could be free of all those mentioned problems. But we still don’t want to copy-paste things. Consider this immature solution. Say I want to hold fish and polybar configs in a directory and push them to GitHub. I will create a .dotfile folder in my home directory and push it to GitHub.
Β 
.dotfiles
β”œβ”€β”€ fish
β”‚   β”œβ”€β”€ .config
β”‚   β”‚   └── fish
β”‚   β”‚       β”œβ”€β”€ conf.d
β”‚   β”‚       β”œβ”€β”€ config.fish
β”‚   β”‚       β”œβ”€β”€ fish_variables
β”œβ”€β”€ polybar
β”‚   β”œβ”€β”€ .config
β”‚   β”‚   └── polybar
β”‚   β”‚       β”œβ”€β”€ colors.ini
β”‚   β”‚       β”œβ”€β”€ config
β”‚   β”‚       β”œβ”€β”€ hardware_control.ini
β”‚   β”‚       β”œβ”€β”€ hardware_info.ini
β”‚   β”‚       β”œβ”€β”€ icons.ini
β”‚   β”‚       β”œβ”€β”€ launch.sh
β”‚   β”‚       β”œβ”€β”€ modules.ini
β”‚   β”‚       └── scripts
Soon things become daunting as you need to copy-paste your config files to make sure they are in sync with your repository.
The good news is there is a solution for this. We can leverage symbolic links in Linux to handle this problem.
Β 
πŸ“Œ
A symbolic link, also known as a symlink or soft link, is a special type of file that points to another file or directory (learn more here)

A Better Solution

So now instead of copy-pasting the original files, we can move those files into the .dotiles directory and then create a symbolic link to them.
Β 
Perfect! Now we have one source of truth for all of our managed configs and we can easily sync them with a remote repository like GitHub.

Using GNU Stow

GNU stow is a tool that helps to do exactly what we did in the previous section. So here will be the step to get started with stow:
  1. Create a dotfiles directory in your home
  1. Add folders for each of the config files you want to manage (e.g. for nvim you would create ~/dotfiles/nvim)
  1. From that folder imagine you are in the home directory and add each folder through the way to the corresponding folder
    1. For instance, in the case of nvim because nvim is ~/.config/nvim/
      We would create a path like the following: ~/dotfiles/nvim/.config/nvim/
  1. You can safely mv/cut all those files inside the original path to the corresponding path in your dotfiles folder
  1. Go to the dotfiles directory and issue the following command
    1. stow nvim
      Β 
      This will create the symlink in the original path so you nvim can use the files.
  1. Now you can create a repository on GitHub or other alternatives and push your dotfiles folder there.
Β 
After you install a new system you can pull your repository and issue the same command for each folder like stow nvim and stow will do the magic for you and put symlinks into correct paths.
Β 
Now you can do this for each config file in your machine that you want to manage. If you want more in-depth steps and more understanding make sure you visit the following references. I also add my repository if you are looking for some inspiration.

Useful References

DevInsideYou: Another YouTube video with more details
ln command in Linux: Learn more about symbolic links
Β