My dotfiles are now just a long documentation file. Not very DRY, in a good way.
I disliked the complexity involved with branching between different devices because of slight differences (can be as small as a work email).
I used to run a nice NixOS setup with everything tracked in git, etc. This is what I ended up after declaring dotfile bankupcy.
Bash
Set my editor and bash mode:
set -o vi
export EDITOR="nvim"
Minimal PS1:
export PS1="\w $ "
Common bin locations:
export PATH="$PATH:$HOME/bin"
export PATH="$PATH:$HOME/go/bin"
export PATH="/opt/homebrew/bin:$PATH"
My p
alias to quickly switch projets:
p() {
cd ~/p && cd "$(find . -mindepth 1 -maxdepth 1 -type d | fzf)"
}
Download audio via aget {{URL}}
:
alias aget="yt-dlp --extract-audio --audio-format mp3"
Download a webpage:
# /bin/hget
# usage: "hget {{URL}} {{outfile}}"
# NOTE: Kobo needs the '-F' flag
chromium --headless --incognito --dump-dom "$1" | monolith - -IF -E utf-8 -b "$1" -o "$2"
SSH
Taliscale & fridge access
- Sign in to tailscale
- Install tailscale
- Setup an ssh key
ssh-keygen -t ed25519 -C dom@tdom.dev
- send
.pub
to another device - add the key to
~/.ssh/authorized_keys
in the fridge
Config
I like to setup my ssh such that it opens a tmux session on a new connection.
Host fridge
HostName 100.92.89.128
User root
RemoteCommand tmux a
RequestTTY yes
Git
Here is a cheatsheet.
Set my credentials:
[user]
name = Dominik Tarnowski
email = dom@tdom.dev
[github]
user = td0m
I am not racist - I do not use master branches 🙃.
[init]
defaultBranch = main
Ignore the global .gitignore
file:
[core]
excludesfile = ~/.gitignore
My beloved aliases:
[alias]
a = add
aa = add --all
d = diff
ds = diff --staged
dd = diff --stat
b = branch
l = log --oneline -n 20 --date=format:'%Y-%m-%d %H:%M' --pretty=format:'%C(cyan)%h%Creset%C(auto)%d %s - %ar'
s = status --short --branch
ch = checkout
c = commit
Use SSH rather than HTTP, so that my ssh public keys are used for authentication:
[url "ssh://git@github.com/"]
insteadOf = https://github.com/
Tmux
By default, tmux starts windows at 0 and does not renumber them on delete. I dislike that.
set -g base-index 1
set -g pane-base-index 1
set-window-option -g pane-base-index 1
set-option -g renumber-windows on
When I open a new window, I want it to be in the same directory as the previous one.
bind c new-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind '"' split-window -v -c "#{pane_current_path}"
I used to use bind-key -n C-g send-prefix
to nest tmux
sessions, but now I just open a new kitty tab for this. Muscle memory is
better this way.
This is copy pasted, and seems to fix my tmux colors, sometimes:
set -as terminal-overrides ",xterm-256color:RGB"
set -g default-terminal "tmux-256color"
Rarely, I like using the mouse to switch windows:
set -g mouse on
If you’ve ever used vim with tmux, you’ll notice escape has a delay. Disable it.
set -sg escape-time 10
Sometimes, I like longer session names. By default tmux truncates them. Extend it.
set -g status-left-length 20
Neovim
Disable syntax highlighting, including treesitter’s.
vim.cmd("syntax off")
Be default, do not wrap - it’s ambiguous.
vim.opt.wrap = false
Try :h tabstop
for recommended ways of using these
options.
expandtab
specifies if tabs should be converted to spaces.tabstop
is the displayed width of a<Tab>
char.shiftwidth
determines how many spaces to indent by (<
,>
movements).
My default, use tabs:
vim.opt.expandtab = false
vim.opt.tabstop = 4
vim.opt.shiftwidth = 0 -- default to tabstop's value
vim.opt.softtabstop = 0 -- disabled
To switch to 2 spaces:
:set expandtab tabstop=2
:%retab!
If your indentation is unexpectedly different, turns out vim lets you
find out exactly which module did it. To likely disable this, run
filetype indent off
.
:verb set shiftwidth
On the topic of tabs vs spaces, in case you need to know which is which:
vim.opt.list = false
vim.opt.listchars = { space = '⋅', tab = '→ ' }
Oftentimes, especially in JS/TS, I find the auto indenting sucks. Hence this just makes the indentation use the same as the line above.
vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
pattern = "*",
callback = function()
vim.bo.indentexpr = ""
end
})
To switch alternate buffers via backspace:
vim.keymap.set("n", "<BS>", ":b#<CR>", { silent = true })
To make searching with /
case insensitive (unless an
uppercase or /C
option), use:
vim.o.ignorecase = true
vim.o.smartcase = true
Re-select last yanked text (different to gv
which is
last visual):
vim.keymap.set("n", "gy", "`[v`]")
To insert the current date via “,d”:
vim.cmd.iabbrev("<expr>", ",d", "strftime('%Y-%m-%d')")
To remove trailing whitespace:
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
pattern = { "*" },
callback = function(_)
local save_cursor = vim.fn.getpos(".")
vim.cmd([[%s/\s\+$//e]])
vim.fn.setpos(".", save_cursor)
end,
})
To persist undos between neovim sessions:
vim.o.undofile = true
To disable the status line:
vim.opt.laststatus = 0
vim.opt.showmode = false
leader:
vim.g.mapleader = " "
vim.g.maplocalleader = " "
lsp configs:
vim.keymap.set("n", "gd", vim.lsp.buf.definition)
vim.keymap.set("n", "<leader>a", vim.lsp.buf.code_action)
vim.api.nvim_create_autocmd("BufRead", {
pattern = { "*.js", "*.jsx", "*.ts", "*.tsx" },
callback = function(args)
vim.lsp.start({
name = "js",
cmd = { "typescript-language-server", "--stdio" },
root_dir = vim.fs.root(0, {"package.json"}),
})
end,
});
Experimental: espeak.
local espeak = 'espeak -s 150 --punct -k 1'
vim.keymap.set('n', '<leader>l', ':.w !setsid -f '..espeak..'<cr><cr>')
vim.keymap.set('n', '<leader>l', ':.w !setsid -f '..espeak..'<cr><cr>')
vim.keymap.set('n', '<leader>u', ':!pkill -9 espeak<CR><CR>')
Neovim remote
v
#!/usr/bin/env bash
export PIPE="$HOME/.cache/nvim/servers/$(openssl rand -hex 4).pipe"
mkdir -p "$(dirname "$PIPE")"
nvim --listen "$PIPE" $@
f
#!/usr/bin/env bash
ARGS="${*:-}"
fd $ARGS | fzf --tmux -m | xargs nvim --server "$PIPE" --remote
g
#!/usr/bin/env bash
RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case $*"
fzf --tmux 60% -m \
--ansi --disabled --query "" \
--bind "start:reload:$RG_PREFIX {q}" \
--bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
--bind 'enter:become(vr {1} && vsend '{2}G')'
neovim integration
vim.keymap.set("n", "<leader>g", [[:silent !g -i &<CR>]], { silent = true })
vim.keymap.set("n", "<leader>G", [[:silent !g -i &]], {})
vim.keymap.set("n", "<leader>f", [[:silent !f -i &<CR>]], { silent = true })
vim.keymap.set("n", "<leader>F", [[:silent !f -i &]], {})
Snippets
I use a super simple mechanism for snippets/templates: a
~/t
directory.
You can activate them with vim via: :r ~/t/doctype
.
doctype
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="theme-color" content="">
<link rel="shortcut icon" href="">
<link rel="stylesheet" href="">
<title>Document</title>
</head>
<body>
</body>
</html>
SQLite
My ~/.sqliterc
has the following defaults:
To enable headers: .headers on
To show as a table, not csv: .mode column
To show number of rows changed: .changes on
Custom emoji for null values: .nullvalue 👻
Postgres
My .psqlrc
contains this line to enable timing
messages:
\timing on
If the columns take up too much space, show one per line:
\x auto
Use ghost emojis to display null
values:
\pset null 👻
If you want histories to be separate per database:
\set HISTFILE ~/.psql_history- :DBNAME
Kitty
My terminal of choice is kitty.
The main custom thing I do there is set a font.
font_family UnifontExMono
adjust_column_width 50%
font_size 14