Dotfiles

3 minute read

An excellent list of dotfile resources on GitHub.

What are dotfiles? (I can’t believe I’m linking to Quora)

In UNIX file systems, dotfiles are text-based configurations files that stores settings of almost every application, service and tool running on your system. These files control the behavior of applications from boot to termination and everything in between.

More info here.

Here’s the setup I use, a fork of mathiasbynens/dotfiles. I’m a little out of date. Going to sync up and check out some those other resources.

One of my favourite functions is wtfis()1:

# Show what a given command really is. It is a combination of "type", "file"
# and "ls". Unlike "which", it does not only take $PATH into account. This
# means it works for aliases and hashes, too. (The name "whatis" was taken,
# and I did not want to overwrite "which", hence "wtfis".)
# The return value is the result of "type" for the last command specified.
function wtfis {
  local cmd type i=1 ret=0;
  if [ $# -eq 0 ]; then
    # Use "fc" to get the last command, and use that when no command
    # was given as a parameter to "wtfis".
    set -- $(fc -nl -1);
    while [ $# -gt 0 -a '(' "sudo" = "$1" -o "-" = "${1:0:1}" ')' ]; do
      # Ignore "sudo" and options ("-x" or "--bla").
      shift;
    done;
    # Replace the positional parameter array with the last command name.
    set -- "$1";
  fi;
  for cmd; do
    type="$(type "$cmd")";
    ret=$?;
    if [ $ret -eq 0 ]; then
      # Try to get the physical path. This works for hashes and
      # "normal" binaries.
      local path="$(type -p "$cmd")";
      if [ -z "$path" ]; then
        # Show the output from "type" without ANSI escapes.
        echo "${type//$'\e'/\\033}";

        case "$(command -v "$cmd")" in
          'alias')
            local alias_="$(alias "$cmd")";
            # The output looks like "alias foo='bar'"; so
            # strip everything except the body.
            alias_="${alias_#*\'}";
            alias_="${alias_%\'}";
            # Use "read" to process escapes. E.g. 'test\ it'
            # will # be read as 'test it'. This allows for
            # spaces inside command names.
            read -d ' ' alias_ <<< "$alias_";
            # Recurse and indent the output.
            # TODO: prevent infinite recursion
            wtfis "$alias_" 2>&2 | sed 's/^/  /';
            ;;
          'keyword' | 'builtin')
            # Get the one-line description from the built-in
            # help, if available. Note that this does not
            # guarantee anything useful, though. Look at the
            # output for "help set", for instance.
            help "$cmd" 2> /dev/null | {
              local buf line;
              read -r line;
              while read -r line; do
                buf="$buf${line/.  */.} ";
                if [[ "$buf" =~ \.\ $ ]]; then
                  echo "$buf";
                  break;
                fi;
              done;
            };
            ;;
        esac;
      else
        # For physical paths, get some more info.
        # First, get the one-line description from the man page.
        # ("col -b" gets rid of the backspaces used by OS X's man
        # to get a "bold" font.)
        (COLUMNS=10000 man "$(basename "$path")" 2>/dev/null) | col -b | \
        awk '/^NAME$/,/^$/' | {
          local buf line;
          read -r line;
          while read -r line; do
            buf="$buf${line/.  */.} ";
            if [[ "$buf" =~ \.\ $ ]]; then
              echo "$buf";
              buf='';
              break;
            fi;
          done;
          [ -n "$buf" ] && echo "$buf";
        }

        # Get the absolute path for the binary.
        local full_path="$(
          cd "$(dirname "$path")" \
            && echo "$PWD/$(basename "$path")" \
            || echo "$path"
        )";

        # Then, combine the output of "type" and "file".
        local fileinfo="$(file "$full_path")";
        echo "${type%$path}${fileinfo}";

        # Finally, show it using "ls" and highlight the path.
        # If the path is a symlink, keep going until we find the
        # final destination. (This assumes there are no circular
        # references.)
        local paths=("$path") target_path="$path";
                while [ -L "$target_path" ]; do
          target_path="$(readlink "$target_path")";
          paths+=("$(
            # Do some relative path resolving for systems
            # without readlink --canonicalize.
            cd "$(dirname "$path")";
            cd "$(dirname "$target_path")";
            echo "$PWD/$(basename "$target_path")"
          )");
        done;
        local ls="$(command ls -fdalF "${paths[@]}")";
        echo "${ls/$path/$'\e[7m'${path}$'\e[27m'}";
      fi;
    fi;

    # Separate the output for all but the last command with blank lines.
    [ $i -lt $# ] && echo;
    let i++;
  done;
  return $ret;
}

  1. I think this was originally from here