---
date: 2024-06-21
title: Dotfiles
tags: 
  - homelab
  - linux
  - bash
  - development
---

In [my previous post](https://blog.mcknight.tech/2024/04/21/Kubernetes-Tools/#Future-Plans), 
I mentioned syncing dotfiles as a future task. I considered using Nextcloud to sync my home 
directory, but realistically I only want a small subset of files to sync between devices. I
also don't necessarily want to share sensitive data like SSH keys or device-specific 
configuration the same way I do dotfiles. For now, I've decided to put things in a
git [repository](https://git.mcknight.tech/d_mcknight/dotfiles); this makes updates simple `git` actions
and allows me to pull everything to a new environment easily.

## `.bashrc`
I [previously documented my .bashrc](https://blog.mcknight.tech/2024/03/27/Shell-Customizations/#BASH-Configuration)
but have added a couple new things.

```shell
alias sudosu="sudo bash --rcfile ~/.bashrc"

if [ -n "${SUDO_USER}" ]; then
  alias nano="nano --rcfile \"/home/${SUDO_USER}/.nanorc\""
fi
```

The `sudosu` alias allows me to open a root shell with my customized `.bashrc`, without modifying the `root` directory.
This means any changes to `~/.bashrc` are available in an elevated shell automatically. The `nano` alias likewise
applies customizations in an elevated shell.

## `.nanorc`
The `nanorc` file is [documented here](https://www.nano-editor.org/dist/latest/nanorc.5.html). I keep mine at
`~/.nanorc` for simplicity and have a few customizations:

```
set smarthome
# home goes to the first non-whitespace character instead of the start of the line
set keycolor cyan,gray
set titlecolor cyan,gray
# color to match my other terminal customizations
```

There are many other ways to customize `nano`, and many other editors available.

## `.tmux.conf`
As I continue to use `tmux`, I've found some helpful customizations that make it
easier to use. The config file is pretty big, so I'll go over it in sections.

```
# Custom Prefix
set -g prefix C-space
```
Rebinds the prefix to `ctrl`+`space` which is a bit easier to reach than 
`ctrl`+`c`.

```
# Shortcut to sync panes
bind C-x setw synchronize-panes
```
Adds a shorcut to synchronize inputs between all panes. This is occasionally useful
for things like benchmarking multiple systems, or running tasks in parallel.

```
# Shortcut to respawn panw
bind M-r respawn-pane -k
```
This is particularly useful on my laptop, where I'll sleep the machine with an SSH
session left over and come back later. This preserves the pane layout but kills any
processes (like a dead SSH session).


```
# Mouse Scrolling
set -g mouse on
```
Enables mouse actions, such as scrolling and pane selection/resizing.


```
# Mouse Copy
bind -T copy-mode    C-C send -X copy-pipe-no-clear "xsel -i --clipboard"\; display "Copied"
bind -T copy-mode-vi C-C send -X copy-pipe-no-clear "xsel -i --clipboard"\; display "Copied"
```
Enables copying highlighted text with `ctrl`+`c`; I prefer using the mouse over the
keyboard shortcuts, mostly because its what I'm used to.


```
# Split
bind S-down split-window -v
bind S-right split-window -h
```
Rebinds `shift`+`down` and `shift`+`right` to open a new split below or to the right
of the selected window. Much easier to remember than the defaults that I've already
forgotten.
> These are both handled after the prefix command.


```
# Navigation
bind -n C-Left select-pane -L
bind -n C-Right select-pane -R
bind -n C-Up select-pane -U
bind -n C-Down select-pane -D

bind -n C-S-Left previous-window
bind -n C-S-Right next-window
```
Faster keybindings to navigate between panes and easier to remember bindings to switch
views. `ctrl`+arrow to move between panes (no prefix required) and 
`ctrl`+`shift`+`left`/`right` to move between windows.


```
# Config
bind R source-file ~/.tmux.conf \; display "Config reloaded!"
```
Adds a shortcut (`shift`+`R`) to reload config and display a confirmation
in the lower left of the window.

```
# Colors
set -g default-terminal "screen-256color"
set -g pane-border-style fg='#008b8b'
set -g pane-active-border-style fg='#34E2E2'

set -g message-style bg='#222222',fg='#34E2E2'
set -g status-style bg='#222222',fg='#AD7FA8'
```
Sets window chrome to match other colors (`nano` and my custom prompt).

```
# Status
set -g status-left '#{?client_prefix,#[fg=#008b8b]█, }'
set -g status-interval 1
set-window-option -g window-status-style fg='#008b8b',bg=default
set-window-option -g window-status-current-style fg='#222222',bg='#ad7fa8'
```
Customizes the status bar. When the prefix is pressed,
a colored block in the bottom left of the terminal provides visual
confirmation (especially helpful when you have nested tmux sessions,
such as an SSH connection where the remote is also running tmux).
 The status styling gives the active window an inverted
scheme to be easily identified at a glance.


I figured out most of this through trial and error and anticipate more
changes as I continue to adapt my workflows to use `tmux`. There are
countless guides and examples on the internet, so I will definitely be
experimenting with more plugins and options.

## `.dircolors`
For most cases, the default highlighting in directory listings works great.
I've noticed in a few terminals though, you can end up with low contrast
between text and background colors. If you're customizing everything in
`tmux` as I am, it is nice to make sure text from `ls`, etc. matches the
overall theme, and more importantly is easy to read.

To load custom directory colors, I added to my `.bashrc`:

```shell
[ -f ~/.dircolors ] && eval "$(dircolors ~/.dircolors)" 
```

To generate the default `.dircolors` file:
```shell
dircolors -p > .dircolors
```

I left the majority of these as the default values, but there were two
fields I changed because the green text on blue background was very low
contrast and hard to read:

```
STICKY_OTHER_WRITABLE 30;45 # dir that is sticky and other-writable (+t,o+w)
OTHER_WRITABLE 26;45 # dir that is other-writable (o+w) and not sticky
```

I wasn't able to find an official reference for the color codes used here,
but [this StackExchange post](https://unix.stackexchange.com/a/94505) was
a very helpful reference.

## Synchronizing Changes
As mentioned in the beginning of this post, all of these files are saved
in a git repository for easy synchronization. To link the repo files to
the expected locations, I have a simple `setup` script along with the
dotfiles. This only needs to be run once on a computer and then any
subsequent updates are simply pulled from git.

> Side note, if you're not using SSH for git operations, do it. I spent
  years dealing with tokens for password authentication (realistically,
  my IDE did this automatically 99% of the time) and just uploading a
  key to GitHub/GitLab and replacing `http` with `ssh` obviates the
  whole thing.
