├── runcom ├── .bashrc ├── .bash_profile └── .inputrc ├── system ├── .n ├── .pnpm ├── .fix ├── .zoxide ├── .fzf ├── .function_git ├── .env.macos ├── .function.macos ├── .grep ├── .function ├── .path ├── .path.macos ├── .function_network ├── .function_text ├── .function_fs ├── .env ├── .alias.macos ├── .alias ├── .completion ├── .prompt └── .dir_colors ├── bin ├── is-arch ├── is-macos ├── is-arm64 ├── is-executable ├── append ├── git-editor ├── is-ubuntu ├── is-supported ├── json └── dot ├── install ├── Rustfile ├── pacmanfile ├── Codefile ├── npmfile ├── Caskfile ├── Brewfile └── duti ├── .github └── workflows │ ├── markdown-link-check.json │ ├── markdown-link-check.yml │ └── dotfiles-installation.yml ├── .gitignore ├── config ├── git │ ├── ignore │ └── config ├── prettier │ └── .prettierrc ├── topgrade.toml ├── thefuck │ └── settings.py └── tmux │ └── tmux.conf ├── .editorconfig ├── macos ├── dock.sh ├── defaults-chrome.sh └── defaults.sh ├── test ├── bin.bats └── function.bats ├── remote-install.sh ├── Makefile └── README.md /runcom/.bashrc: -------------------------------------------------------------------------------- 1 | .bash_profile -------------------------------------------------------------------------------- /system/.n: -------------------------------------------------------------------------------- 1 | export N_PREFIX="$HOME/.n" 2 | -------------------------------------------------------------------------------- /bin/is-arch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | [ -f /etc/arch-release ] 3 | -------------------------------------------------------------------------------- /system/.pnpm: -------------------------------------------------------------------------------- 1 | export PNPM_HOME="$XDG_DATA_HOME/pnpm" 2 | -------------------------------------------------------------------------------- /install/Rustfile: -------------------------------------------------------------------------------- 1 | cargo-cache 2 | cargo-update 3 | jless 4 | just 5 | -------------------------------------------------------------------------------- /system/.fix: -------------------------------------------------------------------------------- 1 | is-executable thefuck && eval $(thefuck --alias fix) 2 | -------------------------------------------------------------------------------- /.github/workflows/markdown-link-check.json: -------------------------------------------------------------------------------- 1 | { 2 | "aliveStatusCodes": [0, 200, 429] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.lock.json 3 | __pycache__ 4 | system/.custom 5 | system/.exports 6 | -------------------------------------------------------------------------------- /config/git/ignore: -------------------------------------------------------------------------------- 1 | ._* 2 | .DS_Store 3 | .idea 4 | .vscode 5 | node_modules 6 | npm-debug.log 7 | -------------------------------------------------------------------------------- /system/.zoxide: -------------------------------------------------------------------------------- 1 | # https://github.com/ajeetdsouza/zoxide 2 | 3 | eval "$(zoxide init bash)" 4 | -------------------------------------------------------------------------------- /bin/is-macos: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ "$OSTYPE" =~ ^darwin ]]; then 4 | exit 0 5 | else 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /bin/is-arm64: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ "$(uname -m)" == "arm64" ]]; then 4 | exit 0 5 | else 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /bin/is-executable: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if type "$1" >/dev/null 2>&1; then 4 | exit 0 5 | else 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /bin/append: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | APPEND="$1" 4 | TARGET="$2" 5 | 6 | pcregrep -qM "$APPEND" "$TARGET" || echo "$APPEND" >> "$TARGET" 7 | -------------------------------------------------------------------------------- /bin/git-editor: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if command -v code >/dev/null 2>&1; then 3 | exec code --wait "$@" 4 | else 5 | exec "$EDITOR" "$@" 6 | fi 7 | -------------------------------------------------------------------------------- /bin/is-ubuntu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -f /etc/os-release ]; then 3 | . /etc/os-release 4 | [ "$ID" = "ubuntu" ] 5 | else 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /config/prettier/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "bracketSameLine": true, 5 | "jsxSingleQuote": false, 6 | "arrowParens": "avoid" 7 | } 8 | -------------------------------------------------------------------------------- /install/pacmanfile: -------------------------------------------------------------------------------- 1 | acl 2 | base-devel 3 | bash-completion 4 | curl 5 | fd 6 | fzf 7 | git 8 | git-delta 9 | nano 10 | nfs-utils 11 | openbsd-netcat 12 | rsync 13 | sudo 14 | tree 15 | unzip 16 | wget 17 | zoxide 18 | -------------------------------------------------------------------------------- /system/.fzf: -------------------------------------------------------------------------------- 1 | eval "$(fzf --bash)" 2 | 3 | export FZF_CTRL_R_OPTS=" 4 | --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort' 5 | --color header:italic 6 | --header 'Press CTRL-Y to copy command into clipboard'" 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /install/Codefile: -------------------------------------------------------------------------------- 1 | adpyke.codesnap 2 | dbaeumer.vscode-eslint 3 | eamodio.gitlens 4 | esbenp.prettier-vscode 5 | hediet.vscode-drawio 6 | naumovs.color-highlight 7 | redhat.vscode-yaml 8 | sharat.vscode-brewfile 9 | stkb.rewrap 10 | -------------------------------------------------------------------------------- /install/npmfile: -------------------------------------------------------------------------------- 1 | @antfu/ni 2 | fast-cli 3 | fkill-cli 4 | get-port-cli 5 | gtop 6 | local-web-server 7 | npm 8 | npm-check-updates 9 | pnpm 10 | prettier 11 | release-it 12 | remark-cli 13 | remark-preset-webpro 14 | svgo 15 | tldr 16 | tsx 17 | underscore-cli 18 | yarn 19 | -------------------------------------------------------------------------------- /system/.function_git: -------------------------------------------------------------------------------- 1 | function git() { 2 | if [ $1 = "c" ] 3 | then 4 | local url="$2"; 5 | [[ "$url" =~ ^[^:]+/.+$ ]] && url="git@github.com:${url}.git" 6 | command git clone "$url" "${@:3}" && cdl 7 | else 8 | command git "$@" 9 | fi 10 | } 11 | -------------------------------------------------------------------------------- /bin/is-supported: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -eq 1 ]; then 4 | if eval "$1" > /dev/null 2>&1; then 5 | exit 0 6 | else 7 | exit 1 8 | fi 9 | else 10 | if eval "$1" > /dev/null 2>&1; then 11 | echo -n "$2" 12 | else 13 | echo -n "$3" 14 | fi 15 | fi 16 | -------------------------------------------------------------------------------- /install/Caskfile: -------------------------------------------------------------------------------- 1 | cask "firefox" 2 | cask "font-fira-code" 3 | cask "font-hack" 4 | cask "fork" 5 | cask "google-chrome" 6 | cask "google-chrome@canary" 7 | cask "maccy" 8 | cask "ngrok" 9 | cask "proton-drive" 10 | cask "raycast" 11 | cask "slack" 12 | cask "visual-studio-code" 13 | cask "vlc" 14 | -------------------------------------------------------------------------------- /config/topgrade.toml: -------------------------------------------------------------------------------- 1 | # Help: `topgrade --config-reference` (displays https://github.com/topgrade-rs/topgrade/blob/main/config.example.toml) 2 | 3 | [misc] 4 | assume_yes = true 5 | disable = ["containers", "git_repos", "pnpm", "yarn", "node"] 6 | display_time = false 7 | cleanup = true 8 | 9 | [commands] 10 | "npm" = "npm update --location global --force" 11 | -------------------------------------------------------------------------------- /config/thefuck/settings.py: -------------------------------------------------------------------------------- 1 | # rules = ['sudo', 'no_command'] 2 | # exclude_rules = ['git_push'] 3 | require_confirmation = True 4 | wait_command = 10 5 | no_colors = False 6 | priority = {'sudo': 100, 'no_command': 9999} 7 | debug = False 8 | history_limit = 9999 9 | alter_history = True 10 | # wait_slow_command = 20 11 | # slow_commands = ['react-native', 'gradle'] 12 | num_close_matches = 5 13 | -------------------------------------------------------------------------------- /bin/json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | OPT_COLOR="" 4 | 5 | while getopts ":c" OPT; do 6 | case "$OPT" in 7 | c) OPT_COLOR="--color";; 8 | esac 9 | done 10 | 11 | shift $((OPTIND-1)) 12 | 13 | if [ $# -ge 1 ]; then 14 | if [[ "$1" == http* ]]; then 15 | INPUT=$(curl --silent "$1") 16 | elif [ -f "$1" ]; then 17 | INPUT=$(cat "$1") 18 | fi 19 | else 20 | INPUT=$(cat -) 21 | fi 22 | 23 | echo "$INPUT" | underscore print "$OPT_COLOR" 24 | -------------------------------------------------------------------------------- /system/.env.macos: -------------------------------------------------------------------------------- 1 | export EDITOR="code" 2 | export VISUAL="code" 3 | export VISUAL_GIT="fork" 4 | 5 | # Some app locations 6 | 7 | export CHROME_BIN="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 8 | export CHROME_CANARY_BIN="/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary" 9 | export FIREFOX_BIN="/Applications/Firefox.app/Contents/MacOS/firefox-bin" 10 | 11 | # Raise limit for open files and processes 12 | 13 | ulimit -S -n 8192 14 | -------------------------------------------------------------------------------- /macos/dock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dockutil --no-restart --remove all 4 | dockutil --no-restart --add "/Applications/Google Chrome.app" 5 | dockutil --no-restart --add "/System/Applications/Mail.app" 6 | dockutil --no-restart --add "/System/Applications/Calendar.app" 7 | dockutil --no-restart --add "/System/Applications/Utilities/Terminal.app" 8 | dockutil --no-restart --add "/System/Applications/System Settings.app" 9 | dockutil --no-restart --add "/Applications/Spotify.app" 10 | 11 | killall Dock 12 | -------------------------------------------------------------------------------- /system/.function.macos: -------------------------------------------------------------------------------- 1 | # Change working directory to the top-most Finder window location 2 | 3 | function cdf() { 4 | cd "$(osascript -e 'tell app "Finder" to POSIX path of (insertion location as alias)')"; 5 | } 6 | 7 | # Dev 8 | 9 | d() { 10 | $VISUAL ${1:-.} 11 | $VISUAL_GIT ${1:-.} 12 | } 13 | 14 | # Get Bundle ID of macOS app 15 | # Example: bundleid terminal 16 | 17 | bundleid() { 18 | local ID=$( osascript -e 'id of app "'"$1"'"' ) 19 | if [ ! -z $ID ]; then 20 | echo $ID | tr -d '[:space:]' | pbcopy 21 | echo "$ID (copied to clipboard)" 22 | fi 23 | } 24 | -------------------------------------------------------------------------------- /system/.grep: -------------------------------------------------------------------------------- 1 | # Tell grep to highlight matches 2 | 3 | if is-supported "grep --color a <<< a"; then 4 | GREP_OPTIONS+=" --color=auto" 5 | fi 6 | 7 | # Avoid VCS folders 8 | 9 | if is-supported "echo | grep --exclude-dir=.cvs ''"; then 10 | for PATTERN in .cvs .git .hg .svn; do 11 | GREP_OPTIONS+=" --exclude-dir=$PATTERN" 12 | done 13 | elif is-supported "echo | grep --exclude=.cvs ''"; then 14 | for PATTERN in .cvs .git .hg .svn; do 15 | GREP_OPTIONS+=" --exclude=$PATTERN" 16 | done 17 | fi 18 | 19 | unset PATTERN 20 | alias grep="grep $GREP_OPTIONS" 21 | export GREP_COLORS='mt=1;32' 22 | -------------------------------------------------------------------------------- /.github/workflows/markdown-link-check.yml: -------------------------------------------------------------------------------- 1 | name: Check Markdown links 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | # Run every Tuesday at 3:00 AM (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07) 9 | - cron: "0 3 * * 2" 10 | 11 | jobs: 12 | markdown-link-check: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@master 16 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 17 | with: 18 | use-quiet-mode: "yes" 19 | config-file: .github/workflows/markdown-link-check.json 20 | -------------------------------------------------------------------------------- /macos/defaults-chrome.sh: -------------------------------------------------------------------------------- 1 | # Disable swipe navigation 2 | defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool false 3 | defaults write com.google.Chrome.canary AppleEnableSwipeNavigateWithScrolls -bool false 4 | 5 | # Use the system-native print preview dialog 6 | defaults write com.google.Chrome DisablePrintPreview -bool true 7 | defaults write com.google.Chrome.canary DisablePrintPreview -bool true 8 | 9 | # Expand the print dialog by default 10 | defaults write com.google.Chrome PMPrintingExpandedStateForPrint2 -bool true 11 | defaults write com.google.Chrome.canary PMPrintingExpandedStateForPrint2 -bool true 12 | -------------------------------------------------------------------------------- /system/.function: -------------------------------------------------------------------------------- 1 | # Switch long/short prompt 2 | 3 | ps0() { 4 | unset PROMPT_COMMAND 5 | PS1='$ ' 6 | } 7 | 8 | ps1() { 9 | source "$DOTFILES_DIR"/system/.prompt 10 | } 11 | 12 | ps2() { 13 | unset PROMPT_COMMAND 14 | PS1="${P_GREEN}$ ${P_RESET}" 15 | } 16 | 17 | # Get named var (usage: get "VAR_NAME") 18 | 19 | get() { 20 | echo "${!1}" 21 | } 22 | 23 | # Calculator 24 | 25 | calc() { 26 | echo "$*" | bc -l; 27 | } 28 | 29 | # Weather 30 | 31 | meteo() { 32 | local LOCALE=$(echo ${LANG:-en} | cut -c1-2) 33 | local LOCATION="$*" 34 | LOCATION="${LOCATION// /%20}" 35 | curl -s "$LOCALE.wttr.in/${LOCATION:-}" 36 | } 37 | -------------------------------------------------------------------------------- /test/bin.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | @test "dot" { 4 | run dot 5 | [[ $output =~ "Usage" ]] 6 | } 7 | 8 | @test "json" { 9 | ACTUAL=$(echo '{"x":1}' | json) 10 | EXPECTED=$'{ "x": 1 }' 11 | [ "$ACTUAL" = "$EXPECTED" ] 12 | } 13 | 14 | @test "is-executable" { 15 | run is-executable ls 16 | [ "$status" -eq 0 ] 17 | } 18 | 19 | @test "is-executable (false)" { 20 | run is-executable nonexistent 21 | [ "$status" -eq 1 ] 22 | } 23 | 24 | @test "is-supported" { 25 | run is-supported ls -a 26 | [ "$status" -eq 0 ] 27 | } 28 | 29 | @test "is-supported (false)" { 30 | run is-supported "ls --nonexistent" 31 | [ "$status" -eq 1 ] 32 | } 33 | -------------------------------------------------------------------------------- /system/.path: -------------------------------------------------------------------------------- 1 | # Start with system path 2 | # Retrieve it from getconf, otherwise it's just current $PATH 3 | 4 | is-executable getconf && PATH=$($(command -v getconf) PATH) 5 | 6 | prepend-path() { 7 | [ -d $1 ] && PATH="$1:$PATH" 8 | } 9 | 10 | # Prepend new items to path (if directory exists) 11 | 12 | prepend-path "/bin" 13 | prepend-path "/sbin" 14 | prepend-path "/usr/bin" 15 | prepend-path "/usr/sbin" 16 | prepend-path "/usr/local/bin" 17 | prepend-path "$DOTFILES_DIR/bin" 18 | 19 | is-macos && . "$DOTFILES_DIR/system/.path.macos" 20 | 21 | # Remove duplicates 22 | PATH=$(echo -n $PATH | awk -v RS=: '{ if (!arr[$0]++) {printf("%s%s",!ln++?"":":",$0)}}') 23 | 24 | export PATH 25 | -------------------------------------------------------------------------------- /system/.path.macos: -------------------------------------------------------------------------------- 1 | export HOMEBREW_PREFIX=$($DOTFILES_DIR/bin/is-supported $DOTFILES_DIR/bin/is-arm64 /opt/homebrew /usr/local) 2 | 3 | # Prepend new items to path (if directory exists) 4 | 5 | prepend-path "$HOMEBREW_PREFIX/bin" 6 | prepend-path "$HOMEBREW_PREFIX/sbin" 7 | prepend-path "$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin" 8 | prepend-path "$HOMEBREW_PREFIX/opt/gnu-sed/libexec/gnubin" 9 | prepend-path "$HOMEBREW_PREFIX/opt/grep/libexec/gnubin" 10 | prepend-path "$HOMEBREW_PREFIX/opt/python/libexec/bin" 11 | prepend-path "$HOMEBREW_PREFIX/opt/ruby/bin" 12 | prepend-path "$HOME/.bun/bin" 13 | prepend-path "$HOME/.cargo/bin" 14 | prepend-path "$HOME/.local/share/pnpm" 15 | prepend-path "$N_PREFIX/bin" 16 | -------------------------------------------------------------------------------- /remote-install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SOURCE="https://github.com/webpro/dotfiles" 4 | TARBALL="$SOURCE/tarball/main" 5 | TARGET="$HOME/.dotfiles" 6 | TAR_CMD="tar -xzv -C "$TARGET" --strip-components=1 --exclude='{.gitignore}'" 7 | 8 | is_executable() { 9 | type "$1" > /dev/null 2>&1 10 | } 11 | 12 | if is_executable "git"; then 13 | CMD="git clone $SOURCE $TARGET" 14 | elif is_executable "curl"; then 15 | CMD="curl -#L $TARBALL | $TAR_CMD" 16 | elif is_executable "wget"; then 17 | CMD="wget --no-check-certificate -O - $TARBALL | $TAR_CMD" 18 | fi 19 | 20 | if [ -z "$CMD" ]; then 21 | echo "No git, curl or wget available. Aborting." 22 | else 23 | echo "Installing dotfiles..." 24 | mkdir -p "$TARGET" 25 | eval "$CMD" 26 | fi 27 | -------------------------------------------------------------------------------- /system/.function_network: -------------------------------------------------------------------------------- 1 | # Webserver 2 | 3 | srv() { 4 | local DIR=${1:-.} 5 | local AVAILABLE_PORT=$(get-port 8000) 6 | local PORT=${2:-$AVAILABLE_PORT} 7 | if [ "$PORT" -le "1024" ]; then 8 | sudo -v 9 | fi 10 | open "http://localhost:$PORT" 11 | ws --directory "$DIR" --port "$PORT" 12 | } 13 | 14 | # Get IP from hostname 15 | 16 | hostname2ip() { 17 | ping -c 1 "$1" | egrep -m1 -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' 18 | } 19 | 20 | # Upload file to transfer.sh 21 | # https://github.com/dutchcoders/transfer.sh/ 22 | 23 | transfer() { 24 | tmpfile=$( mktemp -t transferXXX ) 25 | curl --progress-bar --upload-file "$1" https://transfer.sh/$(basename $1) >> $tmpfile; 26 | cat $tmpfile; 27 | rm -f $tmpfile; 28 | } 29 | 30 | # Find real from shortened url 31 | 32 | unshorten() { 33 | curl -sIL $1 | sed -n 's/Location: *//p' 34 | } 35 | -------------------------------------------------------------------------------- /install/Brewfile: -------------------------------------------------------------------------------- 1 | tap "homebrew/bundle" 2 | tap "lotyp/homebrew-formulae" 3 | 4 | # core/dotfiles 5 | brew "bats-core" 6 | brew "coreutils" 7 | brew "duti" 8 | brew "lotyp/formulae/dockutil" 9 | brew "nano" 10 | brew "stow" 11 | brew "thefuck" 12 | brew "tmux" 13 | brew "topgrade" 14 | 15 | # fs/network 16 | brew "bat" 17 | brew "croc" 18 | brew "eza" 19 | brew "httpie" 20 | brew "ssh-copy-id" 21 | brew "tree" 22 | brew "unar" 23 | brew "wget" 24 | brew "zoxide" 25 | 26 | # search/grep/diff 27 | brew "fd" 28 | brew "fzf" 29 | brew "git-delta" 30 | brew "gnu-sed" 31 | brew "grep" 32 | brew "jq" 33 | brew "psgrep" 34 | brew "ripgrep" 35 | brew "the_silver_searcher" 36 | 37 | # languages/tools 38 | brew "cmake" 39 | brew "gh" 40 | brew "n" 41 | brew "python" 42 | brew "ruby" 43 | brew "rust" 44 | brew "shellcheck" 45 | 46 | # media 47 | brew "ffmpeg" 48 | brew "imagemagick" 49 | brew "optipng" 50 | brew "uni" 51 | brew "webp" 52 | 53 | # misc 54 | brew "grip" 55 | -------------------------------------------------------------------------------- /test/function.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load "../system/.function" 4 | load "../system/.function_text" 5 | 6 | FIXTURE=$'foo\nbar\nbaz\nfoo' 7 | FIXTURE_TEXT="foo" 8 | 9 | @test "get" { 10 | ACTUAL=$(get "FIXTURE_TEXT") 11 | EXPECTED="foo" 12 | [ "$ACTUAL" = "$EXPECTED" ] 13 | } 14 | 15 | @test "calc" { 16 | ACTUAL="$(calc 1+2)" 17 | EXPECTED=3 18 | [ "$ACTUAL" -eq "$EXPECTED" ] 19 | } 20 | 21 | @test "line" { 22 | ACTUAL=$(get "FIXTURE" | line 2) 23 | EXPECTED="bar" 24 | [ "$ACTUAL" = "$EXPECTED" ] 25 | } 26 | 27 | @test "line + surrounding lines" { 28 | ACTUAL=$(get "FIXTURE" | line 3 1) 29 | EXPECTED=$(echo -e "bar\nbaz\nfoo") 30 | [ "$ACTUAL" = "$EXPECTED" ] 31 | } 32 | 33 | @test "duplines" { 34 | ACTUAL=$(get "FIXTURE" | duplines) 35 | EXPECTED=$(echo -e "foo") 36 | [ "$ACTUAL" = "$EXPECTED" ] 37 | } 38 | 39 | @test "uniqlines" { 40 | ACTUAL=$(get "FIXTURE" | uniqlines) 41 | EXPECTED=$'bar\nbaz' 42 | [ "$ACTUAL" = "$EXPECTED" ] 43 | } 44 | -------------------------------------------------------------------------------- /system/.function_text: -------------------------------------------------------------------------------- 1 | # Show line in file with surrounding lines 2 | 3 | line() { 4 | local FILE LINE_NUMBER LINES_AROUND=0 5 | local NAME="${FUNCNAME[0]}" 6 | 7 | if [[ ! -t 0 ]]; then 8 | LINE_NUMBER=$1 9 | LINES_AROUND=${2:-$LINES_AROUND} 10 | elif [[ $1 =~ ^([^:]+):([0-9]+)(:[0-9]+)?$ ]]; then 11 | FILE="${BASH_REMATCH[1]}" 12 | LINE_NUMBER="${BASH_REMATCH[2]}" 13 | LINES_AROUND=${2:-$LINES_AROUND} 14 | else 15 | FILE=$1 16 | LINE_NUMBER=$2 17 | LINES_AROUND=${3:-$LINES_AROUND} 18 | fi 19 | 20 | if [[ -t 0 && -z "$FILE" || -z "$LINE_NUMBER" ]]; then 21 | echo "Usage: ${NAME} [lines_around=0] 22 | ${NAME} 23 | cat | ${NAME} [lines_around=0]" 24 | return 1 25 | fi 26 | 27 | if [[ -t 0 && -n "$FILE" && ! -f "$FILE" ]]; then 28 | echo "${NAME}: $FILE: No such file or directory" 29 | return 1 30 | fi 31 | 32 | sed -n "`expr $LINE_NUMBER - $LINES_AROUND`,`expr $LINE_NUMBER + $LINES_AROUND`p" ${FILE} 33 | } 34 | 35 | # Show duplicate/unique lines 36 | # Source: https://github.com/ain/.dotfiles/commit/967a2e65a44708449b6e93f87daa2721929cb87a 37 | 38 | duplines() { 39 | sort $1 | uniq -d 40 | } 41 | 42 | uniqlines() { 43 | sort $1 | uniq -u 44 | } 45 | -------------------------------------------------------------------------------- /runcom/.bash_profile: -------------------------------------------------------------------------------- 1 | # If not running interactively, don't do anything 2 | 3 | [ -z "$PS1" ] && return 4 | 5 | # Resolve DOTFILES_DIR (assuming ~/.dotfiles on distros without readlink and/or $BASH_SOURCE/$0) 6 | CURRENT_SCRIPT=$BASH_SOURCE 7 | 8 | if [[ -n $CURRENT_SCRIPT && -x readlink ]]; then 9 | SCRIPT_PATH=$(readlink -n $CURRENT_SCRIPT) 10 | DOTFILES_DIR="${PWD}/$(dirname $(dirname $SCRIPT_PATH))" 11 | elif [ -d "$HOME/.dotfiles" ]; then 12 | DOTFILES_DIR="$HOME/.dotfiles" 13 | elif [ -d "$HOME/dotfiles" ]; then 14 | DOTFILES_DIR="$HOME/dotfiles" 15 | else 16 | echo "Unable to find dotfiles, exiting." 17 | return 18 | fi 19 | 20 | # Make utilities available 21 | 22 | PATH="$DOTFILES_DIR/bin:$PATH" 23 | 24 | # Source the dotfiles (order matters) 25 | 26 | [ -f "$DOTFILES_DIR/system/.exports" ] && . "$DOTFILES_DIR/system/.exports" 27 | 28 | for DOTFILE in "$DOTFILES_DIR"/system/.{function,function_*,n,path,env,alias,fzf,grep,prompt,completion,fix,pnpm,zoxide}; do 29 | . "$DOTFILE" 30 | done 31 | 32 | if is-macos; then 33 | for DOTFILE in "$DOTFILES_DIR"/system/.{env,alias,function}.macos; do 34 | . "$DOTFILE" 35 | done 36 | fi 37 | 38 | # Set LSCOLORS 39 | 40 | eval "$(dircolors -b "$DOTFILES_DIR"/system/.dir_colors)" 41 | 42 | # Wrap up 43 | 44 | unset CURRENT_SCRIPT SCRIPT_PATH DOTFILE 45 | 46 | export DOTFILES_DIR 47 | -------------------------------------------------------------------------------- /runcom/.inputrc: -------------------------------------------------------------------------------- 1 | # Make Tab autocomplete regardless of filename case 2 | set completion-ignore-case on 3 | 4 | # List all matches in case multiple possible completions are possible 5 | set show-all-if-ambiguous on 6 | 7 | # Immediately add a trailing slash when autocompleting symlinks to directories 8 | set mark-symlinked-directories on 9 | 10 | # Show all autocomplete results at once 11 | set page-completions off 12 | 13 | # If there are more than 200 possible completions for a word, ask to show them all 14 | set completion-query-items 200 15 | 16 | # Show extra file information when completing, like `ls -F` does 17 | set visible-stats on 18 | 19 | # Be more intelligent when autocompleting by also looking at the text after 20 | # the cursor. For example, when the current line is "cd ~/src/mozil", and 21 | # the cursor is on the "z", pressing Tab will not autocomplete it to "cd 22 | # ~/src/mozillail", but to "cd ~/src/mozilla". (This is supported by the 23 | # Readline used by Bash 4.) 24 | set skip-completed-text on 25 | 26 | # Allow UTF-8 input and output, instead of showing stuff like $'\0123\0456' 27 | set input-meta on 28 | set output-meta on 29 | set convert-meta off 30 | 31 | # Flip through autocompletion matches with Shift-Tab. 32 | "\e[Z": menu-complete 33 | 34 | # Filtered history search 35 | "\e[A": history-search-backward 36 | "\e[B": history-search-forward 37 | -------------------------------------------------------------------------------- /.github/workflows/dotfiles-installation.yml: -------------------------------------------------------------------------------- 1 | name: Dotfiles Installation 2 | 3 | on: 4 | push: 5 | schedule: 6 | - cron: "0 17 * * 4" # Every Thursday 5:00PM 7 | 8 | jobs: 9 | install: 10 | runs-on: ${{ matrix.os }} 11 | strategy: 12 | matrix: 13 | os: [macos-14, macos-15, ubuntu-latest] 14 | 15 | steps: 16 | - name: Clean up installed software 17 | if: startsWith(matrix.os, 'macos') 18 | run: | 19 | brew uninstall --ignore-dependencies --force $(brew list --formula) 20 | # brew uninstall --cask --force $(brew list --cask) 21 | brew uninstall --cask --force firefox google-chrome 22 | brew cleanup --prune-prefix 23 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)" 24 | 25 | - name: Download and install available system updates 26 | # Step disabled since it also tries to update macOS itself and there seems no way to disable this 27 | if: ${{ false && startsWith(matrix.os, 'macos') }} 28 | run: sudo softwareupdate -i -a 29 | 30 | - name: Clone this repository 31 | uses: actions/checkout@v3 32 | 33 | - name: Install using Makefile 34 | run: | 35 | if [ "$RUNNER_OS" == "macOS" ]; then 36 | make 37 | else 38 | sudo make 39 | fi 40 | 41 | - name: Load & verify runcom setup 42 | run: source $HOME/.bash_profile 43 | 44 | - name: Run tests 45 | if: startsWith(matrix.os, 'macos') 46 | run: make test 47 | -------------------------------------------------------------------------------- /system/.function_fs: -------------------------------------------------------------------------------- 1 | # Create a new directory and enter it 2 | 3 | mk() { 4 | mkdir -p "$@" && cd "$@" 5 | } 6 | 7 | # cd into latest created directory 8 | 9 | cdl() { 10 | cd "$(ls -dt */ | head -n 1)" 11 | } 12 | 13 | # Show disk usage of current folder, or list with depth 14 | 15 | duf() { 16 | du --max-depth=${1:-0} -c | sort -r -n | awk '{split("K M G",v); s=1; while($1>1024){$1/=1024; s++} print int($1)v[s]"\t"$2}' 17 | } 18 | 19 | # Check if resource is served compressed 20 | 21 | check_compression() { 22 | curl --write-out 'Size (uncompressed) = %{size_download}\n' --silent --output /dev/null $1 23 | curl --header 'Accept-Encoding: gzip,deflate,compress' --write-out 'Size (compressed) = %{size_download}\n' --silent --output /dev/null $1 24 | curl --head --header 'Accept-Encoding: gzip,deflate' --silent $1 | grep -i "cache\|content\|vary\|expires" 25 | } 26 | 27 | # Get gzipped file size 28 | 29 | gz() { 30 | local ORIGSIZE=$(wc -c < "$1") 31 | local GZIPSIZE=$(gzip -c "$1" | wc -c) 32 | local RATIO=$(echo "$GZIPSIZE * 100/ $ORIGSIZE" | bc -l) 33 | local SAVED=$(echo "($ORIGSIZE - $GZIPSIZE) * 100/ $ORIGSIZE" | bc -l) 34 | printf "orig: %d bytes\ngzip: %d bytes\nsave: %2.0f%% (%2.0f%%)\n" "$ORIGSIZE" "$GZIPSIZE" "$SAVED" "$RATIO" 35 | } 36 | 37 | # Create a data URL from a file 38 | 39 | dataurl() { 40 | local MIMETYPE=$(file --mime-type "$1" | cut -d ' ' -f2) 41 | if [[ $MIMETYPE == "text/*" ]]; then 42 | MIMETYPE="${MIMETYPE};charset=utf-8" 43 | fi 44 | echo "data:${MIMETYPE};base64,$(openssl base64 -in "$1" | tr -d '\n')" 45 | } 46 | 47 | # Tree 48 | 49 | t() { 50 | tree -AdL ${1:-1} 51 | } 52 | -------------------------------------------------------------------------------- /system/.env: -------------------------------------------------------------------------------- 1 | export EDITOR="nano" 2 | export VISUAL="nano" 3 | 4 | # XDG Base Directory Specification (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) 5 | 6 | export XDG_CACHE_HOME="$HOME/.cache" 7 | export XDG_CONFIG_HOME="$HOME/.config" 8 | export XDG_DATA_HOME="$HOME/.local/share" 9 | export XDG_STATE_HOME="$HOME/.local/state" 10 | export XDG_RUNTIME_DIR="$HOME/.local/runtime" # macOS does not have session lifetime directories; alt: `~/Library/Caches` 11 | 12 | # History 13 | 14 | export HISTSIZE=32768; 15 | export HISTFILESIZE="${HISTSIZE}"; 16 | export SAVEHIST=4096 17 | export HISTCONTROL=ignoredups:erasedups 18 | 19 | # Enable colors 20 | 21 | export CLICOLOR=1 22 | 23 | # Prefer US English and use UTF-8 24 | 25 | export LC_ALL="en_US.UTF-8" 26 | export LANG="en_US.UTF-8" 27 | 28 | # Highlight section titles in man pages 29 | 30 | export LESS_TERMCAP_md="${yellow}"; 31 | 32 | # Keep showing man page after exit 33 | 34 | export MANPAGER='less -X'; 35 | 36 | # Case-insensitive globbing (used in pathname expansion) 37 | 38 | shopt -s nocaseglob 39 | 40 | # Recursive globbing with "**" 41 | 42 | if [ ${BASH_VERSINFO[0]} -ge 4 ]; then 43 | shopt -s globstar 44 | fi 45 | 46 | # Append to the Bash history file, rather than overwriting it 47 | 48 | shopt -s histappend 49 | 50 | # Autocorrect typos in path names when using `cd` 51 | 52 | shopt -s cdspell 53 | 54 | # Do not autocomplete when accidentally pressing Tab on an empty line. 55 | 56 | shopt -s no_empty_cmd_completion 57 | 58 | # Check the window size after each command and, if necessary, 59 | # update the values of LINES and COLUMNS. 60 | 61 | shopt -s checkwinsize 62 | -------------------------------------------------------------------------------- /system/.alias.macos: -------------------------------------------------------------------------------- 1 | # Copy pwd to clipboard 2 | 3 | alias cpwd="pwd|tr -d '\n'|pbcopy" 4 | 5 | # Get local IP address 6 | 7 | alias ipl="ifconfig | grep 'inet ' | grep -v 127.0.0.1 | awk '{print \$2}' | head -1" 8 | 9 | # Application shortcuts 10 | 11 | alias gg="$VISUAL_GIT" 12 | 13 | alias chrome="open -a /Applications/Google\ Chrome.app" 14 | alias canary="open -a /Applications/Google\ Chrome\ Canary.app" 15 | alias firefox="open -a /Applications/Firefox.app" 16 | 17 | # Exclude macOS specific files in ZIP archives 18 | 19 | alias zip="zip -x *.DS_Store -x *__MACOSX* -x *.AppleDouble*" 20 | 21 | # Start screen saver 22 | 23 | alias afk="open /System/Library/CoreServices/ScreenSaverEngine.app" 24 | 25 | # Log off 26 | 27 | alias logoff="/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend" 28 | 29 | # Recursively remove Apple meta files 30 | 31 | alias cleanupds="find . -type f -name '*.DS_Store' -ls -delete" 32 | alias cleanupad="find . -type d -name '.AppleD*' -ls -exec /bin/rm -r {} \;" 33 | 34 | # Clean up LaunchServices to remove duplicates in the "Open With" menu 35 | 36 | alias lscleanup="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user && killall Finder" 37 | 38 | # Empty trash on mounted volumes and main HDD, and clear system logs 39 | 40 | alias emptytrash="sudo rm -rfv /Volumes/*/.Trashes; sudo rm -rfv ~/.Trash/*; sudo rm -rfv /private/var/log/asl/*.asl" 41 | 42 | # Reload native apps 43 | 44 | alias killfinder="killall Finder" 45 | alias killdock="killall Dock" 46 | alias killmenubar="killall SystemUIServer NotificationCenter" 47 | alias killos="killfinder && killdock && killmenubar" 48 | 49 | # Show system information 50 | 51 | alias displays="system_profiler SPDisplaysDataType" 52 | alias cpu="sysctl -n machdep.cpu.brand_string" 53 | alias ram="top -l 1 -s 0 | grep PhysMem" 54 | -------------------------------------------------------------------------------- /bin/dot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BIN_NAME=$(basename "$0") 4 | COMMAND_NAME=$1 5 | SUB_COMMAND_NAME=$2 6 | 7 | sub_help () { 8 | echo "Usage: $BIN_NAME " 9 | echo 10 | echo "Commands:" 11 | echo " clean Clean up caches (brew, cargo, gem, pip)" 12 | echo " dock Apply macOS Dock settings" 13 | echo " duti Set default apps for file types (UTI)" 14 | echo " edit Open dotfiles in IDE ($VISUAL) and Git GUI ($VISUAL_GIT)" 15 | echo " help This help message" 16 | echo " macos Apply macOS system defaults" 17 | echo " test Run tests" 18 | echo " update Update packages and pkg managers (brew, casks, cargo, pip3, npm, gems, macOS)" 19 | } 20 | 21 | sub_clean () { 22 | echo "$ brew cleanup" 23 | brew cleanup 24 | echo "$ cargo cache --autoclean" 25 | cargo cache --autoclean 26 | echo "$ gem cleanup" 27 | gem cleanup 28 | echo "$ pip cache purge" 29 | pip cache purge 30 | } 31 | 32 | sub_dock () { 33 | . "${DOTFILES_DIR}/macos/dock.sh" && echo "Dock reloaded." 34 | } 35 | 36 | sub_edit () { 37 | sh -c "$VISUAL $DOTFILES_DIR" 38 | sh -c "$VISUAL_GIT $DOTFILES_DIR" 39 | } 40 | 41 | sub_test () { 42 | bats "$DOTFILES_DIR"/test/*.bats 43 | } 44 | 45 | sub_update () { 46 | topgrade 47 | } 48 | 49 | sub_duti () { 50 | duti -v "${DOTFILES_DIR}/install/duti" 51 | } 52 | 53 | sub_macos () { 54 | for DEFAULTS_FILE in "${DOTFILES_DIR}"/macos/defaults*.sh; do 55 | echo "Applying ${DEFAULTS_FILE}" && . "${DEFAULTS_FILE}" 56 | done 57 | echo "Done. Some changes may require a logout/restart to take effect." 58 | } 59 | 60 | case $COMMAND_NAME in 61 | "" | "-h" | "--help") 62 | sub_help 63 | ;; 64 | *) 65 | shift 66 | sub_${COMMAND_NAME} $@ 67 | if [ $? = 127 ]; then 68 | echo "'$COMMAND_NAME' is not a known command or has errors." >&2 69 | sub_help 70 | exit 1 71 | fi 72 | ;; 73 | esac 74 | -------------------------------------------------------------------------------- /system/.alias: -------------------------------------------------------------------------------- 1 | # Shortcuts 2 | 3 | alias reload="source ~/.bash_profile" 4 | alias _="sudo" 5 | alias g="git" 6 | alias rr="rm -rf" 7 | alias mux="tmuxinator" 8 | 9 | # Default options 10 | 11 | alias rsync="rsync -vh" 12 | alias json="json -c" 13 | alias psgrep="psgrep -i" 14 | 15 | # Global aliases 16 | 17 | if $(is-supported "alias -g"); then 18 | alias -g G="| grep -i" 19 | alias -g H="| head" 20 | alias -g T="| tail" 21 | alias -g L="| less" 22 | fi 23 | 24 | # List declared aliases, functions, paths 25 | 26 | alias aliases="alias | sed 's/=.*//'" 27 | alias functions="declare -f | grep '^[a-z].* ()' | sed 's/{$//'" 28 | alias paths='echo -e ${PATH//:/\\n}' 29 | 30 | # Directory listing/traversal 31 | 32 | LS_COLORIZED=$(is-supported "ls --color" --color -G) 33 | LS_TIMESTYLEISO=$(is-supported "ls --time-style=long-iso" --time-style=long-iso) 34 | LS_GROUPDIRSFIRST=$(is-supported "ls --group-directories-first" --group-directories-first) 35 | 36 | alias l="ls -lahA $LS_COLORIZED $LS_TIMESTYLEISO $LS_GROUPDIRSFIRST" 37 | alias ll="ls -lA $LS_COLORIZED" 38 | alias lt="ls -lhAtr $LS_COLORIZED $LS_TIMESTYLEISO $LS_GROUPDIRSFIRST" 39 | alias ld="ls -ld $LS_COLORIZED */" 40 | alias lp="stat -c '%a %n' *" 41 | 42 | unset LS_COLORIZED LS_TIMESTYLEISO LS_GROUPDIRSFIRST 43 | 44 | alias ..="cd .." 45 | alias ...="cd ../.." 46 | alias ....="cd ../../.." 47 | alias .....="cd ../../../.." 48 | alias -- -="cd -" # Go to previous dir with - 49 | alias cd.='cd $(readlink -f .)' # Go to real dir (i.e. if current dir is linked) 50 | 51 | # p/npm 52 | 53 | alias b="bun" 54 | alias p="pnpm" 55 | alias ncu="npm-check-updates --interactive" 56 | alias ncuw="npm-check-updates --interactive --root --workspaces" 57 | 58 | # Network 59 | 60 | alias ipp="dig +short myip.opendns.com @resolver1.opendns.com" 61 | alias ipl="ip route get 1.1.1.1 2>/dev/null | awk 'NR==1{print \$7}'" 62 | 63 | # Miscellaneous 64 | 65 | alias hosts="sudo $EDITOR /etc/hosts" 66 | alias quit="exit" 67 | alias week="date +%V" 68 | alias speedtest="wget -O /dev/null http://speed.transip.nl/100mb.bin" 69 | alias grip="grip --browser --pass=$GITHUB_TOKEN" 70 | alias fkill="ps -e | fzf | awk '{print $1}' | xargs kill" 71 | alias formatmd="remark --use remark-preset-webpro" 72 | -------------------------------------------------------------------------------- /system/.completion: -------------------------------------------------------------------------------- 1 | if [ -z "$HOMEBREW_PREFIX" ] && is-executable brew; then 2 | HOMEBREW_PREFIX=$(brew --prefix) 3 | fi 4 | 5 | # Bash 6 | 7 | if [ -f "/usr/share/bash-completion/bash_completion" ]; then 8 | . "/usr/share/bash-completion/bash_completion" 9 | elif [ -n "$HOMEBREW_PREFIX" ] && [ -f "$HOMEBREW_PREFIX/share/bash-completion/bash_completion" ]; then 10 | . "$HOMEBREW_PREFIX/share/bash-completion/bash_completion" 11 | fi 12 | 13 | # dot 14 | 15 | _dotfiles_completions() { 16 | local cur="${COMP_WORDS[COMP_CWORD]}" 17 | COMPREPLY=( $(compgen -W 'clean dock duti edit help macos test update' -- $cur ) ); 18 | } 19 | 20 | complete -o default -F _dotfiles_completions dot 21 | 22 | # tmux 23 | 24 | if is-executable tmux; then 25 | if [ -f "/usr/share/bash-completion/completions/tmux" ]; then 26 | . "/usr/share/bash-completion/completions/tmux" 27 | elif [ -n "$HOMEBREW_PREFIX" ] && [ -f "$HOMEBREW_PREFIX/etc/bash_completion.d/tmux" ]; then 28 | . "$HOMEBREW_PREFIX/etc/bash_completion.d/tmux" 29 | fi 30 | fi 31 | 32 | # npm (https://docs.npmjs.com/cli/completion) 33 | 34 | if is-executable npm; then 35 | . <(npm completion) 36 | fi 37 | 38 | # Git 39 | 40 | if is-executable git; then 41 | if [ -f "/usr/share/git/completion/git-completion.bash" ]; then 42 | . "/usr/share/git/completion/git-completion.bash" 43 | elif [ -n "$HOMEBREW_PREFIX" ] && [ -f "$HOMEBREW_PREFIX/etc/bash_completion.d/git-completion.bash" ]; then 44 | . "$HOMEBREW_PREFIX/etc/bash_completion.d/git-completion.bash" 45 | fi 46 | fi 47 | 48 | # pnpm (https://pnpm.io/completion) 49 | 50 | _pnpm_completion () { 51 | local words cword 52 | if type _get_comp_words_by_ref &>/dev/null; then 53 | _get_comp_words_by_ref -n = -n @ -n : -w words -i cword 54 | else 55 | cword="$COMP_CWORD" 56 | words=("${COMP_WORDS[@]}") 57 | fi 58 | 59 | local si="$IFS" 60 | IFS=$'\n' COMPREPLY=($(COMP_CWORD="$cword" \ 61 | COMP_LINE="$COMP_LINE" \ 62 | COMP_POINT="$COMP_POINT" \ 63 | SHELL=bash \ 64 | pnpm completion-server -- "${words[@]}" \ 65 | 2>/dev/null)) || return $? 66 | IFS="$si" 67 | 68 | if [ "$COMPREPLY" = "__tabtab_complete_files__" ]; then 69 | COMPREPLY=($(compgen -f -- "$cword")) 70 | fi 71 | 72 | if type __ltrim_colon_completions &>/dev/null; then 73 | __ltrim_colon_completions "${words[cword]}" 74 | fi 75 | } 76 | complete -o default -F _pnpm_completion pnpm 77 | -------------------------------------------------------------------------------- /config/git/config: -------------------------------------------------------------------------------- 1 | [user] 2 | name = Lars Kappert 3 | email = lars@webpro.nl 4 | 5 | [github] 6 | user = webpro 7 | 8 | [core] 9 | excludesfile = ~/.config/git/ignore 10 | editor = git-editor 11 | filemode = false 12 | trustctime = false 13 | autocrlf = input 14 | untrackedCache = true 15 | pager = delta 16 | ignorecase = false 17 | 18 | [credential] 19 | helper = osxkeychain 20 | 21 | [pull] 22 | rebase = true 23 | 24 | [rerere] 25 | enabled = true 26 | 27 | [rebase] 28 | autoStash = true 29 | 30 | [init] 31 | defaultBranch = main 32 | 33 | [push] 34 | default = simple 35 | followTags = true 36 | 37 | [fetch] 38 | prune = true 39 | 40 | [grep] 41 | lineNumber = true 42 | 43 | [help] 44 | autocorrect = 1 45 | 46 | [alias] 47 | amend = commit --amend --reuse-message=HEAD 48 | br = branch 49 | c = clone 50 | ci = commit 51 | co = checkout 52 | contrib = shortlog --summary --numbered 53 | d = diff 54 | diffstat = "!f() { if [ $# -eq 0 ]; then git show --shortstat HEAD | tail -1; else git show --shortstat $1 | tail -1; fi; }; f" 55 | ds = -c delta.side-by-side=true diff 56 | fc = "log --max-parents=0 --pretty=format:'%ad' --date=format:'%Y-%m-%d' -n 1" 57 | g = grep --break --heading --line-number 58 | home = browse 59 | l = log --graph --abbrev-commit --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' 60 | ld = "!sh -c \"git log --since '${1:-1} days ago' --oneline --author $(git config user.email)\" -" 61 | ll = log --graph --abbrev-commit --pretty=oneline 62 | lm = log --pretty=format:'* %s (%h)' 63 | now = "!f() { GIT_SEQUENCE_EDITOR=: git rebase -i HEAD~${1:-1} --exec \"git commit --amend --no-edit --date=\\\"$(date)\\\"\"; }; f" 64 | p = push 65 | patch = !git --no-pager diff --no-color 66 | pf = push --force 67 | rv = remote -vv 68 | rh = reset --hard HEAD 69 | ra = rebase --abort 70 | rc = rebase --continue 71 | squash-all = "!f() { git reset $(git commit-tree HEAD^{tree} -m \"${1:-Initial commit}\"); }; f" 72 | s = status 73 | show-ignored = !git clean -ndX | perl -pe 's/Would remove //' 74 | sshort = "!f() { git show --shortstat \"${1:-HEAD}\" | awk \"/files? changed/ { gsub(/,/, \\\"\\\", \\$4); gsub(/,/, \\\"\\\", \\$6); print \\\"\\033[32m+\\\" \\$4 \\\" \\033[31m-\\\" \\$6 \\\"\\033[0m\\\" }\"; }; f" 75 | 76 | [diff] 77 | renames = copies 78 | indentHeuristic = true 79 | colorMoved = default 80 | tool = vscode 81 | 82 | [difftool] 83 | prompt = false 84 | 85 | [difftool "vscode"] 86 | cmd = code --wait --diff $LOCAL $REMOTE 87 | path = 88 | 89 | [merge] 90 | conflictstyle = diff3 91 | defaultToUpstream = true 92 | tool = vscode 93 | 94 | [mergetool] 95 | prompt = false 96 | 97 | [mergetool "vscode"] 98 | cmd = code --wait $MERGED 99 | trustExitCode = true 100 | 101 | [delta] 102 | light = false 103 | navigate = true 104 | 105 | [color] 106 | ui = auto 107 | 108 | [versionsort] 109 | suffix = -alpha 110 | suffix = -beta 111 | suffix = -canary 112 | suffix = -rc 113 | suffix = -next 114 | 115 | [advice] 116 | detachedHead = false 117 | -------------------------------------------------------------------------------- /config/tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | # Enable 256 color support 2 | set -g default-terminal "screen-256color" 3 | set-window-option -g xterm-keys on 4 | 5 | # Use Ctrl-Space as prefix key + allow sending it to applications 6 | set -g prefix C-Space 7 | bind C-Space send-prefix 8 | 9 | # Remove delay when pressing escape key 10 | set -s escape-time 0 11 | 12 | # Increase scrollback buffer size 13 | set -g history-limit 50000 14 | 15 | # Update status bar every 5 seconds 16 | set -g status-interval 5 17 | 18 | # Bind prefix + : to open the command prompt 19 | bind-key : command-prompt 20 | 21 | # Aggressively resize windows 22 | setw -g aggressive-resize on 23 | 24 | # Enhance status bar 25 | setw -g automatic-rename-format "#P #{pane_current_path} #{pane_current_command}" 26 | 27 | # Don't exit tmux after kill-session 28 | set-option -g detach-on-destroy off 29 | 30 | # Kill session with prefix + X 31 | bind X confirm-before -y kill-session 32 | 33 | # Remove right status bar content 34 | set -g status-right '' 35 | 36 | # Start window and pane numbering at 1 37 | set -g base-index 1 38 | setw -g pane-base-index 1 39 | 40 | # Automatically renumber windows when one is closed 41 | set -g renumber-windows on 42 | 43 | # Add pane using \ or | for horizontal, - or _ for vertical split 44 | # bind '\' split-window -h 45 | bind '|' split-window -h 46 | bind - split-window -v 47 | bind _ split-window -v 48 | 49 | # Reload this config with 'prefix + r' 50 | bind r source-file $HOME/.dotfiles/config/tmux/.tmux.conf \; display "Config reloaded" 51 | 52 | # Navigate between panes using Shift + ←/→ 53 | bind -n S-right select-pane -t :.+ 54 | bind -n S-left select-pane -t :.- 55 | 56 | # Clear screen and history with Ctrl-k 57 | bind -n C-k send-keys -R Enter \; clear-history \; 58 | 59 | # Switch to oldest session or match 60 | bind d command-prompt -p "session abbr:" "run 'tmux switch -t $(tmux ls -F \"##{session_created}:##{session_name}\" | sort -n | grep \':%%\' | head -n 1 | cut -d \':\' -f 2)'" 61 | 62 | # Enable mouse support for pane selection and scrolling only 63 | # macOS only 64 | set -g mouse on 65 | bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'select-pane -t=; copy-mode -e; send-keys -M'" 66 | bind -n WheelDownPane select-pane -t= \; send-keys -M 67 | bind -n C-WheelUpPane select-pane -t= \; copy-mode -e \; send-keys -M 68 | bind -T copy-mode-vi C-WheelUpPane send-keys -X halfpage-up 69 | bind -T copy-mode-vi C-WheelDownPane send-keys -X halfpage-down 70 | bind -T copy-mode-emacs C-WheelUpPane send-keys -X halfpage-up 71 | bind -T copy-mode-emacs C-WheelDownPane send-keys -X halfpage-down 72 | 73 | # To copy, left click and drag to highlight text in yellow, 74 | # once you release left click yellow text will disappear and will automatically be available in clibboard 75 | # # Use vim keybindings in copy mode 76 | setw -g mode-keys vi 77 | # Update default binding of `Enter` to also use copy-pipe 78 | unbind -T copy-mode-vi Enter 79 | bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy" 80 | bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy" 81 | 82 | bind-key -n Up send-keys Up 83 | bind-key -n Down send-keys Down 84 | bind-key -n Left send-keys Left 85 | bind-key -n Right send-keys Right 86 | -------------------------------------------------------------------------------- /install/duti: -------------------------------------------------------------------------------- 1 | com.microsoft.VSCode .alias editor 2 | com.microsoft.VSCode .astro editor 3 | com.microsoft.VSCode .bash editor 4 | com.microsoft.VSCode .bash_profile editor 5 | com.microsoft.VSCode .bashrc editor 6 | com.microsoft.VSCode .bats editor 7 | com.microsoft.VSCode .cfg editor 8 | com.microsoft.VSCode .cjs editor 9 | com.microsoft.VSCode .colors editor 10 | com.microsoft.VSCode .completion editor 11 | com.microsoft.VSCode .conf editor 12 | com.microsoft.VSCode .config editor 13 | com.microsoft.VSCode .css editor 14 | com.microsoft.VSCode .csv editor 15 | com.microsoft.VSCode .cts editor 16 | com.microsoft.VSCode .dir_colors editor 17 | com.microsoft.VSCode .env editor 18 | com.microsoft.VSCode .exports editor 19 | com.microsoft.VSCode .fix editor 20 | com.microsoft.VSCode .function editor 21 | com.microsoft.VSCode .function_fs editor 22 | com.microsoft.VSCode .function_network editor 23 | com.microsoft.VSCode .function_text editor 24 | com.microsoft.VSCode .gitignore editor 25 | com.microsoft.VSCode .graphql editor 26 | com.microsoft.VSCode .grep editor 27 | # com.microsoft.VSCode .html editor 28 | com.microsoft.VSCode .ignore editor 29 | com.microsoft.VSCode .ini editor 30 | com.microsoft.VSCode .inputrc editor 31 | com.microsoft.VSCode .js editor 32 | com.microsoft.VSCode .json editor 33 | com.microsoft.VSCode .jsonc editor 34 | com.microsoft.VSCode .jsx editor 35 | com.microsoft.VSCode .log editor 36 | com.microsoft.VSCode .lua editor 37 | com.microsoft.VSCode .macos editor 38 | com.microsoft.VSCode .macos editor 39 | com.microsoft.VSCode .map editor 40 | com.microsoft.VSCode .md editor 41 | com.microsoft.VSCode .mdx editor 42 | com.microsoft.VSCode .mjs editor 43 | com.microsoft.VSCode .mts editor 44 | com.microsoft.VSCode .n editor 45 | com.microsoft.VSCode .path editor 46 | com.microsoft.VSCode .prettierignore editor 47 | com.microsoft.VSCode .prettierrc editor 48 | com.microsoft.VSCode .prompt editor 49 | com.microsoft.VSCode .sh editor 50 | com.microsoft.VSCode .snap editor 51 | com.microsoft.VSCode .svelte editor 52 | com.microsoft.VSCode .svg editor 53 | com.microsoft.VSCode .toml editor 54 | com.microsoft.VSCode .ts editor 55 | com.microsoft.VSCode .tsv editor 56 | com.microsoft.VSCode .tsx editor 57 | com.microsoft.VSCode .txt editor 58 | com.microsoft.VSCode .vue editor 59 | com.microsoft.VSCode .yaml editor 60 | com.microsoft.VSCode .yml editor 61 | com.microsoft.VSCode .zoxide editor 62 | com.microsoft.VSCode Brewfile editor 63 | com.microsoft.VSCode Caskfile editor 64 | com.microsoft.VSCode Codefile editor 65 | com.microsoft.VSCode Dockerfile editor 66 | com.microsoft.VSCode Makefile editor 67 | com.microsoft.VSCode npmfile editor 68 | org.videolan.vlc .3gp all 69 | org.videolan.vlc .aac all 70 | org.videolan.vlc .aif all 71 | org.videolan.vlc .avi all 72 | org.videolan.vlc .flac all 73 | org.videolan.vlc .flv all 74 | org.videolan.vlc .iff all 75 | org.videolan.vlc .m4a all 76 | org.videolan.vlc .m4v all 77 | org.videolan.vlc .mid all 78 | org.videolan.vlc .mkv all 79 | org.videolan.vlc .mov all 80 | org.videolan.vlc .mp3 all 81 | org.videolan.vlc .mp4 all 82 | org.videolan.vlc .mpa all 83 | org.videolan.vlc .mpeg all 84 | org.videolan.vlc .mpg all 85 | org.videolan.vlc .mpg4 all 86 | org.videolan.vlc .ogg all 87 | org.videolan.vlc .ra all 88 | org.videolan.vlc .wav all 89 | org.videolan.vlc .webm all 90 | org.videolan.vlc .wma all 91 | org.videolan.vlc .wmv all 92 | -------------------------------------------------------------------------------- /system/.prompt: -------------------------------------------------------------------------------- 1 | ## Prompt 2 | 3 | _bash_prompt_config() { 4 | 5 | local USER_SYMBOL="\u" 6 | local HOST_SYMBOL="\h" 7 | local ESC_OPEN="\[" 8 | local ESC_CLOSE="\]" 9 | 10 | if tput setaf >/dev/null 2>&1 ; then 11 | _setaf () { tput setaf "$1" ; } 12 | local RESET="${ESC_OPEN}$( { tput sgr0 || tput me ; } 2>/dev/null )${ESC_CLOSE}" 13 | local BOLD="$( { tput bold || tput md ; } 2>/dev/null )" 14 | else 15 | # Fallback 16 | _setaf () { echo "\033[0;$(($1+30))m" ; } 17 | local RESET="\033[m" 18 | local BOLD="" 19 | ESC_OPEN="" 20 | ESC_CLOSE="" 21 | fi 22 | 23 | # Normal colors 24 | local BLACK="${ESC_OPEN}$(_setaf 0)${ESC_CLOSE}" 25 | local RED="${ESC_OPEN}$(_setaf 1)${ESC_CLOSE}" 26 | local GREEN="${ESC_OPEN}$(_setaf 2)${ESC_CLOSE}" 27 | local YELLOW="${ESC_OPEN}$(_setaf 3)${ESC_CLOSE}" 28 | local BLUE="${ESC_OPEN}$(_setaf 4)${ESC_CLOSE}" 29 | local VIOLET="${ESC_OPEN}$(_setaf 5)${ESC_CLOSE}" 30 | local CYAN="${ESC_OPEN}$(_setaf 6)${ESC_CLOSE}" 31 | local WHITE="${ESC_OPEN}$(_setaf 7)${ESC_CLOSE}" 32 | 33 | # Bright colors 34 | local BRIGHT_GREEN="${ESC_OPEN}$(_setaf 10)${ESC_CLOSE}" 35 | local BRIGHT_YELLOW="${ESC_OPEN}$(_setaf 11)${ESC_CLOSE}" 36 | local BRIGHT_BLUE="${ESC_OPEN}$(_setaf 12)${ESC_CLOSE}" 37 | local BRIGHT_VIOLET="${ESC_OPEN}$(_setaf 13)${ESC_CLOSE}" 38 | local BRIGHT_CYAN="${ESC_OPEN}$(_setaf 14)${ESC_CLOSE}" 39 | local BRIGHT_WHITE="${ESC_OPEN}$(_setaf 15)${ESC_CLOSE}" 40 | 41 | # Bold colors 42 | local BLACK_BOLD="${ESC_OPEN}${BOLD}$(_setaf 0)${ESC_CLOSE}" 43 | local RED_BOLD="${ESC_OPEN}${BOLD}$(_setaf 1)${ESC_CLOSE}" 44 | local GREEN_BOLD="${ESC_OPEN}${BOLD}$(_setaf 2)${ESC_CLOSE}" 45 | local YELLOW_BOLD="${ESC_OPEN}${BOLD}$(_setaf 3)${ESC_CLOSE}" 46 | local BLUE_BOLD="${ESC_OPEN}${BOLD}$(_setaf 4)${ESC_CLOSE}" 47 | local VIOLET_BOLD="${ESC_OPEN}${BOLD}$(_setaf 5)${ESC_CLOSE}" 48 | local CYAN_BOLD="${ESC_OPEN}${BOLD}$(_setaf 6)${ESC_CLOSE}" 49 | local WHITE_BOLD="${ESC_OPEN}${BOLD}$(_setaf 7)${ESC_CLOSE}" 50 | 51 | # Expose the variables we need in prompt command 52 | P_USER=${BRIGHT_GREEN}${USER_SYMBOL} 53 | P_HOST=${CYAN}${HOST_SYMBOL} 54 | P_WHITE=${WHITE} 55 | P_GREEN=${BRIGHT_GREEN} 56 | P_YELLOW=${YELLOW} 57 | P_RED=${RED} 58 | P_RESET=${RESET} 59 | 60 | } 61 | 62 | bash_prompt_command() { 63 | 64 | local EXIT_CODE=$? 65 | local P_EXIT="" 66 | local MAXLENGTH=35 67 | local TRUNC_SYMBOL=".." 68 | local DIR=${PWD##*/} 69 | local P_PWD=${PWD/#$HOME/\~} 70 | 71 | MAXLENGTH=$(( ( MAXLENGTH < ${#DIR} ) ? ${#DIR} : MAXLENGTH )) 72 | 73 | local OFFSET=$(( ${#P_PWD} - MAXLENGTH )) 74 | 75 | if [ ${OFFSET} -gt "0" ]; then 76 | P_PWD=${P_PWD:$OFFSET:$MAXLENGTH} 77 | P_PWD=${TRUNC_SYMBOL}/${P_PWD#*/} 78 | fi 79 | 80 | # Update terminal title 81 | if [[ $TERM == xterm* ]]; then 82 | echo -ne "\033]0;${P_PWD}\007" 83 | fi 84 | 85 | # Parse Git branch name 86 | P_GIT=$(parse_git_branch) 87 | 88 | # Exit code 89 | if [[ $EXIT_CODE != 0 ]]; then 90 | P_EXIT+="${P_RED}✘ " 91 | fi 92 | 93 | PS1="${P_EXIT}${P_USER}${P_WHITE}@${P_HOST} ${P_YELLOW}${P_PWD}${P_GREEN}${P_GIT}${P_YELLOW} ❯ ${P_RESET}" 94 | } 95 | 96 | parse_git_branch() { 97 | local OUT=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') 98 | if [ "$OUT" != "" ]; then echo " $OUT"; fi 99 | } 100 | 101 | _bash_prompt_config 102 | unset _bash_prompt_config 103 | 104 | PROMPT_COMMAND=bash_prompt_command 105 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOTFILES_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) 2 | OS := $(shell bin/is-supported bin/is-macos macos $(shell bin/is-supported bin/is-ubuntu ubuntu $(shell bin/is-supported bin/is-arch arch linux))) 3 | HOMEBREW_PREFIX := $(shell bin/is-supported bin/is-arm64 /opt/homebrew /usr/local) 4 | export N_PREFIX = $(HOME)/.n 5 | PATH := $(HOMEBREW_PREFIX)/bin:$(DOTFILES_DIR)/bin:$(N_PREFIX)/bin:$(PATH) 6 | SHELL := env PATH=$(PATH) /bin/bash 7 | SHELLS := /private/etc/shells 8 | BIN := $(HOMEBREW_PREFIX)/bin 9 | export XDG_CONFIG_HOME = $(HOME)/.config 10 | export STOW_DIR = $(DOTFILES_DIR) 11 | export ACCEPT_EULA=Y 12 | 13 | .PHONY: test 14 | 15 | all: $(OS) 16 | 17 | macos: sudo core-macos packages-macos link duti bun 18 | 19 | ubuntu: core-ubuntu link 20 | 21 | arch: core-arch packages-arch link 22 | 23 | core-macos: brew bash git npm 24 | 25 | core-ubuntu: 26 | apt-get update 27 | apt-get upgrade -y 28 | apt-get dist-upgrade -f 29 | 30 | stow-ubuntu: core-ubuntu 31 | is-executable stow || apt-get -y install stow 32 | 33 | core-arch: 34 | pacman -Syu --noconfirm 35 | 36 | stow-arch: core-arch 37 | is-executable stow || pacman -S --noconfirm stow 38 | 39 | stow-macos: brew 40 | is-executable stow || brew install stow 41 | 42 | sudo: 43 | ifndef GITHUB_ACTION 44 | sudo -v 45 | while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & 46 | endif 47 | 48 | link: stow-$(OS) 49 | for FILE in $$(\ls -A runcom); do if [ -f $(HOME)/$$FILE -a ! -h $(HOME)/$$FILE ]; then \ 50 | mv -v $(HOME)/$$FILE{,.bak}; fi; done 51 | mkdir -p "$(XDG_CONFIG_HOME)" 52 | stow -t "$(HOME)" runcom 53 | stow -t "$(XDG_CONFIG_HOME)" config 54 | mkdir -p $(HOME)/.local/runtime 55 | chmod 700 $(HOME)/.local/runtime 56 | 57 | unlink: stow-$(OS) 58 | stow --delete -t "$(HOME)" runcom 59 | stow --delete -t "$(XDG_CONFIG_HOME)" config 60 | for FILE in $$(\ls -A runcom); do if [ -f $(HOME)/$$FILE.bak ]; then \ 61 | mv -v $(HOME)/$$FILE.bak $(HOME)/$${FILE%%.bak}; fi; done 62 | 63 | brew: 64 | is-executable brew || curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash 65 | 66 | bash: brew 67 | ifdef GITHUB_ACTION 68 | if ! grep -q bash $(SHELLS); then \ 69 | brew install bash bash-completion@2 pcre && \ 70 | echo $(shell which bash) | sudo tee -a $(SHELLS) && \ 71 | sudo chsh -s $(shell which bash); \ 72 | fi 73 | else 74 | if ! grep -q bash $(SHELLS); then \ 75 | brew install bash bash-completion@2 pcre && \ 76 | echo $(shell which bash) | sudo tee -a $(SHELLS) && \ 77 | chsh -s $(shell which bash); \ 78 | fi 79 | endif 80 | 81 | git: brew 82 | brew install git git-extras 83 | 84 | npm: brew-packages 85 | n install lts 86 | 87 | packages-macos: brew-packages cask-apps node-packages rust-packages 88 | 89 | packages-arch: pacman-packages 90 | 91 | pacman-packages: 92 | pacman -S --noconfirm - < $(DOTFILES_DIR)/install/pacmanfile 93 | 94 | brew-packages: brew 95 | brew bundle --file=$(DOTFILES_DIR)/install/Brewfile || true 96 | 97 | cask-apps: brew 98 | brew bundle --file=$(DOTFILES_DIR)/install/Caskfile || true 99 | 100 | vscode-extensions: cask-apps 101 | for EXT in $$(cat install/Codefile); do code --install-extension $$EXT; done 102 | 103 | node-packages: npm 104 | $(N_PREFIX)/bin/npm install --force --location global $(shell cat install/npmfile) 105 | 106 | rust-packages: brew-packages 107 | cargo install $(shell cat install/Rustfile) 108 | 109 | duti: 110 | duti -v $(DOTFILES_DIR)/install/duti 111 | 112 | bun: 113 | curl -fsSL https://bun.sh/install | bash 114 | 115 | test: 116 | bats test 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # .files 2 | 3 | These are my dotfiles. Take anything you want, but at your own risk. 4 | 5 | Mainly targets macOS systems, but works on Ubuntu and Arch Linux as well. 6 | 7 | ## Highlights 8 | 9 | - Minimal efforts to install everything, using a [Makefile](./Makefile) 10 | - Mostly based around Homebrew, Caskroom and Node.js, latest Bash + GNU Utils 11 | - Fast and colored prompt 12 | - Updated macOS defaults 13 | - Well-organized and easy to customize 14 | - The installation and runcom setup is 15 | [tested weekly on real Ubuntu and macOS machines](https://github.com/webpro/dotfiles/actions) 16 | (Ventura/13, Sonomo/14, Sequoia/15) using [a GitHub Action](./.github/workflows/dotfiles-installation.yml) 17 | - Supports both Apple Silicon (M1) and Intel chips 18 | 19 | ## Packages Overview 20 | 21 | - [Homebrew](https://brew.sh) (packages: [Brewfile](./install/Brewfile)) 22 | - [homebrew-cask](https://github.com/Homebrew/homebrew-cask) (packages: [Caskfile](./install/Caskfile)) 23 | - [Node.js + npm LTS](https://nodejs.org/en/download/) (packages: [npmfile](./install/npmfile)) 24 | - Latest Git, Bash, Python, GNU coreutils, curl, Ruby 25 | - Editors: VS Code and nano (`EDITOR`, `VISUAL` and Git `core.editor`) 26 | 27 | ## Installation 28 | 29 | On a sparkling fresh installation of macOS: 30 | 31 | ```bash 32 | sudo softwareupdate -i -a 33 | xcode-select --install 34 | ``` 35 | 36 | The Xcode Command Line Tools includes `git` and `make` (not available on stock macOS). Now there are two options: 37 | 38 | 1. Install this repo with `curl` available: 39 | 40 | ```bash 41 | bash -c "`curl -fsSL https://raw.githubusercontent.com/webpro/dotfiles/master/remote-install.sh`" 42 | ``` 43 | 44 | This will clone or download this repo to `~/.dotfiles` (depending on the availability of `git`, `curl` or `wget`). 45 | 46 | 1. Alternatively, clone manually into the desired location: 47 | 48 | ```bash 49 | git clone https://github.com/webpro/dotfiles.git ~/.dotfiles 50 | ``` 51 | 52 | 2. Use the [Makefile](./Makefile) to install the [packages listed above](#packages-overview), and symlink 53 | [runcom](./runcom) and [config](./config) files (using [stow](https://www.gnu.org/software/stow/)): 54 | 55 | ```bash 56 | cd ~/.dotfiles 57 | make 58 | ``` 59 | 60 | Running `make` with the Makefile is idempotent. The installation process in the Makefile is tested on every push and every week in this 61 | [GitHub Action](https://github.com/webpro/dotfiles/actions). Please file an issue in this repo if there are errors. 62 | 63 | ## Post-Installation 64 | 65 | 1. Set your Git credentials: 66 | 67 | ```sh 68 | git config --global user.name "your name" 69 | git config --global user.email "your@email.com" 70 | git config --global github.user "your-github-username" 71 | ``` 72 | 73 | 2. Set macOS [Dock items](./macos/dock.sh) and [system defaults](./macos/defaults.sh): 74 | 75 | ```sh 76 | dot dock 77 | dot macos 78 | ``` 79 | 80 | 3. Populate this file with tokens (example: `export GITHUB_TOKEN=abc`): 81 | 82 | ```sh 83 | touch ~/.dotfiles/system/.exports 84 | ``` 85 | 86 | ## The `dot` command 87 | 88 | ``` 89 | $ dot help 90 | Usage: dot 91 | 92 | Commands: 93 | clean Clean up caches (brew, cargo, gem, pip) 94 | dock Apply macOS Dock settings 95 | edit Open dotfiles in IDE ($VISUAL) and Git GUI ($VISUAL_GIT) 96 | help This help message 97 | macos Apply macOS system defaults 98 | test Run tests 99 | update Update packages and pkg managers (brew, casks, cargo, pip3, npm, gems, macOS) 100 | ``` 101 | 102 | ## Customize 103 | 104 | To customize the dotfiles to your likings, fork it and [be the king of your castle!](https://www.webpro.nl/articles/getting-started-with-dotfiles) 105 | 106 | ## Credits 107 | 108 | Many thanks to the [dotfiles community](https://dotfiles.github.io). 109 | -------------------------------------------------------------------------------- /system/.dir_colors: -------------------------------------------------------------------------------- 1 | # Exact Solarized color theme for the color GNU ls utility. 2 | # Designed for dircolors (GNU coreutils) 5.97 3 | # 4 | # This simple theme was simultaneously designed for these terminal color schemes: 5 | # - Solarized dark (best) 6 | # - Solarized light (best) 7 | # - default dark 8 | # - default light 9 | # 10 | # How the colors were selected: 11 | # - Terminal emulators often have an option typically enabled by default that makes 12 | # bold a different color. It is important to leave this option enabled so that 13 | # you can access the entire 16-color Solarized palette, and not just 8 colors. 14 | # - We favor universality over a greater number of colors. So we limit the number 15 | # of colors so that this theme will work out of the box in all terminals, 16 | # Solarized or not, dark or light. 17 | # - We choose to have the following category of files: 18 | # NORMAL & FILE, DIR, LINK, EXEC and 19 | # editable text including source, unimportant text, binary docs & multimedia source 20 | # files, viewable multimedia, archived/compressed, and unimportant non-text 21 | # - For uniqueness, we stay away from the Solarized foreground colors are -- either 22 | # base00 (brightyellow) or base0 (brighblue). However, they can be used if 23 | # you know what the bg/fg colors of your terminal are, in order to optimize the display. 24 | # - 3 different options are provided: universal, solarized dark, and solarized light. 25 | # The only difference between the universal scheme and one that's optimized for 26 | # dark/light is the color of "unimportant" files, which should blend more with the 27 | # background 28 | # - We note that blue is the hardest color to see on dark bg and yellow is the hardest 29 | # color to see on light bg (with blue being particularly bad). So we choose yellow 30 | # for multimedia files which are usually accessed in a GUI folder browser anyway. 31 | # And blue is kept for custom use of this scheme's user. 32 | # - See table below to see the assignments. 33 | 34 | 35 | # Insatllation instructions: 36 | # This file goes in the /etc directory, and must be world readable. 37 | # You can copy this file to .dir_colors in your $HOME directory to override 38 | # the system defaults. 39 | 40 | # COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not 41 | # pipes. 'all' adds color characters to all output. 'none' shuts colorization 42 | # off. 43 | COLOR tty 44 | 45 | # Below, there should be one TERM entry for each termtype that is colorizable 46 | TERM ansi 47 | TERM color_xterm 48 | TERM color-xterm 49 | TERM con132x25 50 | TERM con132x30 51 | TERM con132x43 52 | TERM con132x60 53 | TERM con80x25 54 | TERM con80x28 55 | TERM con80x30 56 | TERM con80x43 57 | TERM con80x50 58 | TERM con80x60 59 | TERM cons25 60 | TERM console 61 | TERM cygwin 62 | TERM dtterm 63 | TERM Eterm 64 | TERM eterm-color 65 | TERM gnome 66 | TERM gnome-256color 67 | TERM jfbterm 68 | TERM konsole 69 | TERM kterm 70 | TERM linux 71 | TERM linux-c 72 | TERM mach-color 73 | TERM mlterm 74 | TERM nxterm 75 | TERM putty 76 | TERM rxvt 77 | TERM rxvt-256color 78 | TERM rxvt-cygwin 79 | TERM rxvt-cygwin-native 80 | TERM rxvt-unicode 81 | TERM rxvt-unicode256 82 | TERM rxvt-unicode-256color 83 | TERM screen 84 | TERM screen-256color 85 | TERM screen-256color-bce 86 | TERM screen-bce 87 | TERM screen.linux 88 | TERM screen-w 89 | TERM vt100 90 | TERM xterm 91 | TERM xterm-16color 92 | TERM xterm-256color 93 | TERM xterm-88color 94 | TERM xterm-color 95 | TERM xterm-debian 96 | 97 | # EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) 98 | EIGHTBIT 1 99 | 100 | ############################################################################# 101 | # Below are the color init strings for the basic file types. A color init 102 | # string consists of one or more of the following numeric codes: 103 | # 104 | # Attribute codes: 105 | # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed 106 | # Text color codes: 107 | # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white 108 | # Background color codes: 109 | # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white 110 | # 111 | # NOTES: 112 | # - See http://www.oreilly.com/catalog/wdnut/excerpt/color_names.html 113 | # - Color combinations 114 | # ANSI Color code Solarized Notes Universal SolDark SolLight 115 | # ~~~~~~~~~~~~~~~ ~~~~~~~~~ ~~~~~ ~~~~~~~~~ ~~~~~~~ ~~~~~~~~ 116 | # 00 none NORMAL, FILE 117 | # 30 black base02 118 | # 01;30 bright black base03 bg of SolDark 119 | # 31 red red docs & mm src 120 | # 01;31 bright red orange EXEC 121 | # 32 green green editable text 122 | # 01;32 bright green base01 unimportant text 123 | # 33 yellow yellow unclear in light bg multimedia 124 | # 01;33 bright yellow base00 fg of SolLight unimportant non-text 125 | # 34 blue blue unclear in dark bg user customized 126 | # 01;34 bright blue base0 fg in SolDark unimportant text 127 | # 35 magenta magenta LINK 128 | # 01;35 bright magenta violet archive/compressed 129 | # 36 cyan cyan DIR 130 | # 01;36 bright cyan base1 unimportant non-text 131 | # 37 white base2 132 | # 01;37 bright white base3 bg in SolLight 133 | # 05;37;41 unclear in Putty dark 134 | 135 | 136 | ### By file type 137 | 138 | # global default 139 | NORMAL 00 140 | # normal file 141 | FILE 00 142 | # directory 143 | DIR 36 144 | # symbolic link 145 | LINK 35 146 | 147 | # pipe, socket, block device, character device (blue bg) 148 | FIFO 30;44 149 | SOCK 35;44 150 | DOOR 35;44 # Solaris 2.5 and later 151 | BLK 33;44 152 | CHR 37;44 153 | 154 | 155 | ############################################################################# 156 | ### By file attributes 157 | 158 | # Orphaned symlinks (blinking white on red) 159 | # Blink may or may not work (works on iTerm dark or light, and Putty dark) 160 | ORPHAN 05;37;41 161 | # ... and the files that orphaned symlinks point to (blinking white on red) 162 | MISSING 05;37;41 163 | 164 | # files with execute permission 165 | EXEC 01;31 # Unix 166 | .cmd 01;31 # Win 167 | .exe 01;31 # Win 168 | .com 01;31 # Win 169 | .bat 01;31 # Win 170 | .reg 01;31 # Win 171 | .app 01;31 # OSX 172 | 173 | ############################################################################# 174 | ### By extension 175 | 176 | # List any file extensions like '.gz' or '.tar' that you would like ls 177 | # to colorize below. Put the extension, a space, and the color init string. 178 | # (and any comments you want to add after a '#') 179 | 180 | ### Text formats 181 | 182 | # Text that we can edit with a regular editor 183 | .txt 32 184 | .org 32 185 | .md 32 186 | .mkd 32 187 | .pdc 32 188 | 189 | # Source text 190 | .h 32 191 | .c 32 192 | .C 32 193 | .cc 32 194 | .cxx 32 195 | .objc 32 196 | .sh 32 197 | .csh 32 198 | .zsh 32 199 | .el 32 200 | .vim 32 201 | .java 32 202 | .pl 32 203 | .pm 32 204 | .py 32 205 | .rb 32 206 | .hs 32 207 | .php 32 208 | .htm 32 209 | .html 32 210 | .shtml 32 211 | .xml 32 212 | .rdf 32 213 | .css 32 214 | .js 32 215 | .man 32 216 | .0 32 217 | .1 32 218 | .2 32 219 | .3 32 220 | .4 32 221 | .5 32 222 | .6 32 223 | .7 32 224 | .8 32 225 | .9 32 226 | .l 32 227 | .n 32 228 | .p 32 229 | .pod 32 230 | .tex 32 231 | 232 | ### Multimedia formats 233 | 234 | # Image 235 | .bmp 33 236 | .cgm 33 237 | .dl 33 238 | .dvi 33 239 | .emf 33 240 | .eps 33 241 | .gif 33 242 | .jpeg 33 243 | .jpg 33 244 | .JPG 33 245 | .mng 33 246 | .pbm 33 247 | .pcx 33 248 | .pdf 33 249 | .pgm 33 250 | .png 33 251 | .ppm 33 252 | .pps 33 253 | .ppsx 33 254 | .ps 33 255 | .svg 33 256 | .svgz 33 257 | .tga 33 258 | .tif 33 259 | .tiff 33 260 | .xbm 33 261 | .xcf 33 262 | .xpm 33 263 | .xwd 33 264 | .xwd 33 265 | .yuv 33 266 | 267 | # Audio 268 | .aac 33 269 | .au 33 270 | .flac 33 271 | .mid 33 272 | .midi 33 273 | .mka 33 274 | .mp3 33 275 | .mpa 33 276 | .mpeg 33 277 | .mpg 33 278 | .ogg 33 279 | .ra 33 280 | .wav 33 281 | 282 | # Video 283 | .anx 33 284 | .asf 33 285 | .avi 33 286 | .axv 33 287 | .flc 33 288 | .fli 33 289 | .flv 33 290 | .gl 33 291 | .m2v 33 292 | .m4v 33 293 | .mkv 33 294 | .mov 33 295 | .mp4 33 296 | .mp4v 33 297 | .mpeg 33 298 | .mpg 33 299 | .nuv 33 300 | .ogm 33 301 | .ogv 33 302 | .ogx 33 303 | .qt 33 304 | .rm 33 305 | .rmvb 33 306 | .swf 33 307 | .vob 33 308 | .wmv 33 309 | 310 | ### Misc 311 | 312 | # Binary document formats and multimedia source 313 | .doc 31 314 | .docx 31 315 | .rtf 31 316 | .dot 31 317 | .dotx 31 318 | .xls 31 319 | .xlsx 31 320 | .ppt 31 321 | .pptx 31 322 | .fla 31 323 | .psd 31 324 | 325 | # Archives, compressed 326 | .7z 1;35 327 | .apk 1;35 328 | .arj 1;35 329 | .bin 1;35 330 | .bz 1;35 331 | .bz2 1;35 332 | .cab 1;35 # Win 333 | .deb 1;35 334 | .dmg 1;35 # OSX 335 | .gem 1;35 336 | .gz 1;35 337 | .iso 1;35 338 | .jar 1;35 339 | .msi 1;35 # Win 340 | .rar 1;35 341 | .rpm 1;35 342 | .tar 1;35 343 | .tbz 1;35 344 | .tbz2 1;35 345 | .tgz 1;35 346 | .tx 1;35 347 | .war 1;35 348 | .xpi 1;35 349 | .xz 1;35 350 | .z 1;35 351 | .Z 1;35 352 | .zip 1;35 353 | 354 | # For testing 355 | .ANSI-30-black 30 356 | .ANSI-01;30-brblack 01;30 357 | .ANSI-31-red 31 358 | .ANSI-01;31-brred 01;31 359 | .ANSI-32-green 32 360 | .ANSI-01;32-brgreen 01;32 361 | .ANSI-33-yellow 33 362 | .ANSI-01;33-bryellow 01;33 363 | .ANSI-34-blue 34 364 | .ANSI-01;34-brblue 01;34 365 | .ANSI-35-magenta 35 366 | .ANSI-01;35-brmagenta 01;35 367 | .ANSI-36-cyan 36 368 | .ANSI-01;36-brcyan 01;36 369 | .ANSI-37-white 37 370 | .ANSI-01;37-brwhite 01;37 371 | 372 | ############################################################################# 373 | # Your customizations 374 | 375 | # Unimportant text files 376 | # For universal scheme, use brightgreen 01;32 377 | # For optimal on light bg (but too prominent on dark bg), use white 01;34 378 | .log 01;32 379 | *~ 01;32 380 | *# 01;32 381 | #.log 01;34 382 | #*~ 01;34 383 | #*# 01;34 384 | 385 | # Unimportant non-text files 386 | # For universal scheme, use brightcyan 01;36 387 | # For optimal on dark bg (but too prominent on light bg), change to 01;33 388 | .bak 01;36 389 | .BAK 01;36 390 | .old 01;36 391 | .OLD 01;36 392 | .org_archive 01;36 393 | .off 01;36 394 | .OFF 01;36 395 | .dist 01;36 396 | .DIST 01;36 397 | .orig 01;36 398 | .ORIG 01;36 399 | .swp 01;36 400 | .swo 01;36 401 | *,v 01;36 402 | #.bak 01;33 403 | #.BAK 01;33 404 | #.old 01;33 405 | #.OLD 01;33 406 | #.org_archive 01;33 407 | #.off 01;33 408 | #.OFF 01;33 409 | #.dist 01;33 410 | #.DIST 01;33 411 | #.orig 01;33 412 | #.ORIG 01;33 413 | #.swp 01;33 414 | #.swo 01;33 415 | #*,v 01;33 416 | 417 | # The brightmagenta (Solarized: purple) color is free for you to use for your 418 | # custom file type 419 | .gpg 34 420 | .gpg 34 421 | .pgp 34 422 | .asc 34 423 | .3des 34 424 | .aes 34 425 | .enc 34 426 | -------------------------------------------------------------------------------- /macos/defaults.sh: -------------------------------------------------------------------------------- 1 | COMPUTER_NAME="Neo" 2 | LANGUAGES=(en nl) 3 | LOCALE="en_US@currency=EUR" 4 | MEASUREMENT_UNITS="Centimeters" 5 | SCREENSHOTS_FOLDER="${HOME}/Screenshots" 6 | 7 | # Topics 8 | # 9 | # - Computer & Host name 10 | # - Localization 11 | # - System 12 | # - Keyboard & Input 13 | # - Trackpad, mouse, Bluetooth accessories 14 | # - Screen 15 | # - Finder 16 | # - Dock 17 | # - Mail 18 | # - Calendar 19 | # - Terminal 20 | # - Activity Monitor 21 | # - Software Updates 22 | 23 | osascript -e 'tell application "System Preferences" to quit' 24 | 25 | # Ask for the administrator password upfront 26 | sudo -v 27 | 28 | # Keep-alive: update existing `sudo` time stamp until this script has finished 29 | while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & 30 | 31 | ############################################################################### 32 | # Computer & Host name # 33 | ############################################################################### 34 | 35 | # Set computer name (as done via System Preferences → Sharing) 36 | sudo scutil --set ComputerName "$COMPUTER_NAME" 37 | sudo scutil --set HostName "$COMPUTER_NAME" 38 | sudo scutil --set LocalHostName "$COMPUTER_NAME" 39 | sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName -string "$COMPUTER_NAME" 40 | 41 | ############################################################################### 42 | # Localization # 43 | ############################################################################### 44 | 45 | # Set language and text formats 46 | defaults write NSGlobalDomain AppleLanguages -array ${LANGUAGES[@]} 47 | defaults write NSGlobalDomain AppleLocale -string "$LOCALE" 48 | defaults write NSGlobalDomain AppleMeasurementUnits -string "$MEASUREMENT_UNITS" 49 | defaults write NSGlobalDomain AppleMetricUnits -bool true 50 | 51 | # Using systemsetup might give Error:-99, can be ignored (commands still work) 52 | # systemsetup manpage: https://ss64.com/osx/systemsetup.html 53 | 54 | # Set the time zone 55 | sudo defaults write /Library/Preferences/com.apple.timezone.auto Active -bool YES 56 | sudo systemsetup -setusingnetworktime on 57 | 58 | ############################################################################### 59 | # System # 60 | ############################################################################### 61 | 62 | # Restart automatically if the computer freezes (Error:-99 can be ignored) 63 | sudo systemsetup -setrestartfreeze on 2> /dev/null 64 | 65 | # Set standby delay to 24 hours (default is 1 hour) 66 | sudo pmset -a standbydelay 86400 67 | 68 | # Disable Sudden Motion Sensor 69 | sudo pmset -a sms 0 70 | 71 | # Disable audio feedback when volume is changed 72 | defaults write com.apple.sound.beep.feedback -bool false 73 | 74 | # Disable the sound effects on boot 75 | sudo nvram SystemAudioVolume=" " 76 | sudo nvram StartupMute=%01 77 | 78 | # Menu bar: show battery percentage 79 | defaults write com.apple.menuextra.battery ShowPercent YES 80 | 81 | # Disable opening and closing window animations 82 | defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool false 83 | 84 | # Increase window resize speed for Cocoa applications 85 | defaults write NSGlobalDomain NSWindowResizeTime -float 0.001 86 | 87 | # Expand save panel by default 88 | defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true 89 | defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true 90 | 91 | # Expand print panel by default 92 | defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true 93 | defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true 94 | 95 | # Save to disk (not to iCloud) by default 96 | defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false 97 | 98 | # Automatically quit printer app once the print jobs complete 99 | defaults write com.apple.print.PrintingPrefs "Quit When Finished" -bool true 100 | 101 | # Disable the “Are you sure you want to open this application?” dialog 102 | defaults write com.apple.LaunchServices LSQuarantine -bool false 103 | 104 | # Disable Resume system-wide 105 | defaults write com.apple.systempreferences NSQuitAlwaysKeepsWindows -bool false 106 | 107 | # Disable the crash reporter 108 | defaults write com.apple.CrashReporter DialogType -string "none" 109 | 110 | # Disable Notification Center and remove the menu bar icon 111 | launchctl unload -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist 2> /dev/null 112 | 113 | ############################################################################### 114 | # Keyboard & Input # 115 | ############################################################################### 116 | 117 | # Disable smart quotes and dashes as they’re annoying when typing code 118 | defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false 119 | defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false 120 | 121 | # Enable full keyboard access for all controls 122 | # (e.g. enable Tab in modal dialogs) 123 | defaults write NSGlobalDomain AppleKeyboardUIMode -int 3 124 | 125 | # Disable press-and-hold for keys in favor of key repeat 126 | defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false 127 | 128 | # Set a blazingly fast keyboard repeat rate 129 | defaults write NSGlobalDomain KeyRepeat -int 1 130 | defaults write NSGlobalDomain InitialKeyRepeat -int 15 131 | 132 | # Automatically illuminate built-in MacBook keyboard in low light 133 | defaults write com.apple.BezelServices kDim -bool true 134 | 135 | # Turn off keyboard illumination when computer is not used for 5 minutes 136 | defaults write com.apple.BezelServices kDimTime -int 300 137 | 138 | # Disable auto-correct 139 | defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false 140 | 141 | ############################################################################### 142 | # Trackpad, mouse, Bluetooth accessories # 143 | ############################################################################### 144 | 145 | # Trackpad: enable tap to click for this user and for the login screen 146 | defaults write com.apple.AppleMultitouchTrackpad Clicking -bool true 147 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true 148 | defaults -currentHost write NSGlobalDomain com.apple.mouse.tapBehavior -int 1 149 | defaults write NSGlobalDomain com.apple.mouse.tapBehavior -int 1 150 | 151 | # Trackpad: map bottom right corner to right-click 152 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadCornerSecondaryClick -int 2 153 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadRightClick -bool true 154 | defaults -currentHost write NSGlobalDomain com.apple.trackpad.trackpadCornerClickBehavior -int 1 155 | defaults -currentHost write NSGlobalDomain com.apple.trackpad.enableSecondaryClick -bool true 156 | 157 | # Trackpad: swipe between pages with three fingers 158 | defaults write NSGlobalDomain AppleEnableSwipeNavigateWithScrolls -bool true 159 | defaults -currentHost write NSGlobalDomain com.apple.trackpad.threeFingerHorizSwipeGesture -int 1 160 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerHorizSwipeGesture -int 1 161 | 162 | # Increase sound quality for Bluetooth headphones/headsets 163 | defaults write com.apple.BluetoothAudioAgent "Apple Bitpool Min (editable)" -int 40 164 | 165 | ############################################################################### 166 | # Screen # 167 | ############################################################################### 168 | 169 | # Require password immediately after sleep or screen saver begins 170 | defaults write com.apple.screensaver askForPassword -int 1 171 | defaults write com.apple.screensaver askForPasswordDelay -int 0 172 | 173 | # Save screenshots to the ~/Screenshots folder 174 | mkdir -p "${SCREENSHOTS_FOLDER}" 175 | defaults write com.apple.screencapture location -string "${SCREENSHOTS_FOLDER}" 176 | 177 | # Save screenshots in PNG format (other options: BMP, GIF, JPG, PDF, TIFF) 178 | defaults write com.apple.screencapture type -string "png" 179 | 180 | # Disable shadow in screenshots 181 | defaults write com.apple.screencapture disable-shadow -bool true 182 | 183 | # Enable subpixel font rendering on non-Apple LCDs 184 | defaults write NSGlobalDomain AppleFontSmoothing -int 2 185 | 186 | ############################################################################### 187 | # Finder # 188 | ############################################################################### 189 | 190 | # Finder: allow quitting via ⌘ + Q; doing so will also hide desktop icons 191 | defaults write com.apple.finder QuitMenuItem -bool true 192 | 193 | # Finder: disable window animations and Get Info animations 194 | defaults write com.apple.finder DisableAllAnimations -bool true 195 | 196 | # Finder: show hidden files by default 197 | defaults write com.apple.finder AppleShowAllFiles -bool true 198 | 199 | # Finder: show all filename extensions 200 | defaults write NSGlobalDomain AppleShowAllExtensions -bool true 201 | 202 | # Finder: show status bar 203 | defaults write com.apple.finder ShowStatusBar -bool true 204 | 205 | # Finder: show path bar 206 | defaults write com.apple.finder ShowPathbar -bool true 207 | 208 | # Finder: allow text selection in Quick Look 209 | defaults write com.apple.finder QLEnableTextSelection -bool true 210 | 211 | # Display full POSIX path as Finder window title 212 | defaults write com.apple.finder _FXShowPosixPathInTitle -bool true 213 | 214 | # Keep folders on top when sorting by name 215 | defaults write com.apple.finder _FXSortFoldersFirst -bool true 216 | 217 | # When performing a search, search the current folder by default 218 | defaults write com.apple.finder FXDefaultSearchScope -string "SCcf" 219 | 220 | # Disable the warning when changing a file extension 221 | defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false 222 | 223 | # Avoid creating .DS_Store files on network or USB volumes 224 | defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true 225 | defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true 226 | 227 | # Disable disk image verification 228 | defaults write com.apple.frameworks.diskimages skip-verify -bool true 229 | defaults write com.apple.frameworks.diskimages skip-verify-locked -bool true 230 | defaults write com.apple.frameworks.diskimages skip-verify-remote -bool true 231 | 232 | # Use AirDrop over every interface. 233 | defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool true 234 | 235 | # Always open everything in Finder's list view. 236 | # Use list view in all Finder windows by default 237 | # Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv` 238 | defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv" 239 | 240 | # Disable the warning before emptying the Trash 241 | defaults write com.apple.finder WarnOnEmptyTrash -bool false 242 | 243 | # Expand the following File Info panes: 244 | # “General”, “Open with”, and “Sharing & Permissions” 245 | defaults write com.apple.finder FXInfoPanesExpanded -dict General -bool true OpenWith -bool true Privileges -bool true 246 | 247 | ############################################################################### 248 | # Dock # 249 | ############################################################################### 250 | 251 | # Show indicator lights for open applications in the Dock 252 | defaults write com.apple.dock show-process-indicators -bool true 253 | 254 | # Don’t animate opening applications from the Dock 255 | defaults write com.apple.dock launchanim -bool false 256 | 257 | # Automatically hide and show the Dock 258 | defaults write com.apple.dock autohide -bool true 259 | 260 | # Make Dock icons of hidden applications translucent 261 | defaults write com.apple.dock showhidden -bool true 262 | 263 | # No bouncing icons 264 | defaults write com.apple.dock no-bouncing -bool true 265 | 266 | # Disable hot corners 267 | defaults write com.apple.dock wvous-tl-corner -int 0 268 | defaults write com.apple.dock wvous-tr-corner -int 0 269 | defaults write com.apple.dock wvous-bl-corner -int 0 270 | defaults write com.apple.dock wvous-br-corner -int 0 271 | 272 | # Don't show recently used applications in the Dock 273 | defaults write com.Apple.Dock show-recents -bool false 274 | 275 | ############################################################################### 276 | # Mail # 277 | ############################################################################### 278 | 279 | # Display emails in threaded mode 280 | defaults write com.apple.mail DraftsViewerAttributes -dict-add "DisplayInThreadedMode" -string "yes" 281 | 282 | # Disable send and reply animations in Mail.app 283 | defaults write com.apple.mail DisableReplyAnimations -bool true 284 | defaults write com.apple.mail DisableSendAnimations -bool true 285 | 286 | # Copy email addresses as `foo@example.com` instead of `Foo Bar ` in Mail.app 287 | defaults write com.apple.mail AddressesIncludeNameOnPasteboard -bool false 288 | 289 | # Disable inline attachments (just show the icons) 290 | defaults write com.apple.mail DisableInlineAttachmentViewing -bool true 291 | 292 | # Disable automatic spell checking 293 | defaults write com.apple.mail SpellCheckingBehavior -string "NoSpellCheckingEnabled" 294 | 295 | # Disable sound for incoming mail 296 | defaults write com.apple.mail MailSound -string "" 297 | 298 | # Disable sound for other mail actions 299 | defaults write com.apple.mail PlayMailSounds -bool false 300 | 301 | # Mark all messages as read when opening a conversation 302 | defaults write com.apple.mail ConversationViewMarkAllAsRead -bool true 303 | 304 | # Disable includings results from trash in search 305 | defaults write com.apple.mail IndexTrash -bool false 306 | 307 | # Automatically check for new message (not every 5 minutes) 308 | defaults write com.apple.mail AutoFetch -bool true 309 | defaults write com.apple.mail PollTime -string "-1" 310 | 311 | # Show most recent message at the top in conversations 312 | defaults write com.apple.mail ConversationViewSortDescending -bool true 313 | 314 | ############################################################################### 315 | # Calendar # 316 | ############################################################################### 317 | 318 | # Show week numbers (10.8 only) 319 | defaults write com.apple.iCal "Show Week Numbers" -bool true 320 | 321 | # Week starts on monday 322 | defaults write com.apple.iCal "first day of week" -int 1 323 | 324 | ############################################################################### 325 | # Terminal # 326 | ############################################################################### 327 | 328 | # Only use UTF-8 in Terminal.app 329 | defaults write com.apple.terminal StringEncodings -array 4 330 | 331 | # Appearance 332 | defaults write com.apple.terminal "Default Window Settings" -string "Pro" 333 | defaults write com.apple.terminal "Startup Window Settings" -string "Pro" 334 | defaults write com.apple.Terminal ShowLineMarks -int 0 335 | 336 | ############################################################################### 337 | # Activity Monitor # 338 | ############################################################################### 339 | 340 | # Show the main window when launching Activity Monitor 341 | defaults write com.apple.ActivityMonitor OpenMainWindow -bool true 342 | 343 | # Visualize CPU usage in the Activity Monitor Dock icon 344 | defaults write com.apple.ActivityMonitor IconType -int 5 345 | 346 | # Show all processes in Activity Monitor 347 | defaults write com.apple.ActivityMonitor ShowCategory -int 0 348 | 349 | # Sort Activity Monitor results by CPU usage 350 | defaults write com.apple.ActivityMonitor SortColumn -string "CPUUsage" 351 | defaults write com.apple.ActivityMonitor SortDirection -int 0 352 | 353 | ############################################################################### 354 | # Software Updates # 355 | ############################################################################### 356 | 357 | # Enable the automatic update check 358 | defaults write com.apple.SoftwareUpdate AutomaticCheckEnabled -bool true 359 | 360 | # Check for software updates weekly (`dot update` includes software updates) 361 | defaults write com.apple.SoftwareUpdate ScheduleFrequency -string 7 362 | 363 | # Download newly available updates in background 364 | defaults write com.apple.SoftwareUpdate AutomaticDownload -bool true 365 | 366 | # Install System data files & security updates 367 | defaults write com.apple.SoftwareUpdate CriticalUpdateInstall -bool true 368 | 369 | # Turn on app auto-update 370 | defaults write com.apple.commerce AutoUpdate -bool true 371 | 372 | # Allow the App Store to reboot machine on macOS updates 373 | defaults write com.apple.commerce AutoUpdateRestartRequired -bool true 374 | 375 | ############################################################################### 376 | # Kill affected applications # 377 | ############################################################################### 378 | 379 | for app in "Address Book" "Calendar" "Contacts" "Dock" "Finder" "Mail" "Safari" "SystemUIServer" "iCal"; do 380 | killall "${app}" &> /dev/null 381 | done 382 | --------------------------------------------------------------------------------