Move everything possible into XDG directories

With the help of xdg-ninja (https://github.com/b3nj5m1n/xdg-ninja)
we move all kinds of config/cache files into the XDG directories
This commit is contained in:
Alexander Hess 2023-04-10 04:08:07 +02:00
commit 13b8724696
Signed by: alexander
GPG key ID: 344EA5AB10D868E0
27 changed files with 131 additions and 42 deletions

205
.config/git/config Normal file
View file

@ -0,0 +1,205 @@
[alias]
# Important: ~/.config/shell/aliases.sh loads all git aliases with
# less than 7 characters into the shell's "namespace" with a "g" prefix
# Example: git add <=> git a <=> ga
a = add
ap = add --patch
bi = bisect
br = branch
bra = branch --all
brd = branch --delete
brdd = branch --delete --force
brm = branch --move
cf = cat-file
ci = commit
cim = commit --message
cl = clone
co = checkout
cob = checkout -b
cod = checkout develop
com = checkout master
cp = cherry-pick
de = describe --tags
df = diff
fe = fetch
lg = log
lga = log --all
mb = merge-base
me = merge
mea = merge --abort
mec = merge --continue
mefeat = "!f() { if [ $# -eq 0 ]; then echo "Must specify a branch to merge in"; exit 1; fi; git check-pull; if [ $? -gt 0 ]; then echo "$1 must be rebased first"; exit 1; fi; cb=$(git current-branch) && printf '# SUBJECT\n# =======\n# - what does the commit do\n# - capitalize the first word and use the\n# imperative mood (e.g. "Add" vs "Adds")\n# - do not end the line with a period\n# - start with "Fix" for any hotfixes\n# ========= 50 characters / 1 line ============= |\nMerge in \"%s\"\n# ============================================== |\n\n\n# BODY (optional)\n# ===============\n# - explain what the commit does, why it does it, and how\n# - do not format the text (e.g., Markdown or reStructuredText)\n# - use multiple lines starting with "-" as bullet points\n# - link to external resources for even more context where appropriate\n# ========= 72 characters / multiple lines (and paragraphs) ========== |\nMerge branch \"%s\" into \"%s\"\n\nSummary of the merged in commits:\n' $1 $1 $cb > .merge_msg.txt.tmp && git log --format=format:' * %h: %s' $cb..$1 >> .merge_msg.txt.tmp && printf '\n\n\n# ==================================================================== |\n\n\n# GITHUB ISSUE (optional)\n# =======================\n# - uncomment and adapt one of the lines below\n# - use the "closes" keyword if applicable\n# (see https://help.github.com/en/articles/closing-issues-using-keywords)\n#\n# Related GitHub issue: #21\n# This commit closes #42 on the GitHub issue tracker\n\n\n#\n# END\n#\n' >> .merge_msg.txt.tmp && git merge --no-ff --no-commit $1 && SKIP=no-commit-to-branch git commit --edit --file=.merge_msg.txt.tmp; rm -f .merge_msg.txt.tmp; }; f"
meff = merge --ff-only
menoff = merge --no-ff
pl = pull
plrb = pull --rebase
ps = push
psf = push --force
rb = rebase --committer-date-is-author-date
rba = rebase --abort
rbc = rebase --continue
rbi = rebase --interactive
rbq = rebase --quit
rbs = rebase --skip
rl = reflog
rm = rm # To make it available as the grm alias
rp = rev-parse
rs = reset
rv = revert
s = status
ss = status --short
sh = show
st = stash
sta = stash push --include-untracked # push does not go into the shortcut!
stam = stash push --include-untracked --message
stapp = stash apply
stl = stash list
stp = stash pop
stsh = stash show
# Provide an overview of all aliases. Second one is for use in ~/.bashrc
aliases = config --get-regexp 'alias.*'
internal-aliases = !git config --list | grep 'alias\\.' | sed 's/alias\\.\\([^=]*\\)=\\(.*\\)/\\1/' | sort
# Provide synonyms as "specified" in the git status header
discard = checkout --
unstage = reset HEAD --
# Common tasks with tedious or non-intuitive flags
amend-commit = !git log -n 1 --pretty=tformat:%B | git commit -F - --amend # Keep the commit message
check-pull = "!f() { git fetch; upstream=${1:-'@{u}'}; local=$(git rev-parse @); remote=$(git rev-parse "$upstream"); base=$(git merge-base @ "$upstream"); if [ $local = $remote ]; then echo "Up-to-date"; exit 0; elif [ $local = $base ]; then echo "Local branch is behind upstream"; elif [ $remote = $base ]; then echo "Local branch is ahead of upstream"; else echo "Local and remote branches diverged"; fi; exit 1; }; f"
current-branch = !git rev-parse --abbrev-ref HEAD
project-root = rev-parse --show-toplevel
uncommit = reset --soft HEAD~1
# Sync the working directory into the index
rm-deleted = !git ls-files -z --deleted | xargs -r -0 git rm
sync-pwd-to-index = !git rm-deleted && git add . --all
sy = !git sync-pwd-to-index
# Make minimal diff the default
diff-minimal = diff --color-words=. --ws-error-highlight=all
d = diff --color-words=. --ws-error-highlight=all
dlc = diff --color-words=. --ws-error-highlight=all HEAD
ds = diff --color-words=. --ws-error-highlight=all --staged
# Clean the project folder with intuitive commands
# Always keep the .python-version file, which is also often in ~.gitignore
clean-all = !git reset --hard && git clean-ignored && git clean-untracked
clean-ignored = "!f() { if [ -f .python-version ]; then mv .python-version .python-version.XYZ; fi; if [ -f .env ]; then mv .env .env.XYZ; fi; git clean -X -d -f "$@"; if [ -f .python-version.XYZ ]; then mv .python-version.XYZ .python-version; fi; if [ -f .env.XYZ ]; then mv .env.XYZ .env; fi }; f"
clean-untracked = !git clean -x -d -e ".python-version" -e ".env" -f # The -e flag does not work with -X
# Delete everything not reachable from a branch from the repository
gc-everything = "!f() { git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"; }; f"
# Make the logs look nice by default
last-commit = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%aN @ %ad => %ar%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S %z' -1 -p --stat
lc = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%aN @ %ad => %ar%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S %z' -1 -p --stat
history = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%aN @ %ad => %ar%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S %z' --graph
hi = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%aN @ %ad => %ar%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S %z' --graph
hia = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%aN @ %ad => %ar%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S %z' --graph --all
summary = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%an @ %ad => %ar%n' --date=format:'%a %Y-%m-%d %H:%M:%S %z' --graph
su = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%an @ %ad => %ar%n' --date=format:'%a %Y-%m-%d %H:%M:%S %z' --graph
sua = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%an @ %ad => %ar%n' --date=format:'%a %Y-%m-%d %H:%M:%S %z' --graph --all
oneline = log --pretty='%C(auto)%h: %s%d' --graph
ol = log --pretty='%C(auto)%h: %s%d' --graph
ola = log --pretty='%C(auto)%h: %s%d' --graph --all
# Search the repository
grep-code = grep --break --context 1 --full-name --heading --line-number --show-function
grepc = grep --break --context 1 --full-name --heading --line-number --show-function
grep-log = log --all --regexp-ignore-case --pretty='%C(auto)%h: %s%+D%Creset%n%C(reverse)%C(dim)%aN @ %ad = %ar%Creset%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S' --grep
grepl = log --all --regexp-ignore-case --pretty='%C(auto)%h: %s%+D%Creset%n%C(reverse)%C(dim)%aN @ %ad = %ar%Creset%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S' --grep
grep-text = grep --break --context 1 --full-name --heading --ignore-case --line-number
grept = grep --break --context 1 --full-name --heading --ignore-case --line-number
# Push current branch to origin
push-to-origin = "!f(){ git push --set-upstream origin $(git current-branch) "$@"; }; f"
pso = "!f(){ git push --set-upstream origin $(git current-branch) "$@"; }; f"
[clean]
requireforce = true
[color "branch"]
current = cyan dim bold reverse
local = green bold
remote = red bold
[color "decorate"]
HEAD = cyan dim bold reverse
branch = green bold
remoteBranch = red bold
stash = magenta dim bold reverse
tag = magenta bold
[color "diff"]
context = white
frag = blue dim bold reverse
meta = yellow dim bold reverse
new = green bold
old = red bold
whitespace = red dim bold reverse
[color "grep"]
context = white
filename = yellow dim bold reverse
function = white bold
linenumber = blue dim bold reverse
match = red bold
selected = white
separator = blue dim bold reverse
[color "interactive"]
error = red dim bold reverse
header = white
help = yellow bold
prompt = white dim bold reverse
[color "status"]
added = green bold
branch = cyan dim bold reverse
changed = yellow bold
header = white
localBranch = green bold
nobranch = red dim bold reverse
remoteBranch = red bold
unmerged = yellow dim bold reverse
untracked = red bold
[commit]
cleanup = strip
gpgSign = true
template = ~/.config/git/commit_msg_template.txt
verbose = true
[core]
editor = vim
excludesfile = ~/.config/git/ignore
pager = less --chop-long-lines --ignore-case --LONG-PROMPT --status-column --quit-if-one-screen
whitespace = -space-before-tab,tab-in-indent
[diff]
renames = true
submodule = log
[help]
autocorrect = 50
[merge]
conflictstyle = diff3
ff = only
[pull]
ff = only
rebase = true
[push]
default = upstream
recursesubmodules = check
[rerere]
enabled = true
[url "https://bitbucket.org/"]
insteadOf = bb:
[url "https://github.com/"]
insteadOf = gh:
[url "https://gitlab.com/"]
insteadOf = gl:
[user]
name = Alexander Hess
email = alexander@webartifex.biz
signingKey = AB5C0E319D77350FBA6CF143344EA5AB10D868E0

