Skip to content

weikinhuang/dotfiles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

weikinhuang's dotfiles

My $SHELL, mostly bash, works everywhere, *nix, osx, wsl.

Installation

The bootstrap script will create symlinks in the home directory to the proper files. The script will also create *.bak files for backups of existing files.

Install dotfiles with auto bootstrap

This will by default install dotfiles in the home directory with all options enabled

curl https://raw.githubusercontent.com/weikinhuang/dotfiles/master/bootstrap.sh | bash

# Additional arguments can be passed to the bootstrap script
curl https://raw.github...master/bootstrap.sh | bash -s -- [args]

Install dotfiles with Git

You can clone the repository wherever you want, the home (~/) directory is recommended.

When the git repo is updated, the files will be automatically updated when the session is restarted.

# args can be passed to the bootstrap script
git clone https://github.com/weikinhuang/dotfiles.git ~/.dotfiles && ~/.dotfiles/bootstrap.sh

To update later on, just run git pull in ~/.dotfiles.

Install dotfiles without Git

To install or update without git installed, run:

cd; mkdir -p ~/.dotfiles \
  && curl -#L https://github.com/weikinhuang/dotfiles/tarball/master \
    | tar -C ~/.dotfiles -xzv --strip-components 1 \
  && ~/.dotfiles/bootstrap.sh

bootstrap.sh args

Arg Description
--dir PATH Change the install directory
--no-git Skip setting up .gitconfig
--no-vim Skip setting up .vimrc and .vim

See REFERENCE.md for all added commands, overrides, and changes to built-ins.

High level overview

  • cd -- list last 10 traversed directories
  • chpwd, precmd, and preexec hooks with similar behavior to Zsh
  • sudo works on aliases
  • rm cp mv are always inteactive -i (use -f to override)
  • ls and grep always has color (use --color=never to override)
  • which command expands full path when possible
  • less does not clear the screen upon exit and process colors (with options -XR)
  • diff uses git's diff command with color when possible
  • pbcopy and pbpaste for cross-platform copy/paste from cli, and optionally over ssh
  • open for cross-platform open in native application
  • chattr, mklink, is-elevated-session, winstart, winsudo WSL tools

See PROMPT.md for configuration options.

Prompt example

Configuration Options

To use these variables, export them to ~/.bash_local.

# EXAMPLE
export DOT_AUTOLOAD_SSH_AGENT=1
exported ENV var Default Description
DOT_AUTOLOAD_SSH_AGENT UNSET Automatically start up ssh-agent when starting a new shell, or reuse any existing agent instances
DOT_BASH_RESOLVE_PATHS UNSET Set bash option set -o physical to not resolve symlink paths
DOT_DISABLE_PREEXEC UNSET Disables loading bash-preexec.sh functionality. This is needed for some bash prompt functionality.
DOT_DISABLE_PS1 UNSET Disables the custom bash prompt
DOT_INCLUDE_BREW_PATH UNSET Use to homebrew utilities without the g prefix (OSX)
DOT_INCLUDE_BUILTIN_PLUGINS UNSET Loads files in dotfiles/plugins. This is needed for some bash prompt functionality.
DOT_SOLARIZED_DARK UNSET Use to tell common commands to use solarized dark (ex. LS_COLORS, vim) colors
DOT_SOLARIZED_LIGHT UNSET Use to tell common commands to use solarized light (ex. LS_COLORS, vim) colors

Custom hook points

~/.bash_local

If ~/.bash_local exists, it will be sourced before the built-ins are sourced. Env vars, configuration vars, and hooks can be placed in this file.

