My personal dotfiles and shell scripts
Customizes a vanilla Fedora or Ubuntu system to my preferences.
- Prerequisites
- Installation
- Setting up and maintaining a new system
- Shell scripts
- Shell customizations
- Vim customizations
-
SSH keys should already be created and configured in GitHub user settings
ssh-keygen -b 4096
-
Prerequisite packages
sudo dnf install vim-enhanced stow git curl
sudo apt install vim-gtk stow git curl
git clone --recurse-submodules git@github.com:Notgnoshi/dotfiles.git ~/.config/dotfiles
cd ~/.config/dotfiles
./setup
Dotfiles are managed with GNU Stow. Anything in the ./stowdir/ is symlinked into my home directory. Stow can somehow detect script renames, and delete the stale symlinks.
I highly recommend Stow, especially over doing it yourself.
Installed applications and system preferences are listed in various scriptlets in ./setup.d/.
All of this is managed through the setup script, which handles Ubuntu/Fedora differences
using the -fedora.sh
or -ubuntu.sh
suffix on the ./setup.d/*.sh
scriptlets when there's
differences to account for.
I have lots of shell scripts in ~/.local/bin/. Some I use very often, some are just one-offs.
Here's some of the highlights:
git-gl
- A bettergit log
with an unforunate name that's now embedded in my muscle memoryclip
- Pipe to/from your Wayland/X11 clipboard.docker-cwd
- Get an interactive shell in the current directory for the given Docker image. Has Bash completion for available Docker imagesfilter-wkt
andwkt2csv
- Helpers for working with WKT geometry dataqgis-project
- Generate a QGIS project from a (nested) directory of CSV layer filesdate2unix
andunix2date
- Helpers to convert UTC timestamps between Unix timestamps and ISO-8061 timestamps. Useful for correlating between logs files in different formatsrandpass
- Generate random passphrases that use alliterationcsvdelta
- calculate interrow deltas for a column in a CSV filecsvstats
- calculate summary statistics for a column in a CSV fileemoticon
- copy different emoticons to the clipboardxldd
- A version ofldd
that tries to be cross-compilation and Yocto SDK aware
As my bashrc and setup scripts have grown, I've found the need to break them apart. My ~/.bashrc
nowadays is essentially
DOTFILES_DIR=# Resolve the symlink for this file
##################################################################################################
# Source each of components in alphabetical order.
##################################################################################################
for rcfile in "${DOTFILES_DIR}/bashrc.d/"*.sh; do
[ -f "$rcfile" ] && source "$rcfile"
done
with some extra bookkeeping.
PS1 - bashrc.d/060-ps1.sh
My PS1 is fairly dynamic and gives several useful at-a-glance status indicators:
- Color the trailing
$
red if the previous command failed - Utilize the excellent
__git_ps1
if it exists - List the number of background jobs, if there are any
- Indicate whether I'm connected to the current device over SSH or a serial connection (requires this PS1 to be configured on the remote device)
- Indicate whether this shell's environment has been polluted by a Yocto SDK, and which SDK, if it has been
- Indicate if my work VPN is running, and if it is, whether or not it has a route to the gateway
- Requires
VPN_GATEWAY
be set, which I do withbashrc.d/100-work.sh
, which is.gitignore
d
- Requires
I highly recommend using __git_ps1
. I frequently see coworkers getting confused because they
weren't aware of the state their worktree was in before or after some Git incantation.
History - bashrc.d/050-history.sh
- Keep an infinite history
- Keep track of the date and time each command was run on
- Share the same history between every shell
IMPORTANT: Don't mount your home directory in a Docker container - that's asking to get your history wiped out.
Environment variables - bashrc.d/070-environment.sh
I refuse to run sudo make install
.
So I use environment variables to make ~/.local/
act just like /usr/local/
.
fzf has had a profound impact on my perceived usability of the terminal.
Pressing ctrl-r
will start a reverse history search. The one provided by GNU Readline is perfectly
useable, but FZF's is just better. It shows me the closest matches to my query, and I don't have
to spell something perfectly.
This combines nicely with a permanent Bash history.
Outside of Vim, I use ctrl-t
to open a fuzzy file-finder.
Inside of Vim, I use :GFiles
and sometimes just :Files
to do exactly the same thing. I use this
often enough that I have keybinds for it.
I also use :Buffers
to switch between open buffers, and :Rg [pattern]
to use ripgrep
to
recursively grep
a codebase. Using tab
to select results loads them into the quickfix list.
:Rg
is a much more powerful :vimgrep
.
Within Vim, there's also :BCommits
and :Commits
to view the Git commits for the current buffer,
or the whole project respectively.
I tend not to use this, because it's been difficult to customize, so I built git-gl to do the same thing. It's effectively a console version of gitk that's optimized for my workflow.
It accept any argument that git log
accepts, and also has Bash
completion to tab-complete, because that's just
plain nice.
- Press
enter
to opengit show
for the selected commit, usingdelta
as the pager, which provides word diffs, and side-by-side diffs if the terminal is wide enough. - Press
ctrl-y
togit checkout
the selected commit - Press
ctrl-h
to copy the selected commit's hash to my clipboard (useful forgit commit --fixup=<hash>
commits) - Press
ctrl-p
togit cherry-pick
the selected commit onto your current branch (you probably only want to do this if you rungit gl
on a branch other than your current one). - Press
ctrl-r
to perform an interactive rebase targetting the selected commit
Grooming a Git branch's history is like combing hair. Never start at the root and yank all the way to the tip. Instead, start at the root and make tiny short strokes, working your way to the tip.
(I don't have long hair, so maybe I have the direction backwards; it seems like working your way from the tip to the root would be less painful?)
I don't run git log
or git rebase
by hand anymore.
I used to use Tilix as my terminal emulator, but it's unmaintained, and sometimes crashes. The primary reason I used to use it was to get side-by-side terminal panes.
I now use tmux for this, and have found I quite like it.
I use vim-tmux-navigator to use the same
keybinds ctrl-{h,j,k,l}
to seamlessly navigate between Vim splits and tmux panes.
I use ALE to provide completion, code formatting, and linting in Vim. It supports any language I care to use, and provides enough configuration hooks for me to use whatever formatter / linter / LSP a project requires.
I mostly use
- rust-analyzer
- clangd
- clang-format
- clang-tidy
- black
- isort
- pydocstyle
- gitlint
ALE provides the IDE experience I want:
- Jump to definition
- Find references
- Rename
- Completion
- Static-analysis lints
- Compilation warnings and errors
I don't want a "big green 'go' button", because my experience has shown me that
- You get IDE lock-in to sub-par IDEs when a work project requires an IDE just to build a project
- Understanding how the build works is important!
- Not understanding how the build works results in developers that don't know how to troubleshoot CI/CD pipelines
- Building a project at your terminal and the CI/CD pipeline should be the same experience - or else developers won't trust the pipeline
I won't list each plugin, but here's the important ones:
-
https://github.com/dense-analysis/ale
Discussed above
-
https://github.com/ericcurtin/CurtineIncSw.vim
Switch between C++ headers and source files. Uses heuristics and sometimes gets it wrong.
-
https://github.com/tpope/vim-commentary
Provides nice ways to comment and uncomment code blocks
-
https://github.com/junegunn/fzf and https://github.com/junegunn/fzf.vim
Discussed above
-
https://github.com/puremourning/vimspector
Use VS Code debug adapters from Vim. Better than
:Termdebug
, but finicky configuration -
https://github.com/Notgnoshi/rust.vim
A fork of the upstream https://github.com/rust-lang/rust.vim that is seemingly unmaintained
-
https://github.com/SirVer/ultisnips
Provides snippets. I rarely use, except for default Bash and Python script templates.
-
https://github.com/djoshea/vim-autoread
Detect external changes
-
https://github.com/tpope/vim-dispatch
Adds
:Make
that runs:make
in the background, loadingerrorformat
results into the quickfix list once it's done. Nice integration withvim-test
-
https://github.com/vim-test/vim-test
Nice support for running tests from within Vim. Can run the test under the cursor, and load test results in the quickfix list.
-
https://github.com/tpope/vim-fugitive
Really nice Vim + Git integration. Would use it more if I weren't so set in my ways
-
https://github.com/airblade/vim-gitgutter
Show gutter signs for additions, removals, and modifications
-
https://github.com/michaeljsmith/vim-indent-object
Text objects for indentation. Quite nice for Python projects where you can't use iB/aB with braces.
-
https://github.com/tpope/vim-surround
Surround things with matched delimiters or HTML tags. I use all the time. Was what showed me that text objects are super powerful.
-
https://github.com/christoomey/vim-tmux-navigator
Seamlessly navigate between Vim splits and tmux panes