35
.config/psql/psqlrc Normal file
View file

@ -0,0 +1,35 @@
-- psql executes the commands in this ~/.psqlrc creating output
-- (this flag hides that and is unset again at the bottom)
\set QUIET 1
-- Show verbose error messages
\set VERBOSITY verbose
-- Use normal "table" format by default and "expanded table" with lots of columns
\x auto
-- By default, NULLs show up as empty spaces, which looks like empty strings
\pset null 'NULL'
-- Ignore errors in interactive sessions but not when executing scripts
\set ON_ERROR_ROLLBACK interactive
-- Upper case SQL keywords
\set COMP_KEYWORD_CASE upper
-- Use the best text editor in the world
\set EDITOR vi
-- Use separate history files per database and
-- keep them in one folder (for easier sync with mackup)
-- under $XDG_STATE_HOME/psql
\set HISTFILE ~/.local/state/psql/history- :DBNAME
-- Don't store the same SQL statement repeatedly
\set HISTCONTROL ignoredups
-- Make all queries display query times
\timing
-- Unset the flag set at the top of this file
\unset QUIET

33
.config/python/pythonrc Normal file
View file

@ -0,0 +1,33 @@
# This file moves Python's history file to $XDG_STATE_HOME/python/history
# Adapted from: https://unix.stackexchange.com/questions/630642/change-location-of-python-history
import os
import atexit
import readline
from pathlib import Path
if readline.get_current_history_length() == 0:
state_home = os.environ.get("XDG_STATE_HOME")
if state_home is None:
state_home = Path.home() / ".local" / "state"
else:
state_home = Path(state_home)
history_path = state_home / "python" / "history"
if history_path.is_dir():
raise OSError(f"'{history_path}' cannot be a directory")
history = str(history_path)
try:
readline.read_history_file(history)
except OSError: # Non existent
pass
def write_history():
try:
readline.write_history_file(history)
except OSError:
pass
atexit.register(write_history)