~/.bash_local.d/*.sh

All files ending with .sh located in ~/.bash_local.d will be loaded right after ~/.bash_local, this is a good place to put include scripts that setup additional environments in separate files.

.gitconfig.local

If a file ~/.gitconfig.local exists, it will be sourced in addition to the built in git settings. Configurations in this file will be set with the highest priority.

Plugins

Plugins are scripts that are loaded near the end of the dotfiles initialization process. They usually contain hooks, setup, or configuration for external programs.

See the plugins/ directory for the built-in examples.

Plugins are also loaded from ~/.bash_local.d/ with any file ending in .plugin. Sorting is preserved via the combination of both directories.

Example plugin for direnv:

# check if direnv exists
if ! command -v direnv &>/dev/null; then
  return
fi
# load direnv program hook
source <(direnv hook bash 2>/dev/null)

Specific plugins can be disabled with an environment variable: DOT_PLUGIN_DISABLE_${PLUGIN_FILE_NAME}.

Example disable direnv hook:

export DOT_PLUGIN_DISABLE_direnv=1

Hooks

Hooks are available before and after each part of the dotfiles repo is loaded. This allows for customization between steps or overrides at point in time loading. They should be declared in ~/.bash_local or ~/.bash_local.d/*.sh so that they are available by the time the dotfiles are loaded.

Hook points are available before and after the following steps:

  • aliases
  • completion
  • env
  • exports
  • extra
  • functions
  • plugins
  • prompt

They can be declared as either a single function dotfiles_hook_${HOOK}_{pre,post} or pushed into the arrays dotfiles_hook_${HOOK}_{pre,post}_functions.

Example

# add a hook to run before the "functions" segment is loaded
function dotfiles_hook_functions_pre() {
    echo "I'm loading before functions"
    export FOO=123
}

# add a hook to run after the "alias" segment is loaded
function foobar() {
    echo "I'm loading after aliases"
    alias curl-help="curl --help"
}
# append to array
dotfiles_hook_alias_post_functions+=(foobar)

Setup and configuration of Window's WSL is documented in utils/wsl/README.md.

Development

You can try out this repo in docker easily to test your plugins or hooks.

$ docker run -it --rm -v "$(pwd):/root/.dotfiles:ro" -v "$HOME/.bash_local:/root/.bash_local:ro" -v "$HOME/.bash_local.d:/root/.bash_local.d:ro" -v "$(pwd)/dev/docker-entrypoint.sh:/docker-entrypoint.sh:ro" --entrypoint /docker-entrypoint.sh bash:latest bash
# OR with overrides set locally in the dotfiles repo
mkdir -p bash_local_d_sample
touch bash_local_d_sample/bash_local
$ docker run -it --rm -v "$(pwd):/root/.dotfiles:ro" -v "$(pwd)/bash_local_d_sample/bash_local:/root/.bash_local:ro" -v "$(pwd)/bash_local_d_sample:/root/.bash_local.d:ro" -v "$(pwd)/dev/docker-entrypoint.sh:/docker-entrypoint.sh:ro" -v "$(pwd)/bash_local_d_sample/.bash_history:/root/.bash_history" --entrypoint /docker-entrypoint.sh bash:latest bash

# in the docker shell
$ (cd ~ && .dotfiles/bootstrap.sh)
# install any dependencies you might need, ex.
$ apk add --no-cache coreutils curl git tar nodejs

# start a new shell with the dotfiles loaded, to reload, exit this shell and run this command again
$ env -i PS1=1 TERM="$TERM" PATH="$PATH" HOME="$HOME" SHELL="$SHELL" bash -l
$ CTRL+d
$ env -i PS1=1 TERM="$TERM" PATH="$PATH" HOME="$HOME" SHELL="$SHELL" bash -l
...

shellcheck and shfmt

shellcheck and shfmt are used to ensure consistency of the scripts in this repo. Files in /external are ignored, since they are external scripts.

# shellcheck
( git ls-files -z | xargs -0 grep -l 'shellcheck shell=\|^#!.\+sh'; git ls-files | grep '\.sh$' ) | grep -v '\.md$' | grep -v .gitlab-ci.yml | sort | uniq | xargs -n1 shellcheck -f gcc --source-path=SCRIPTDIR

# shfmt
( git ls-files -z | xargs -0 grep -l 'shellcheck shell=\|^#!.\+sh'; git ls-files | grep '\.sh$' ) | grep -v '\.md$' | grep -v .gitlab-ci.yml | sort | uniq | xargs -n1 shfmt -ln bash -ci -bn -i 2 -d -w

Validate the codebase with the following script, it should return with OK on success.

$ ./dev/lint.sh
OK

Layout

Each layout folder contains the following files

File Description
aliases bash aliases declared via alias="some command
completion bash completion functions for complete
env any additional bash-isms that don't fall in the above category
exports environment vars that are exported via export
extra any additional bash-isms that don't fall in the above category
functions bash function declarations, can be exported via export -f FN_NAME
prompt scripts to generate or modify the prompt vars PS1, PS2, SUDO_PS1

Folder layout

- dotenv
    # common across all platforms
    - LISTED FILES^^
    # bin dir to append to path
    - `bin`
    - `bin.$(uname -m)`
    # non shell config files
    - config
        - git
    - darwin
        # only sourced on OSX
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`
    - lib
      - library scripts
    - linux
        # only sourced on linux
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`
    - screen
        # only sourced on when screen is active
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`
    - ssh
        # only sourced on when ssh is active
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`
    - tmux
        # only sourced on when tmux is active
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`
    - wsl
        # only sourced on WSL (1 & 2)
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`
    - wsl2
        # only sourced on WSL 2
        - LISTED FILES^^
        # bin dir to append to path
        - `bin`
        - `bin.$(uname -m)`

File loading order

The core ~/.bashrc will import each of the files in the layout table, first in the common top level dotenv folder. then platform specific files, and finally if a file is name with a . prefix in your HOME directory (ex. .exports).

dotenv environments are loaded in the following order:

  1. dotenv/*.sh
  2. dotenv/{darwin,linux}/*.sh
  3. dotenv/wsl/*.sh
  4. dotenv/wsl2/*.sh
  5. dotenv/tmux/*.sh
  6. dotenv/screen/*.sh
  7. dotenv/ssh/*.sh

dotenv scripts are loaded in the following order:

  1. exports
  2. functions
  3. aliases
  4. extra
  5. env
  6. completion
  7. plugins
  8. prompt