diff --git a/.bash_completion b/.bash_completion index fd0492e..4270820 100644 --- a/.bash_completion +++ b/.bash_completion @@ -2,7 +2,7 @@ # Include all files from ~/.bash_completion.d/ if [[ -d ~/.bash_completion.d ]]; then - for f in ~/.bash_completion.d/*; do - [[ -f "$f" ]] && . "$f" - done + for f in ~/.bash_completion.d/*; do + [[ -f "$f" ]] && . "$f" + done fi diff --git a/.bashrc b/.bashrc index 9014ba1..9ac27dc 100644 --- a/.bashrc +++ b/.bashrc @@ -40,15 +40,15 @@ alias ll='ls -la' # Colored man pages man() { - env \ - LESS_TERMCAP_mb=$(printf "\e[1;31m") \ - LESS_TERMCAP_md=$(printf "\e[1;31m") \ - LESS_TERMCAP_me=$(printf "\e[0m") \ - LESS_TERMCAP_se=$(printf "\e[0m") \ - LESS_TERMCAP_so=$(printf "\e[1;44;33m") \ - LESS_TERMCAP_ue=$(printf "\e[0m") \ - LESS_TERMCAP_us=$(printf "\e[1;32m") \ - man "$@" + env \ + LESS_TERMCAP_mb=$(printf "\e[1;31m") \ + LESS_TERMCAP_md=$(printf "\e[1;31m") \ + LESS_TERMCAP_me=$(printf "\e[0m") \ + LESS_TERMCAP_se=$(printf "\e[0m") \ + LESS_TERMCAP_so=$(printf "\e[1;44;33m") \ + LESS_TERMCAP_ue=$(printf "\e[0m") \ + LESS_TERMCAP_us=$(printf "\e[1;32m") \ + man "$@" } # (Other aliases are defined in .bashrc.d/10_common_aliases.sh etc.) @@ -67,21 +67,21 @@ TWHITEB='\[\e[1;37m\]' # White bold # Set default prompt if [[ ${EUID} == 0 ]] ; then - PS1="${TRED}\u@\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" + PS1="${TRED}\u@\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" else - PS1="${TGREEN}\u@\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" + PS1="${TGREEN}\u@\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" fi # Include drop-in files if [[ -d ~/.config/bashrc.d ]]; then - for f in ~/.config/bashrc.d/*; do - [[ -f $f ]] && source "$f" - done + for f in ~/.config/bashrc.d/*; do + [[ -f $f ]] && source "$f" + done fi # Deprecation warning for old drop-in file locations if [[ -e ~/.bashrc.d || -e ~/.bashrc.local ]]; then - echo "WARNING: ~/.bashrc.d and ~/.bashrc.local are ignored, please use ~/.config/bashrc.d/ instead." + echo "WARNING: ~/.bashrc.d and ~/.bashrc.local are ignored, please use ~/.config/bashrc.d/ instead." fi # Clean up environment variables diff --git a/.config/bashrc.d/10_common.sh b/.config/bashrc.d/10_common.sh index a7cf2dc..b4dc5ec 100644 --- a/.config/bashrc.d/10_common.sh +++ b/.config/bashrc.d/10_common.sh @@ -17,70 +17,64 @@ alias suvim='sudo -e' # Stop Ctrl-S from doing terminally things in vim/vimdiff vim() { - local STTYOPTS="$(stty --save)" - stty stop '' -ixoff - command vim "$@" - stty "$STTYOPTS" + local STTYOPTS="$(stty --save)" + stty stop '' -ixoff + command vim "$@" + stty "$STTYOPTS" } vimdiff() { - local STTYOPTS="$(stty --save)" - stty stop '' -ixoff - command vimdiff "$@" - stty "$STTYOPTS" + local STTYOPTS="$(stty --save)" + stty stop '' -ixoff + command vimdiff "$@" + stty "$STTYOPTS" } -# Neovim shortcuts -alias nv='nvim' -alias nvimr='nvim -R' -alias nvim-config='nvim ~/.config/nvim/init.lua' - # yay without parameters does "pacman -Syu" but I don't want it to do this yay() { - [[ $# -gt 0 ]] || { echo "error: no operation specified (use -h for help)"; return 1; } - command yay "$@" + [[ $# -gt 0 ]] || { echo "error: no operation specified (use -h for help)"; return 1; } + command yay "$@" } # Create and cd to temporary directory ~/tmp/tmp.YYYYMMDD.XXXXXX or ~/tmp/tmp.$1.XXXXXX if an argument is given function cdtmp() { - cd $(mktemp -d -p ~/tmp tmp.${1:-$(date +%Y%m%d)}.XXXXXX) + cd $(mktemp -d -p ~/tmp tmp.${1:-$(date +%Y%m%d)}.XXXXXX) } # Make dir and cd into it (from Mara) function mkcd() { - mkdir -p "$1" - cd "$1" + mkdir -p "$1" + cd "$1" } # cd into dir + ll (ls -la) function cdll() { - cd "$1" - ls -la + cd "$1" + ls -la } # Show content of something, `ls` for dirs (and special files), `cat` for files -# TODO: actually `highlight` for fancy colors function lscat() { - [[ $# -eq 0 ]] && ls -la && return - printnewline="" - for f in "$@"; do - [[ $printnewline ]] && echo - printnewline=1 - if [[ -f $f ]]; then - [[ $# -gt 1 ]] && echo "-- cat \"$f\"" - cat "$f" - else - [[ $# -gt 1 ]] && echo "-- ls \"$f\"" - ls -la "$f" - fi - done + [[ $# -eq 0 ]] && ls -la && return + printnewline="" + for f in "$@"; do + [[ $printnewline ]] && echo + printnewline=1 + if [[ -f $f ]]; then + [[ $# -gt 1 ]] && echo "-- cat \"$f\"" + cat "$f" + else + [[ $# -gt 1 ]] && echo "-- ls \"$f\"" + ls -la "$f" + fi + done } # Shortcut for lscat (either c for cat or c for "see") alias c='lscat' function calc() { - echo "$@" | bc + echo "$@" | bc } # termbin.com: terminal pastebin diff --git a/.config/bashrc.d/30_desktop.sh b/.config/bashrc.d/30_desktop.sh index a7c5649..c0d556e 100644 --- a/.config/bashrc.d/30_desktop.sh +++ b/.config/bashrc.d/30_desktop.sh @@ -4,7 +4,7 @@ # Open files according to MIME type xo() { - (nohup mimeopen "$@" 2>/dev/null 1>&2 &) + (nohup mimeopen "$@" 2>/dev/null 1>&2 &) } # X application aliases diff --git a/.config/bashrc.d/60_server.sh b/.config/bashrc.d/60_server.sh index 2fdb984..9e41ec4 100644 --- a/.config/bashrc.d/60_server.sh +++ b/.config/bashrc.d/60_server.sh @@ -12,7 +12,7 @@ fi # Set prompt: highlight hostname in red to signalize "you're on a server, be careful" if [[ ${EUID} == 0 ]] ; then - PS1="${TRED}\u@\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" + PS1="${TRED}\u@\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" else - PS1="${TGREEN}\u@${TRED}\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" + PS1="${TGREEN}\u@${TRED}\h ${TBLUE}\w ${TWHITEB}\$ ${TRESET}" fi diff --git a/.config/git/config.inc/common.gitconfig b/.config/git/config.inc/common.gitconfig index 7be7d70..bfe6e16 100644 --- a/.config/git/config.inc/common.gitconfig +++ b/.config/git/config.inc/common.gitconfig @@ -1,6 +1,6 @@ [core] # Normalize line endings - autocrlf = input + autocrlf = input [advice] detachedHead = false @@ -41,10 +41,10 @@ helper = /usr/lib/git-core/git-credential-libsecret [filter "lfs"] - required = true - clean = git-lfs clean -- %f - smudge = git-lfs smudge -- %f - process = git-lfs filter-process + required = true + clean = git-lfs clean -- %f + smudge = git-lfs smudge -- %f + process = git-lfs filter-process [pretty] ls = tformat:%C(yellow)%h %Cgreen%ad %Creset%s %Cblue[%an]%C(auto)%d diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua deleted file mode 100644 index 9524df8..0000000 --- a/.config/nvim/init.lua +++ /dev/null @@ -1,128 +0,0 @@ --- Config shortcuts -local o = vim.o -local opt = vim.opt -local keymap = vim.keymap - - ------------------- --- GENERAL OPTIONS ------------------- - --- Line numbers -o.number = true -o.relativenumber = true - --- Highlight the cursor line -o.cursorline = true - --- Amount of screen lines that should be visible above/below the cursor -o.scrolloff = 8 - --- Show tabs and trailing spaces -o.list = true - --- Wrap lines at word boundaries -o.linebreak = true - --- Case insensitive search (except when explicitly using uppercase letters) -o.ignorecase = true -o.smartcase = true - --- Indentation settings -o.smartindent = true -o.expandtab = true -o.shiftwidth = 4 -o.softtabstop = -1 - --- Don't auto-insert comment leader when entering insert mode with o/O -vim.api.nvim_create_autocmd('FileType', { - command = 'set formatoptions-=o', -}) - - -------------- --- FILE TYPES -------------- - -vim.filetype.add { - extension = { - gitconfig = 'gitconfig', - }, -} - --- HTML formatting -vim.g.html_indent_autotags = 'html,body' -vim.g.html_indent_inctags = 'p' - - ------------ --- MAPPINGS ------------ - --- For keys that are safe to be mapped, see: https://vim.fandom.com/wiki/Unused_keys - --- Exit insert mode with jk -keymap.set('i', 'jk', '') - --- Quick exit with Ctrl-q -keymap.set('n', '', ':q') - --- Quick save all open buffers with Ctrl-s -keymap.set('n', '', ':wall') -keymap.set('i', '', ':wall') - --- Simple copy and paste to/from system clipboard with Ctrl-c in visual mode --- and Ctrl-v in insert mode -keymap.set('v', '', '"+y') -keymap.set('i', '', '"+P') - --- Navigate between windows with Alt and hjkl -keymap.set('n', '', 'h') -keymap.set('n', '', 'j') -keymap.set('n', '', 'k') -keymap.set('n', '', 'l') - --- Resize windows with Alt and arrow keys -keymap.set('n', '', '2-') -keymap.set('n', '', '2+') -keymap.set('n', '', '4<') -keymap.set('n', '', '4>') - --- Shortcuts for jumping to start of line (H) or end of line (L) -keymap.set({'n', 'x'}, 'H', '^') -keymap.set({'n', 'x'}, 'L', '$') - --- Use comma (,) as a "modifier prefix" for alternative functions of regular --- commands (e.g. yank to system clipboard) or for random shortcuts. --- TODO: Comma or semicolon or single quote? -keymap.set({'n', 'x'}, ',', '') - --- Prefix yank/delete/change/paste commands with "," to use system clipboard -keymap.set({'n', 'x'}, ',y', '"+y') -keymap.set({'n', 'x'}, ',Y', '"+y$') -keymap.set({'n', 'x'}, ',d', '"+d') -keymap.set({'n', 'x'}, ',D', '"+D') -keymap.set({'n', 'x'}, ',c', '"+c') -keymap.set({'n', 'x'}, ',C', '"+C') -keymap.set({'n', 'x'}, ',p', '"+p') -keymap.set({'n', 'x'}, ',P', '"+P') - --- Insert empty line(s) below or above current line without moving the cursor -keymap.set('n', ',o', function() - local line = vim.api.nvim_win_get_cursor(0)[1] - local repeated = vim.fn['repeat']({''}, vim.v.count1) - vim.api.nvim_buf_set_lines(0, line, line, true, repeated) -end) -keymap.set('n', ',O', function() - local line = vim.api.nvim_win_get_cursor(0)[1] - 1 - local repeated = vim.fn['repeat']({''}, vim.v.count1) - vim.api.nvim_buf_set_lines(0, line, line, true, repeated) -end) - - ----------- --- PLUGINS ----------- - -require('init.theme') -require('init.plugins') diff --git a/.config/nvim/lua/init/plugins.lua b/.config/nvim/lua/init/plugins.lua deleted file mode 100644 index 9f95917..0000000 --- a/.config/nvim/lua/init/plugins.lua +++ /dev/null @@ -1,103 +0,0 @@ --- Config shortcuts -local keymap = vim.keymap -local vr = vim.version.range - - ------------------- --- INSTALL PLUGINS ------------------- - -vim.pack.add { - -- Better code completion - { src = 'https://github.com/saghen/blink.cmp', version = vr '1.*' }, - - -- Better marks - 'https://github.com/chentoast/marks.nvim', - - -- Surround selections with quotes etc. - { src = 'https://github.com/kylechui/nvim-surround', version = vr '4.*' }, - - -- Substitute and exchange operator - 'https://github.com/gbprod/substitute.nvim', - - -- Highlight todo comments - 'https://github.com/folke/todo-comments.nvim', - - -- Highlight colors (hex codes etc.) - 'https://github.com/brenoprata10/nvim-highlight-colors', -} - - ---------------------- --- INITIALIZE PLUGINS ---------------------- - --- Better code completion -require('blink.cmp').setup { - keymap = { - preset = 'super-tab', - }, - cmdline = { - keymap = { - preset = 'inherit', - [''] = { - 'show', - 'select_and_accept', - 'fallback', - }, - }, - completion = { - menu = { auto_show = true }, - }, - }, -} - - --- Better marks -require('marks').setup { - -- Show builtin marks in gutter: last jump position (`), last change (.), - -- last selection in visual mode (). - -- TODO: See which of those are really helpful and remove the others. - builtin_marks = { '`', '.', '<', '>' }, -} - - --- Surround selections with quotes etc. -require('nvim-surround').setup {} - - --- Substitute and exchange operator -local substitute = require('substitute') -substitute.setup {} - --- ... Use "s" key for substitute (by default "s" is equivalent to "cl") -keymap.set('n', 's', substitute.operator) -keymap.set('n', 'ss', substitute.line) -keymap.set('n', 'S', substitute.eol) -keymap.set('x', 's', substitute.visual) - --- ... Prefix with "," to use system clipboard (remap to use the substitute mappings above) -keymap.set({'n', 'x'}, ',s', '"+s', { remap = true }) -keymap.set({'n', 'x'}, ',S', '"+S', { remap = true }) - - --- Highlight todo comments -require('todo-comments').setup { - -- Disable gutter icons - signs = false, - - -- Customize highlighting - highlight = { - before = '', - -- By default ("wide"), the surrounding space and colon are highlighted too, - -- which makes the colon invisible - keyword = 'bg', - after = 'fg', - -- Highlight keywords always, not just when followed by a colon (the default) - pattern = '<(KEYWORDS)>', - }, -} - - --- Highlight colors (hex codes etc.) -require('nvim-highlight-colors').setup {} diff --git a/.config/nvim/lua/init/theme.lua b/.config/nvim/lua/init/theme.lua deleted file mode 100644 index c805b9b..0000000 --- a/.config/nvim/lua/init/theme.lua +++ /dev/null @@ -1,36 +0,0 @@ --- Install theme plugins -vim.pack.add { - { src = 'https://github.com/rebelot/kanagawa.nvim', name = 'kanagawa' }, - -- { src = 'https://github.com/rose-pine/neovim', name = 'rose-pine' }, - -- { src = 'https://github.com/nickkadutskyi/jb.nvim', name = 'jetbrains-theme' }, -} - --- Initialize and customize themes -require('kanagawa').setup { - -- Compile colorscheme for fast startup times. - -- Note: When changing the theme, make sure to run `:KanagawaCompile` afterwards! - compile = true, - - -- Dim inactive windows - dimInactive = true, - - -- Customize colors - colors = { - theme = { - all = { - ui = { - -- Disable background of gutter (line numbers etc.) - bg_gutter = 'none', - }, - }, - }, - }, -} - ---require('rose-pine').setup {} ---require('jb').setup {} - --- Enable theme -vim.cmd.colorscheme('kanagawa') ---vim.cmd.colorscheme('rose-pine') ---vim.cmd.colorscheme('jb') diff --git a/.config/nvim/nvim-pack-lock.json b/.config/nvim/nvim-pack-lock.json deleted file mode 100644 index 7308339..0000000 --- a/.config/nvim/nvim-pack-lock.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "plugins": { - "blink.cmp": { - "rev": "78336bc89ee5365633bcf754d93df01678b5c08f", - "src": "https://github.com/saghen/blink.cmp", - "version": "1.0.0 - 2.0.0" - }, - "kanagawa": { - "rev": "bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3", - "src": "https://github.com/rebelot/kanagawa.nvim" - }, - "marks.nvim": { - "rev": "f353e8c08c50f39e99a9ed474172df7eddd89b72", - "src": "https://github.com/chentoast/marks.nvim" - }, - "nvim-highlight-colors": { - "rev": "e4c7af0211866162d999ce0bdd6a029302e19139", - "src": "https://github.com/brenoprata10/nvim-highlight-colors" - }, - "nvim-surround": { - "rev": "2e93e154de9ff326def6480a4358bfc149d5da2c", - "src": "https://github.com/kylechui/nvim-surround", - "version": "4.0.0 - 5.0.0" - }, - "substitute.nvim": { - "rev": "0d2077398552f069abccbd964a26dd7cd26882cd", - "src": "https://github.com/gbprod/substitute.nvim" - }, - "todo-comments.nvim": { - "rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668", - "src": "https://github.com/folke/todo-comments.nvim" - } - } -} diff --git a/.config/profile.d/30_desktop.sh b/.config/profile.d/30_desktop.sh index 8317cdd..3ed9f2d 100644 --- a/.config/profile.d/30_desktop.sh +++ b/.config/profile.d/30_desktop.sh @@ -14,10 +14,3 @@ export WINEDLLOVERRIDES=winemenubuilder.exe=d # Firefox: Enable pixel-perfect scrolling export MOZ_USE_XINPUT2=1 - -# Set dark theme for Gtk applications -export GTK_THEME=Adwaita:dark - -# Use qt6ct to configure Qt styling -# (You should install qt6ct-kde from AUR, as well as the breeze theme.) -export QT_QPA_PLATFORMTHEME=qt6ct diff --git a/.profile b/.profile index f68daa6..e58d5b9 100644 --- a/.profile +++ b/.profile @@ -22,12 +22,12 @@ export BC_ENV_ARGS="-lq" # Include drop-in files if [[ -d ~/.config/profile.d ]]; then - for f in ~/.config/profile.d/*; do - [[ -f $f ]] && source "$f" - done + for f in ~/.config/profile.d/*; do + [[ -f $f ]] && source "$f" + done fi # Deprecation warning for .profile.local if [[ -e ~/.profile.local ]]; then - echo "WARNING: ~/.profile.local is ignored, please use ~/.config/profile.d/ instead." + echo "WARNING: ~/.profile.local is ignored, please use ~/.config/profile.d/ instead." fi diff --git a/.vimrc b/.vimrc index 9001fcb..1e91ac6 100644 --- a/.vimrc +++ b/.vimrc @@ -1,23 +1,8 @@ " Visual settings set t_Co=16 set bg=dark -highlight LineNr ctermfg=darkgrey - -" Disable beeping on console -set belloff=all - -" Mouse settings -set mouse=a - -" Line numbers set number -set relativenumber - -" Amount of screen lines that should be visible above/below the cursor -set scrolloff=5 - -" Wrap lines at word boundaries -set linebreak +highlight LineNr ctermfg=darkgrey " Syntax highlighting syntax on @@ -27,11 +12,12 @@ set hlsearch set ignorecase set smartcase -" Indentation settings -set smartindent +" Indentation options (yeah let's switch to spaces instead of tabs I guess...) +set autoindent set expandtab set shiftwidth=4 -set softtabstop=-1 +set tabstop=4 +set softtabstop=4 " Activate filetype plugin (e.g. for automatically using tabs instead of spaces in Makefiles) filetype plugin on @@ -43,49 +29,120 @@ autocmd BufNewFile,BufRead *.rasi set syntax=scss " Indentation for YAML (use 2 spaces) autocmd FileType yml,yaml setlocal sts=2 sw=2 +" Mouse settings +set mouse=a + +" Disable beeping on console +set belloff=all + " Do not insert comment leader when entering insert mode with 'o'/'O' in comment line autocmd BufNewFile,BufRead * set formatoptions-=o +" clang autocomplete: do not open completion box automatically +let g:clang_complete_auto=0 + + +" Disable middle mouse button paste when in normal mode +map +map <2-MiddleMouse> +map <3-MiddleMouse> +map <4-MiddleMouse> + " Keyboard mappings " ----------------- - -nnoremap :nohl:diffupdate +nnoremap :nohl:diffupdate set pastetoggle= -" Exit insert mode with jk -inoremap jk +" Toggle line numbers +nnoremap :set number! -" Quick exit with Ctrl-q -nnoremap :q -nnoremap Q +" If the current buffer has never been saved, it will have no name, +" call the file browser to save it, otherwise just save it. +command! -nargs=0 -bar Update if &modified + \| if empty(bufname('%')) + \| browse confirm write + \| else + \| confirm write + \| endif + \|endif -" Quick save all open buffers with Ctrl-S -nnoremap :wall -inoremap :wall - -" Simple copy and paste to/from system clipboard with Ctrl-c in visual mode -" and Ctrl-v in insert mode -vnoremap "+y -inoremap "+P +" Bind to save +nnoremap :Update +inoremap :Update " sudo-write with :w!! cnoremap w!! w !sudo tee >/dev/null % +" Edit (\ev) and reload (\rv) .vimrc (reload .gvimrc if running gvim) +nnoremap ev :split $MYVIMRC +if has('gui_running') + nnoremap rv :source $MYVIMRC:source $MYGVIMRC +else + nnoremap rv :source $MYVIMRC +endif + +" Split line at cursor with (as opposite of for join lines) +nnoremap ik$ + + +" Easier buffer switching +" ----------------------- +" Mappings to access buffers (don't use "\p" because a +" delay before pressing "p" would accidentally paste). +" \l : list buffers +" \b \n \g : go back/forward/last-used +" \1 \2 \3 : go to buffer 1/2/3 etc +nnoremap l :ls +nnoremap b :bp +nnoremap n :bn +nnoremap g :e# +nnoremap 1 :1b +nnoremap 2 :2b +nnoremap 3 :3b +nnoremap 4 :4b +nnoremap 5 :5b +nnoremap 6 :6b +nnoremap 7 :7b +nnoremap 8 :8b +nnoremap 9 :9b +nnoremap 0 :10b + +" Compiling and making +nnoremap :up:make:redraw! \| cw +nnoremap :up:make run:redraw! \| cw + +" Tab buffers +nnoremap :tab ball + " Tab movement noremap :-tabmove noremap :+tabmove -" Use comma (,) as a "modifier prefix" for alternative functions of regular -" commands (e.g. yank to system clipboard) or for random shortcuts. -noremap , -" Prefix yank/delete/change/paste commands with "," to use system clipboard -noremap ,y "+y -noremap ,Y "+y$ -noremap ,d "+d -noremap ,D "+D -noremap ,c "+c -noremap ,C "+C -noremap ,p "+p -noremap ,P "+P +" -- Shortcuts for insert mode +" Exit insert mode +imap ,, +imap jk +inoremap + +" Quick movement with Alt-h/j/k/l +inoremap h +inoremap j +inoremap k +inoremap l + +" Unindent with Shift-Tab +inoremap << + +" Copy to and paste from X clipboard (Ctrl-C in visual mode and Ctrl-V in insert mode) +vmap "+y +imap "+P + +" Undo in insert mode with Ctrl-U +imap u + +" Quick exit +map Q :qa +" Because I always type q: too fast, which opens the command history... +map q: :q diff --git a/bin/dotfiles b/bin/dotfiles index af55641..c175440 100755 --- a/bin/dotfiles +++ b/bin/dotfiles @@ -2,49 +2,49 @@ ## ## binaryDiv's dotfiles management script -## Version 0.5.3 +## Version 0.5.2 ## usage() { - cat << END_OF_HELPTEXT - Usage: $(basename $0) COMMAND [...] - Manage dotfiles via git. + cat <<- END_OF_HELPTEXT + Usage: $(basename $0) COMMAND [...] + Manage dotfiles via git. - General commands: - help print this help message + General commands: + help print this help message - Installation: - install run this on first start: install dotfiles script in ~/bin, configure git, ... - (this will NOT create links for all dotfiles, though) + Installation: + install run this on first start: install dotfiles script in ~/bin, configure git, ... + (this will NOT create links for all dotfiles, though) - Dotfile management: - ls [DIR] list contents of .dotfiles directory (or DIR relative to it) - (-l: list host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME/DIR) - edit FILE open ~/.dotfiles/FILE in vim - (-l: open host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME/DIR) - diff FILE use vimdiff to compare ~/FILE to ~/.dotfiles/FILE - (-l: compare host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME/DIR) - link FILE... create a symlink from ~/FILE to ~/.dotfiles/FILE (multiple files possible) - (-q: be quiet, only print something if an error occurs) - (-l: link host-specific files, i.e. ~/FILE to ~/.dotfiles/_local/HOSTNAME/FILE) - linkstatus [DIR] list contents of .dotfiles with information about whether there are links to - them in ~/, whether they differ, etc... - (-l: show linkstatus only for host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME) - createfrom FILE... copy ~/FILE to ~/.dotfiles/FILE and symlink the file - (-n: only copy, leave the original, do not create symlink) - (-l: create host-specific files, i.e. ~/FILE to ~/.dotfiles/_local/HOSTNAME/FILE) + Dotfile management: + ls [DIR] list contents of .dotfiles directory (or DIR relative to it) + (-l: list host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME/DIR) + edit FILE open ~/.dotfiles/FILE in vim + (-l: open host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME/DIR) + diff FILE use vimdiff to compare ~/FILE to ~/.dotfiles/FILE + (-l: compare host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME/DIR) + link FILE... create a symlink from ~/FILE to ~/.dotfiles/FILE (multiple files possible) + (-q: be quiet, only print something if an error occurs) + (-l: link host-specific files, i.e. ~/FILE to ~/.dotfiles/_local/HOSTNAME/FILE) + linkstatus [DIR] list contents of .dotfiles with information about whether there are links to + them in ~/, whether they differ, etc... + (-l: show linkstatus only for host-specific files, i.e. ~/.dotfiles/_local/HOSTNAME) + createfrom FILE... copy ~/FILE to ~/.dotfiles/FILE and symlink the file + (-n: only copy, leave the original, do not create symlink) + (-l: create host-specific files, i.e. ~/FILE to ~/.dotfiles/_local/HOSTNAME/FILE) - Synchronization: - git ARGS... wrapper for git (all arguments are passed on to git) - pull shortcut for git pull -END_OF_HELPTEXT + Synchronization: + git ARGS... wrapper for git (all arguments are passed on to git) + pull shortcut for git pull + END_OF_HELPTEXT } # Define root dir for dotfiles management (defaults to $HOME, can be overridden # with environment variables for debugging) if [[ -z $DOTFILESROOT ]]; then - DOTFILESROOT="$HOME" + DOTFILESROOT="$HOME" fi # Set variables @@ -62,315 +62,315 @@ shift # Parse command case "$cmd" in - help|--help|-h) - usage - exit 1 - ;; + help|--help|-h) + usage + exit 1 + ;; - install) - bin_source="$dotfilesdir/bin/dotfiles" - bin_target="$homedir/bin/dotfiles" - bin_dir="$homedir/bin" + install) + bin_source="$dotfilesdir/bin/dotfiles" + bin_target="$homedir/bin/dotfiles" + bin_dir="$homedir/bin" - if [[ ! -e $bin_target ]]; then - echo "* Installing dotfiles script in $bin_dir/" - mkdir -pv "$bin_dir" - ln -sr "$bin_source" "$bin_target" || exit 1 - elif [[ ! "$(realpath $bin_target)" -ef "$bin_source" ]]; then - echo "! Warning: File $bin_target already exists but is NOT a link to $bin_source" - fi + if [[ ! -e $bin_target ]]; then + echo "* Installing dotfiles script in $bin_dir/" + mkdir -pv "$bin_dir" + ln -sr "$bin_source" "$bin_target" || exit 1 + elif [[ ! "$(realpath $bin_target)" -ef "$bin_source" ]]; then + echo "! Warning: File $bin_target already exists but is NOT a link to $bin_source" + fi - if [[ ":$PATH:" != *":$bin_dir:"* ]]; then - echo "! Warning: $bin_dir is not in your PATH." - fi + if [[ ":$PATH:" != *":$bin_dir:"* ]]; then + echo "! Warning: $bin_dir is not in your PATH." + fi - show_bash_restart_info= + show_bash_restart_info= - # Enable user-defined bash completion per directory - bashcompletion_filename=.bash_completion - if [[ ! -e "$homedir/$bashcompletion_filename" ]] || - [[ ! "$(realpath "$homedir/$bashcompletion_filename")" -ef "$dotfilesdir/$bashcompletion_filename" ]]; - then - echo "* Installing user-defined bash completion (~/.bash_completion.d/)" - "$0" link -q "$bashcompletion_filename" && - show_bash_restart_info=1 - fi - mkdir -p "$homedir/.bash_completion.d" + # Enable user-defined bash completion per directory + bashcompletion_filename=.bash_completion + if [[ ! -e "$homedir/$bashcompletion_filename" ]] || + [[ ! "$(realpath "$homedir/$bashcompletion_filename")" -ef "$dotfilesdir/$bashcompletion_filename" ]]; + then + echo "* Installing user-defined bash completion (~/.bash_completion.d/)" + "$0" link -q "$bashcompletion_filename" && + show_bash_restart_info=1 + fi + mkdir -p "$homedir/.bash_completion.d" - # Activate dotfiles bash completion - bashcompletion_dotfiles_filename=.bash_completion.d/10-dotfiles.sh - if [[ ! -e "$homedir/$bashcompletion_dotfiles_filename" ]] || - [[ ! "$(realpath "$homedir/$bashcompletion_dotfiles_filename")" -ef "$dotfilesdir/$bashcompletion_dotfiles_filename" ]]; - then - echo "* Installing bash completion for dotfiles script" - "$0" link -q "$bashcompletion_dotfiles_filename" && - show_bash_restart_info=1 - fi + # Activate dotfiles bash completion + bashcompletion_dotfiles_filename=.bash_completion.d/10-dotfiles.sh + if [[ ! -e "$homedir/$bashcompletion_dotfiles_filename" ]] || + [[ ! "$(realpath "$homedir/$bashcompletion_dotfiles_filename")" -ef "$dotfilesdir/$bashcompletion_dotfiles_filename" ]]; + then + echo "* Installing bash completion for dotfiles script" + "$0" link -q "$bashcompletion_dotfiles_filename" && + show_bash_restart_info=1 + fi - if [[ -n $show_bash_restart_info ]]; then - echo " Restart bash or run 'source $homedir/.bash_completion' to activate it now" - fi + if [[ -n $show_bash_restart_info ]]; then + echo " Restart bash or run 'source $homedir/.bash_completion' to activate it now" + fi - echo "* Configuring git settings" - git -C "$dotfilesdir" config merge.ff only - ;; + echo "* Configuring git settings" + git -C "$dotfilesdir" config merge.ff only + ;; - ls) - lsdir="$dotfilesdir" - [[ $1 = "-l" ]] && { lsdir="$lsdir/$dotfiles_local_prefix"; shift; } - [[ -n $1 ]] && lsdir="$lsdir/$1" + ls) + lsdir="$dotfilesdir" + [[ $1 = "-l" ]] && { lsdir="$lsdir/$dotfiles_local_prefix"; shift; } + [[ -n $1 ]] && lsdir="$lsdir/$1" - echo "$lsdir:" - ls -lAh --color=auto "$lsdir" - ;; + echo "$lsdir:" + ls -lAh --color=auto "$lsdir" + ;; - linkstatus) - cd "$dotfilesdir" + linkstatus) + cd "$dotfilesdir" - subdir="$1" - [[ $subdir = "-l" ]] && { subdir="$dotfiles_local_prefix/$1"; shift; } + subdir="$1" + [[ $subdir = "-l" ]] && { subdir="$dotfiles_local_prefix/$1"; shift; } - if [[ -n $subdir ]]; then - subdir="${subdir%/}" - [[ $subdir = $dotfiles_local_base ]] && subdir=$dotfiles_local_prefix + if [[ -n $subdir ]]; then + subdir="${subdir%/}" + [[ $subdir = $dotfiles_local_base ]] && subdir=$dotfiles_local_prefix - [[ -e $subdir ]] || { echo "$dotfilesdir/$subdir does not exist"; exit 1; } - [[ -d $subdir ]] && subdir="$subdir/" - fi + [[ -e $subdir ]] || { echo "$dotfilesdir/$subdir does not exist"; exit 1; } + [[ -d $subdir ]] && subdir="$subdir/" + fi - shopt -s nullglob dotglob - dotdirs=() + shopt -s nullglob dotglob + dotdirs=() - for file in $subdir*; do - [[ -e $file ]] || continue - [[ $file = ".git" ]] && continue + for file in $subdir*; do + [[ -e $file ]] || continue + [[ $file = ".git" ]] && continue - file_home="$homedir/$file" - file_dotfiles="$dotfilesdir/$file" + file_home="$homedir/$file" + file_dotfiles="$dotfilesdir/$file" - if [[ $subdir == $dotfiles_local_base/* ]]; then - file_home="$homedir/${file#$dotfiles_local_prefix/}" - fi + if [[ $subdir == $dotfiles_local_base/* ]]; then + file_home="$homedir/${file#$dotfiles_local_prefix/}" + fi - if [[ -e $file_home ]]; then - if [[ "$(realpath "$file_home")" -ef "$file_dotfiles" ]]; then - file_status=" LINKED " - elif [[ -d $file_home ]]; then - dotdirs+=($file) - continue - elif [[ -f $file_home ]] && cmp --silent "$file_home" "$file_dotfiles"; then - file_status="== EQUAL " - else - file_status="<> DIFFERS " - fi - elif [[ $file = $dotfiles_local_base ]]; then - dotdirs=("$dotfiles_local_prefix" "${dotdirs[@]}") - continue - else - if [[ -d $file_dotfiles ]]; then - file_status="++ NEW DIR " - else - file_status="++ NEW FILE" - fi - fi + if [[ -e $file_home ]]; then + if [[ "$(realpath "$file_home")" -ef "$file_dotfiles" ]]; then + file_status=" LINKED " + elif [[ -d $file_home ]]; then + dotdirs+=($file) + continue + elif [[ -f $file_home ]] && cmp --silent "$file_home" "$file_dotfiles"; then + file_status="== EQUAL " + else + file_status="<> DIFFERS " + fi + elif [[ $file = $dotfiles_local_base ]]; then + dotdirs=("$dotfiles_local_prefix" "${dotdirs[@]}") + continue + else + if [[ -d $file_dotfiles ]]; then + file_status="++ NEW DIR " + else + file_status="++ NEW FILE" + fi + fi - [[ -d $file_dotfiles ]] && file="$file/" - echo "$file_status $file" - done + [[ -d $file_dotfiles ]] && file="$file/" + echo "$file_status $file" + done - if [[ $dotdirs ]]; then - echo - for dir in ${dotdirs[@]}; do - echo "[$dir]" - dotfiles linkstatus "$dir" | grep '\(LINKED\|EQUAL\|DIFFERS\|NEW\)' - echo - done - fi - ;; + if [[ $dotdirs ]]; then + echo + for dir in ${dotdirs[@]}; do + echo "[$dir]" + dotfiles linkstatus "$dir" | grep '\(LINKED\|EQUAL\|DIFFERS\|NEW\)' + echo + done + fi + ;; - edit) - basedir=$dotfilesdir - [[ $1 = "-l" ]] && { basedir="$basedir/$dotfiles_local_prefix"; shift; } - [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } - vim "$basedir/$1" - ;; + edit) + basedir=$dotfilesdir + [[ $1 = "-l" ]] && { basedir="$basedir/$dotfiles_local_prefix"; shift; } + [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } + vim "$basedir/$1" + ;; - diff) - basedir=$dotfilesdir - [[ $1 = "-l" ]] && { basedir="$basedir/$dotfiles_local_prefix"; shift; } - [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } - file_A="$homedir/$1" - file_B="$basedir/$1" + diff) + basedir=$dotfilesdir + [[ $1 = "-l" ]] && { basedir="$basedir/$dotfiles_local_prefix"; shift; } + [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } + file_A="$homedir/$1" + file_B="$basedir/$1" - if [[ "$(realpath "$file_A")" -ef "$file_B" ]]; then - echo "$file_A is a link to $file_B" - else - vimdiff "$file_A" "$file_B" - fi - ;; + if [[ "$(realpath "$file_A")" -ef "$file_B" ]]; then + echo "$file_A is a link to $file_B" + else + vimdiff "$file_A" "$file_B" + fi + ;; - link) - while getopts ":ql" opt; do - case $opt in - q) QUIET=1 ;; - l) link_local=1 ;; - \?) - echo "Invalid option: -$OPTARG" - exit 1 - ;; - esac - done - shift $((OPTIND-1)) + link) + while getopts ":ql" opt; do + case $opt in + q) QUIET=1 ;; + l) link_local=1 ;; + \?) + echo "Invalid option: -$OPTARG" + exit 1 + ;; + esac + done + shift $((OPTIND-1)) - [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } + [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } - for filename in "$@"; do - file_home="$homedir/$filename" - file_dotfiles="$dotfilesdir/$filename" + for filename in "$@"; do + file_home="$homedir/$filename" + file_dotfiles="$dotfilesdir/$filename" - if [[ $link_local ]]; then - file_dotfiles="$dotfilesdir/$dotfiles_local_prefix/$filename" - fi + if [[ $link_local ]]; then + file_dotfiles="$dotfilesdir/$dotfiles_local_prefix/$filename" + fi - if [[ ! -e $file_dotfiles ]]; then - echo "! $file_dotfiles: target file does not exist" - exit 1 - fi + if [[ ! -e $file_dotfiles ]]; then + echo "! $file_dotfiles: target file does not exist" + exit 1 + fi - if [[ -e $file_home ]]; then - if [[ "$(realpath "$file_home")" -ef "$file_dotfiles" ]]; then - # Target is already a link to the correct file - continue - fi + if [[ -e $file_home ]]; then + if [[ "$(realpath "$file_home")" -ef "$file_dotfiles" ]]; then + # Target is already a link to the correct file + continue + fi - if cmp --silent "$file_home" "$file_dotfiles"; then - echo "! $file_home already exists and is equal to $file_dotfiles" - read -p " Delete $file_home and create link? [y/N] " -r - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - # Don't delete file - continue - fi - rm "$file_home" || exit 1 - else - echo "! $file_home already exists but is NOT a link to $file_dotfiles, please fix manually" - exit 1 - fi - fi + if cmp --silent "$file_home" "$file_dotfiles"; then + echo "! $file_home already exists and is equal to $file_dotfiles" + read -p " Delete $file_home and create link? [y/N] " -r + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + # Don't delete file + continue + fi + rm "$file_home" || exit 1 + else + echo "! $file_home already exists but is NOT a link to $file_dotfiles, please fix manually" + exit 1 + fi + fi - [[ $QUIET ]] || echo "* Creating link $file_home -> $file_dotfiles" - mkdir -p "$(dirname "$file_home")" || exit 1 - ln -sr "$file_dotfiles" "$file_home" || exit 1 - done - ;; + [[ $QUIET ]] || echo "* Creating link $file_home -> $file_dotfiles" + mkdir -p "$(dirname "$file_home")" || exit 1 + ln -sr "$file_dotfiles" "$file_home" || exit 1 + done + ;; - createfrom) - while getopts ":nl" opt; do - case $opt in - n) NOLINK=1 ;; - l) create_local=1 ;; - \?) - echo "Invalid option: -$OPTARG" - exit 1 - ;; - esac - done - shift $((OPTIND-1)) + createfrom) + while getopts ":nl" opt; do + case $opt in + n) NOLINK=1 ;; + l) create_local=1 ;; + \?) + echo "Invalid option: -$OPTARG" + exit 1 + ;; + esac + done + shift $((OPTIND-1)) - [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } + [[ -n $1 ]] || { echo "$(basename $0) $cmd: Missing argument."; exit 1; } - for filename in "$@"; do - file_home="$homedir/$filename" - file_dotfiles="$dotfilesdir/$filename" + for filename in "$@"; do + file_home="$homedir/$filename" + file_dotfiles="$dotfilesdir/$filename" - if [[ $create_local ]]; then - file_dotfiles="$dotfilesdir/$dotfiles_local_prefix/$filename" - fi + if [[ $create_local ]]; then + file_dotfiles="$dotfilesdir/$dotfiles_local_prefix/$filename" + fi - if [[ ! -e $file_home ]]; then - echo "! $file_home: source file does not exist" - exit 1 - elif [[ -e $file_dotfiles ]]; then - echo "! $file_dotfiles already exists" - exit 1 - else - mkdir -p "$(dirname "$file_dotfiles")" - [[ $QUIET ]] || echo "* Copy $file_home -> $file_dotfiles" - cp -n "$file_home" "$file_dotfiles" || exit 1 - if [[ ! $NOLINK ]]; then - [[ $QUIET ]] || echo "* Remove original and link $file_home -> $file_dotfiles" - rm "$file_home" || exit 1 - ln -sr "$file_dotfiles" "$file_home" || exit 1 - fi - fi - done - ;; + if [[ ! -e $file_home ]]; then + echo "! $file_home: source file does not exist" + exit 1 + elif [[ -e $file_dotfiles ]]; then + echo "! $file_dotfiles already exists" + exit 1 + else + mkdir -p "$(dirname "$file_dotfiles")" + [[ $QUIET ]] || echo "* Copy $file_home -> $file_dotfiles" + cp -n "$file_home" "$file_dotfiles" || exit 1 + if [[ ! $NOLINK ]]; then + [[ $QUIET ]] || echo "* Remove original and link $file_home -> $file_dotfiles" + rm "$file_home" || exit 1 + ln -sr "$file_dotfiles" "$file_home" || exit 1 + fi + fi + done + ;; + + git) + git -C "$dotfilesdir" "$@" + ;; - git) - git -C "$dotfilesdir" "$@" - ;; + pull) + git -C "$dotfilesdir" pull "$@" + ;; - pull) - git -C "$dotfilesdir" pull "$@" - ;; + bash-completion) + cat <<- 'END_OF_BASHCOMPLETION' + _dotfiles_filenames() { + compopt -o filenames + files=($(compgen -f -X '*/@(.|..|.git)' .dotfiles/$cur)) + COMPREPLY=(${files[@]#.dotfiles/}) + } + _dotfiles_filenames_local() { + compopt -o filenames + dotfiles_prefix=.dotfiles/_local/$(hostname) + files=($(compgen -f -X '*/@(.|..|.git)' $dotfiles_prefix/$cur)) + COMPREPLY=(${files[@]#$dotfiles_prefix/}) + } + _dotfiles() { + COMPREPLY=() + local cur="${COMP_WORDS[COMP_CWORD]}" + local commands="help install ls edit diff link linkstatus createfrom git pull" + local gitcommands="add commit diff fetch log pull push rebase status" - bash-completion) - cat << 'END_OF_BASHCOMPLETION' - _dotfiles_filenames() { - compopt -o filenames - files=($(compgen -f -X '*/@(.|..|.git)' .dotfiles/$cur)) - COMPREPLY=(${files[@]#.dotfiles/}) - } - _dotfiles_filenames_local() { - compopt -o filenames - dotfiles_prefix=.dotfiles/_local/$(hostname) - files=($(compgen -f -X '*/@(.|..|.git)' $dotfiles_prefix/$cur)) - COMPREPLY=(${files[@]#$dotfiles_prefix/}) - } - _dotfiles() { - COMPREPLY=() - local cur="${COMP_WORDS[COMP_CWORD]}" - local commands="help install ls edit diff link linkstatus createfrom git pull" - local gitcommands="add commit diff fetch log pull push rebase status" + if [[ $COMP_CWORD -eq 1 ]]; then + COMPREPLY=($(compgen -W "$commands" -- $cur)) + else + case "${COMP_WORDS[1]}" in + ls|edit|diff) + [[ $COMP_CWORD -eq 2 ]] && _dotfiles_filenames + ;; - if [[ $COMP_CWORD -eq 1 ]]; then - COMPREPLY=($(compgen -W "$commands" -- $cur)) - else - case "${COMP_WORDS[1]}" in - ls|edit|diff) - [[ $COMP_CWORD -eq 2 ]] && _dotfiles_filenames - ;; + link|linkstatus) + if [[ $COMP_CWORD -gt 2 && ${COMP_WORDS[2]} = "-l" ]]; then + _dotfiles_filenames_local + else + _dotfiles_filenames + fi + ;; - link|linkstatus) - if [[ $COMP_CWORD -gt 2 && ${COMP_WORDS[2]} = "-l" ]]; then - _dotfiles_filenames_local - else - _dotfiles_filenames - fi - ;; + createfrom) + compopt -o filenames + COMPREPLY=($(compgen -f -- ${cur})) + ;; - createfrom) - compopt -o filenames - COMPREPLY=($(compgen -f -- ${cur})) - ;; + git) + if [[ $COMP_CWORD -eq 2 ]]; then + COMPREPLY=($(compgen -W "$gitcommands" -- ${cur})) + else + _dotfiles_filenames + fi + ;; + esac + fi + } - git) - if [[ $COMP_CWORD -eq 2 ]]; then - COMPREPLY=($(compgen -W "$gitcommands" -- ${cur})) - else - _dotfiles_filenames - fi - ;; - esac - fi - } + complete -F _dotfiles dotfiles + END_OF_BASHCOMPLETION + ;; - complete -F _dotfiles dotfiles -END_OF_BASHCOMPLETION - ;; - - *) - echo "Unknown command '$cmd', use 'help' to show all commands." - exit 1 - ;; + *) + echo "Unknown command '$cmd', use 'help' to show all commands." + exit 1 + ;; esac