View file

@ -56,7 +56,7 @@ _command_exists exa && alias exa='exa --group-directories-first --git --time-sty
_command_exists netstat && alias ports='netstat -tulanp'
_command_exists screenfetch && alias screenfetch='screenfetch -n'
alias uptime='uptime --pretty'
alias wget='wget --continue'
alias wget="wget --continue --hsts-file=$XDG_STATE_HOME/wget/history"
# Create shorter aliases for various utilities

View file

@ -1,4 +1,8 @@
# This file initializes the ~/.dotfiles as a bare repository
# This file sets up the $XDG_DATA_HOME/dotfiles, a bare git repository,
# such that they are available within a user's $HOME as common "dotfiles"
export XDG_DATA_HOME="$HOME/.local/share" # temporarily set here; mainly set in ~/.profile
_command_exists() {
@ -14,14 +18,27 @@ rm -rf "$HOME/.dotfiles" >/dev/null
git clone --bare https://code.webartifex.biz/alexander/dotfiles.git "$HOME/.dotfiles"
# Distribute the dotfiles in $HOME
git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME checkout --force
git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME config --local status.showUntrackedFiles no
git --git-dir=$XDG_DATA_HOME/dotfiles/ --work-tree=$HOME checkout --force
git --git-dir=$XDG_DATA_HOME/dotfiles/ --work-tree=$HOME config --local status.showUntrackedFiles no
# Dirty Fix: Otherwise `gnupg` emits a warning
[ -d "$XDG_DATA_HOME/gnupg" ] && chmod 700 $XDG_DATA_HOME/gnupg
if _command_exists zsh; then
# Set the $ZDOTDIR in /etc[/zsh]/zshenv if that is not already done
# Notes:
# - must use $HOME as $XDG_CONFIG_HOME is not yet set
# - on Fedora, the global config files are not in /etc/zsh but in /etc
export ZDOTDIR="$HOME/.config/zsh"
for _file in '/etc/zshenv' '/etc/zsh/zshenv'; do
if [ -f $_file ]; then
grep -q -F "export ZDOTDIR" $_file || echo 'export ZDOTDIR="$HOME"/.config/zsh' | sudo tee -a $_file
fi
done
# (Re-)Install oh-my-zsh
export ZSH="$HOME/.oh-my-zsh"
export ZSH="$XDG_DATA_HOME/oh-my-zsh" # temporarily set here; mainly set in $XDG_CONFIG_HOME/zsh/.zshenv
rm -rf $ZSH >/dev/null
# Let's NOT use the main repository but our personal fork
git clone --origin fork --branch forked https://code.webartifex.biz/alexander/oh-my-zsh.git $ZSH
@ -30,16 +47,19 @@ if _command_exists zsh; then
cd $HOME
# (Re-)Install zplug
export ZPLUG_HOME="$HOME/.zplug"
export ZPLUG_HOME="$XDG_DATA_HOME/zplug" # temporarily set here; mainly set in $XDG_CONFIG_HOME/zsh/.zshenv
rm -rf $ZPLUG_HOME >/dev/null
git clone https://github.com/zplug/zplug $ZPLUG_HOME
# Set up all the zplug plugins (-i so that the new ~/.zshrc is sourced)
# Set up all the zplug plugins (-i so that the new $XDG_CONFIG_HOME/zsh/.zshrc is sourced)
zsh -i -c "zplug install"
fi
# Disable the creation of ~/.sudo_as_admin_successful
echo 'Defaults !admin_flag' | sudo tee /etc/sudoers.d/disable_admin_note
echo
echo "Probably it's a good idea to restart the shell"
echo "Make sure to start bash or zsh as a login shell the next time"

View file

@ -57,7 +57,7 @@ _update_repositories() {
ZSH_DOTENV_FILE='.env'
_command_exists pass && echo "Fetching $HOME/.password-store" && pass git pull
_command_exists pass && echo "Fetching $XDG_DATA_HOME/pass" && pass git pull
_update_dotfiles
cd $cwd

View file

@ -0,0 +1,65 @@
" Set the search path to the folder of the current file and its sub-folders
setlocal path=.,**
" Exclude Python's compiled files from searches
setlocal wildignore=*/__pycache__/*,*.pyc
" TODO: This does not work, maybe because we spell out imports
" as project-local imports (e.g. from lalib.fields import base)?
" Include *.py files imported as modules when searching.
" Source: https://www.youtube.com/watch?v=Gs1VDYnS-Ac
set include=^\\s*\\(from\\\|import\\)\\s*\\zs\\(\\S\\+\\s\\{-}\\)*\\ze\\($\\\|\ as\\)
" 1) import foo.bar -> foo/bar.py
" 2) from foo import bar as var -> foo/bar.py or foo.py
function! PyInclude(fname)
let parts = split(a:fname, ' import ') " 1) [foo.bar] or 2) [foo, bar]
let left = parts[0] " 1) foo.bar or 2) foo
if len(parts) > 1
let right = parts[1] " only 2) bar
let joined = join([left, right], '.')
let fpath = substitute(joined, '\.', '/', 'g') . '.py'
let found = glob(fpath, 1)
if len(found)
return found
endif
endif
return substitute(left, '\.', '/', 'g') . '.py'
endfunction
setlocal includeexpr=PyInclude(v:fname)
setlocal define=^\\s*\\<\\(def\\|class\\)\\>
" Number of spaces used for each step of auto-indent
set shiftwidth=4
" Number of spaces a <Tab> counts for in the file
set tabstop=4
" Number of spaces a <Tab> counts for in editing mode
set softtabstop=4
" Change <Tab>s into spaces
set expandtab
" Copy indent from previous line when starting a new line
set autoindent
" Use indent according to the syntax of the open file
set smartindent
" Auto-wrap lines after 88 characters, which is PEP8's limit plus 10%,
" a more relaxed boundary which occasionally may be used
set textwidth=88
" Make column 80 red to indicate PEP8's maximum allowed line length
set colorcolumn=80
" Additionally, give every character beyond 80 columns a red background
highlight ColorColumn ctermbg=DarkRed
call matchadd('ColorColumn', '\%80v', 100)
match ErrorMsg '\%>80v.\+'
" Show line numbers by default for .py files
let g:show_numbers=1

View file

312
.config/vim/vimrc Normal file
View file

@ -0,0 +1,312 @@
" Good sources on vimrc files:
" - https://www.youtube.com/watch?v=Gs1VDYnS-Ac
" Use VIM improved mode
set nocompatible
" Set environment variables for convenient usage
let $RC="$XDG_CONFIG_HOME/vim/vimrc"
let $RTP=split(&runtimepath, ',')[0]
" Disable VIM's startup message
set shortmess+=I
" Number of remembered undo steps
set undolevels=1000
" Detect the file's type and load the corresponding plugin and indent files
filetype plugin indent on
" Enable syntax highlighting
syntax on
" Allow backspace to delete characters in insert mode
" beyond the start of the insertion and end of lines
set backspace=start,eol,indent
" Hide buffers instead of closing them, wich means we can have
" unwritten changes to a file and open a new one with :e,
" without having to write the changes first
set hidden
" Set to the folder of the current file and its sub-folders
" (this may need to be adapted for large project folders)
set path=.,**
" Store all vim-related working files in the ~/.local/state/vim folder
set viminfo+=n$XDG_STATE_HOME/vim/viminfo
" Use dedicated folders to store temporary backup, swap, and undo files
" (the // means that VIM adapts names automatically to avoid duplicates)
set backupdir=$XDG_STATE_HOME/vim/backup//
set directory=$XDG_STATE_HOME/vim/swap//
set undodir=$XDG_STATE_HOME/vim/undo//
" To disable any of the temporary files, uncomment one of the following
" set nobackup
" set nowritebackup
" set noswapfile
" set noundofile
set runtimepath+=$XDG_CONFIG_HOME/vim,$XDG_CONFIG_HOME/vim/after,$VIM,$VIMRUNTIME
" Show the filename in the terminal window's title bar
set title
" Do not wrap lines when showing text
set nowrap
" This avoids a problem of loosing data upon insertion in old VIMs
set wrapmargin=0
" Show spelling mistakes (in English) in italics
set spelllang=en_us,de_de
set spell
hi clear SpellBad
hi clear SpellCap
hi clear SpellRare
hi clear SpellLocal
hi SpellBad cterm=italic
" Show whitespace characters
set listchars=tab:»»,extends:,precedes:,nbsp,trail
set list
" Highlight matching brackets
set showmatch
set matchpairs+=<:>
" Always show the status bar at the bottom
set laststatus=2
" Show current position in status bar
set ruler
set rulerformat=%=%l/%L\ %c\ (%P)
" Show commands in status bar
set showcmd
" If in non-normal mode, show the mode in the status bar
set showmode
" Show a dialog to save changes instead of an error message
set confirm
" Auto-clear messages from the status bar
autocmd CursorHold * :echo
" Better copy and paste behavior
set pastetoggle=<F2>
set clipboard=unnamed
" Make : and ; synonyms
nnoremap ; :
" Use \ and <space> as the <leader> keys and lower time to enter key sequences
let mapleader='\'
set timeoutlen=750
" Make <space> the <leader> in visual mode as well
nmap <space> \
vmap <space> \
" Q normally goes into Ex mode
nmap Q <Nop>
" Get sudo rights when writing a buffer with w!!
cnoremap w!! w !sudo tee % >/dev/null
" Fix mouse issues with Alacritty terminal
" Source: https://wiki.archlinux.org/title/Alacritty#Mouse_not_working_properly_in_Vim
set ttymouse=sgr
" Enable the mouse for selections, including a toggle for this mode
set mouse=a
let g:mouse_enabled=1
function ToggleMouse()
if g:mouse_enabled == 1
echo "Mouse OFF"
set mouse=
let g:mouse_enabled=0
else
echo "Mouse ON"
set mouse=a
let g:mouse_enabled=1
endif
endfunction
noremap <silent><leader>m :call ToggleMouse()<cr>
" Enable toggling between
" - showing and hiding line numbers (<leader>l)
" - absolute and relative numbers (<leader>a) in normal mode
" (default: relative line numbering)
let g:show_numbers=0
let g:show_absolute_numbers=0
function! ShowLineNumbers()
if g:show_numbers == 1
set number
if g:show_absolute_numbers
set norelativenumber
else
set relativenumber
endif
else
set nonumber
set norelativenumber
endif
endfunction
function! ToggleLineNumbers()
if g:show_numbers == 1
let g:show_numbers=0
else
let g:show_numbers=1
endif
call ShowLineNumbers()
endfunction
function! ToggleAbsoluteAndRelativeLineNumbers()
if g:show_absolute_numbers == 1
let g:show_absolute_numbers=0
else
let g:show_absolute_numbers=1
endif
call ShowLineNumbers()
endfunction
" Auto-switch between absolute and relative numbering when switching modes
" (insert mode always shows absolute numbers when numbers are shown)
augroup numbertoggle
autocmd!
autocmd BufEnter,FocusGained,InsertLeave * call ShowLineNumbers()
autocmd BufLeave,FocusLost,InsertEnter * if g:show_numbers == 1 | set number | set norelativenumber | endif
augroup END
" Key bindings
nnoremap <silent><leader>l :call ToggleLineNumbers()<cr>
nnoremap <silent><leader>a :call ToggleAbsoluteAndRelativeLineNumbers()<cr>
" Show all possible matches above command-line when tab completing
set wildmenu
set wildmode=longest:full,full
" Highlight search results
set hlsearch
" Shortcut to remove current highlighting
nnoremap <silent><leader>h :nohlsearch<cr>
" Move cursor to result while typing immediately
set incsearch
" Ignore case when searching
set ignorecase
" Upper case search term => case sensitive search
set smartcase
" Highlight the next match in red for 0.25 seconds
function! HighlightNext()
let [bufnum, lnum, col, off] = getpos('.')
let matchlen = strlen(matchstr(strpart(getline('.'),col-1),@/))
let target_pat = '\c\%#\%('.@/.'\)'
let ring = matchadd('ErrorMsg', target_pat, 101)
redraw
exec 'sleep ' . float2nr(250) . 'm'
call matchdelete(ring)
redraw
endfunction
nnoremap <silent>n n:call HighlightNext()<cr>
nnoremap <silent>N N:call HighlightNext()<cr>
" Make <leader>w safe the buffer in normal mode
" and <c-z> save the buffer in all modes
" (the latter disables making VIM a background job;
" <c-z> is useful to have as <leader>w does not work in INSERT mode)
nnoremap <leader>w :update<cr>
nnoremap <c-z> :update<cr>
vnoremap <c-z> <c-c>:update<cr>
inoremap <c-z> <c-o>:update<cr>
" <leader>q quits VIM
nnoremap <leader>q :quit<cr>
" Easier switching between tabs
noremap <leader>, <esc>:tabprevious<cr>
noremap <leader>. <esc>:tabnext<cr>
" Arrow keys and <c-h/j/k/l> either (un)indent lines or move them up or down
" (same for blocks of lines in visual mode)
nnoremap <left> <<
nnoremap <right> >>
nnoremap <silent><up> :m-2<cr>
nnoremap <silent><down> :m+<cr>
nmap <c-h> <left>
nmap <c-j> <down>
nmap <c-k> <up>
nmap <c-l> <right>
vnoremap <left> <gv
vnoremap <right> >gv
vnoremap <up> :m'<-2<cr>gv=gv
vnoremap <down> :m'>+1<cr>gv=gv
vmap <c-h> <left>
vmap <c-j> <down>
vmap <c-k> <up>
vmap <c-l> <right>
" Make <tab> (un)indent lines
nnoremap <tab> >>
nnoremap <s-tab> <<
inoremap <tab> <esc>>>
inoremap <s-tab> <esc><<
vnoremap <tab> >gv
vnoremap <s-tab> <gv
" Make Y yank the rest of a line, just like C or D work
noremap Y y$
" Alphabetically sort a selection of lines
vnoremap <leader>s :sort<cr>
" Switch two words, just like xp switches two characters
noremap <leader>xp dwElp
" Auto-reload a file that was changed by some other process
" if the buffer has not yet been changed in the meantime
set autoread
augroup checktime
autocmd!
autocmd BufEnter * silent! checktime
autocmd CursorHold * silent! checktime
autocmd CursorHoldI * silent! checktime
autocmd CursorMoved * silent! checktime
autocmd CursorMovedI * silent! checktime
augroup END
" Auto-reload ~/.vim/vimrc
augroup vimrc
autocmd! BufWritePost $RC source % | redraw
augroup END
" Key binding to reload ~/.vim/vimrc manually
nnoremap <silent><leader>rc :so $RC<cr>

1622
.config/zsh/.p10k.zsh Normal file

File diff suppressed because it is too large Load diff

3
.config/zsh/.zlogout Normal file
View file

@ -0,0 +1,3 @@
# Executed by zsh when a login shell exits
source "$HOME/.config/shell/logout.sh"

5
.config/zsh/.zprofile Normal file
View file

@ -0,0 +1,5 @@
# Executed by zsh when a login shell starts
# Unify ~/.profile and ~/.zprofile conceptually
# (~/.zlogin is skipped here as it is sourced after ~/.zshrc)
source "$HOME/.profile"

40
.config/zsh/.zshenv Normal file
View file

@ -0,0 +1,40 @@
# This file is sourced by zsh before ~/.zprofile and ~/.zshrc
# (it's kind of a zsh-only ~/.profile file)
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
export ZSH="$XDG_DATA_HOME/oh-my-zsh"
export ZPLUG_HOME="$XDG_DATA_HOME/zplug"
export _Z_DATA="$XDG_DATA_HOME/z"
# Use <Up> key to auto-complete a partially typed command
# TODO: the coloring does not work when zsh-syntax-highlighting is loaded simultaniously
# Source: https://github.com/zsh-users/zsh-history-substring-search/issues/131
export HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND="fg=#ffffff,bg=#38761d,bold"
export HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND="fg=#ffffff,bg=#990000,bold"
# Notify about shorter aliases for typed commands
# Source: https://github.com/MichaelAquilina/zsh-you-should-use
export YSU_MESSAGE_POSITION="before"
export YSU_MODE="BESTMATCH"
# Suggest commands as one types
# Source: https://github.com/zsh-users/zsh-autosuggestions
export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#666666,bg=bold"
export ZSH_AUTOSUGGEST_STRATEGY=(history completion)
# Temporary files should go into ~/.cache
export ZSH_COMPDUMP="${XDG_CACHE_HOME:-$HOME/.cache}/.zcompdump-$HOST-$ZSH_VERSION"
# Automatically source ".env" files in folders
# Source: https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/dotenv
export ZSH_DOTENV_FILE=".env"

181
.config/zsh/.zshrc Normal file
View file

@ -0,0 +1,181 @@
# Executed by zsh when a (non-)login shell starts
# Ensure zsh is running interactively
[[ $- != *i* ]] && return
# Check if a command can be found on the $PATH
_command_exists() {
command -v "$1" 1>/dev/null 2>&1
}
# Enable Powerlevel10k instant prompt
if [ -r "${XDG_CACHE_HOME:-$HOME/.cache}/zsh/p10k-instant-prompt-${(%):-%n}.zsh" ]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/zsh/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Enable XON/XOFF software flow control
stty -ixon
# Enable colors and change prompt
autoload -Uz colors
colors
# Enable VI mode
bindkey -v
# If an entered command does not exist per se
# but is the name of a folder instead, go there
setopt AUTO_CD
# Treat "#", "~", and "^" as part of patterns for filename generation
setopt EXTENDED_GLOB
# Warn if there are no matches
setopt NO_MATCH
# Silence the shell
setopt NO_BEEP
# Report status of background jobs immediately
setopt NOTIFY
# Remove all "built-in" aliases
unalias -a
# Set these environment variables here (and not in ~/.profile)
# due to conflict/overlap with bash
# Note: This file is NOT synced by mackup as zsh destroys the symbolic link
export HISTFILE="$XDG_STATE_HOME/zsh/history"
export HISTSIZE=999999 # number of lines kept in memory
export SAVEHIST=999999 # number of lines kept in $HISTFILE
# Append to the $HISTFILE rather than overwrite it
setopt APPEND_HISTORY
setopt INC_APPEND_HISTORY
# Initialize oh-my-zsh's plugins
plugins=(
command-not-found
dirhistory
dotenv # config in ~/.zshenv; `_update_repositories` temporarily disables this
git-escape-magic
invoke # completions for invoke
jsontools
pip # completions for pip
poetry # completions for poetry
z
)
source "$ZSH/oh-my-zsh.sh"
# Initialize zplug's plugins
source "$XDG_DATA_HOME/zplug/init.zsh" # config in ~/.config/zsh/.zshenv
# Must use double quotes in this section
# Source: https://github.com/zplug/zplug#example
# Make zplug manage itself like a plugin
# Source: https://github.com/zplug/zplug#let-zplug-manage-zplug
zplug "zplug/zplug", hook-build:"zplug --self-manage"
zplug "MichaelAquilina/zsh-you-should-use" # config in ~/.zshenv
zplug "zsh-users/zsh-autosuggestions" # config in ~/.zshenv
zplug "zsh-users/zsh-history-substring-search" # config in ~/.zshenv; there are key bindings below
zplug "zsh-users/zsh-syntax-highlighting"
zplug "romkatv/powerlevel10k", as:theme, depth:1
zplug load
# Initialize various utilities and aliases
source "$HOME/.config/shell/init.sh"
# Initialize zsh's completions
# This is already done via ~/.oh-my-zsh.sh above
# autoload -Uz compinit
# compinit -u -d "$ZSH_COMPDUMP"
# Enable match highlighting and scrolling through long lists,
# and provide a different style of menu completion
zmodload zsh/complist
# Include hidden files in tab completion
_comp_options+=(GLOB_DOTS)
# Enable arrow-key driven interface
zstyle ':completion:*' menu select
# Make compinit find new executables right away
zstyle ':completion:*' rehash true
# Enable grouping and group headers
zstyle ':completion:*:descriptions' format '%B%d%b'
zstyle ':completion:*:messages' format '%d'
zstyle ':completion:*:warnings' format 'No matches for: %d'
zstyle ':completion:*' group-name ''
# Enable completions for various tools
# invoke -> see plugins above; alternatively use
# _command_exists invoke && eval "$(invoke --print-completion-script=zsh)"
_command_exists nox && eval "$(register-python-argcomplete nox)"
# pip -> see plugins above; alternatively use
# _command_exists pip && eval "$(pip completion --zsh)"
_command_exists pipx && eval "$(register-python-argcomplete pipx)"
# poetry -> see plugins above; no alternative here
# Define key bindings
# zsh-autosuggestions plugin
bindkey "^ " autosuggest-accept
# Enable Ctrl-R
bindkey "^R" history-incremental-search-backward
# Use VI keys to navigate the completions in the menu
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
# history-substring-search plugin
# Source: https://github.com/zsh-users/zsh-history-substring-search#usage
# Normal mode
bindkey "$terminfo[kcuu1]" history-substring-search-up
bindkey "$terminfo[kcud1]" history-substring-search-down
# VI mode
bindkey -M vicmd 'k' history-substring-search-up
bindkey -M vicmd 'j' history-substring-search-down
# Enable Powerlevel10k "full" prompt
[[ ! -f $XDG_CONFIG_HOME/zsh/.p10k.zsh ]] || source $XDG_CONFIG_HOME/zsh/.p10k.zsh