Repository: holman/dotfiles Branch: master Commit: c6afa692d72e Files: 73 Total size: 49.2 KB Directory structure: gitextract_nwnhqg01/ ├── .gitignore ├── Brewfile ├── LICENSE.md ├── README.md ├── atuin/ │ └── env.zsh ├── bin/ │ ├── a │ ├── battery-status │ ├── dns-flush │ ├── dot │ ├── e │ ├── ee │ ├── git-all │ ├── git-amend │ ├── git-copy-branch-name │ ├── git-credit │ ├── git-delete-local-merged │ ├── git-edit-new │ ├── git-nuke │ ├── git-promote │ ├── git-rank-contributors │ ├── git-track │ ├── git-undo │ ├── git-unpushed │ ├── git-unpushed-stat │ ├── git-up │ ├── git-wtf │ ├── gitio │ ├── headers │ ├── search │ ├── set-defaults │ ├── todo │ └── yt ├── docker/ │ └── aliases.zsh ├── editors/ │ ├── env.zsh │ └── windsurf.zsh ├── functions/ │ ├── _boom │ ├── _brew │ ├── _c │ ├── _git-rm │ ├── c │ ├── extract │ └── gf ├── git/ │ ├── aliases.zsh │ ├── completion.zsh │ ├── gitconfig.local.symlink.example │ ├── gitconfig.symlink │ └── gitignore.symlink ├── homebrew/ │ ├── install.sh │ └── path.zsh ├── macos/ │ ├── set-defaults.sh │ └── set-hostname.sh ├── ruby/ │ ├── aliases.zsh │ ├── completion.zsh │ ├── gemrc.symlink │ ├── irbrc.symlink │ └── rbenv.zsh ├── script/ │ ├── bootstrap │ └── install ├── system/ │ ├── _path.zsh │ ├── aliases.zsh │ ├── env.zsh │ ├── grc.zsh │ └── keys.zsh ├── vim/ │ └── vimrc.symlink ├── xcode/ │ └── aliases.zsh ├── yarn/ │ └── path.zsh └── zsh/ ├── aliases.zsh ├── completion.zsh ├── config.zsh ├── fpath.zsh ├── prompt.zsh ├── window.zsh └── zshrc.symlink ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ git/gitconfig.local.symlink Brewfile.lock.json ================================================ FILE: Brewfile ================================================ cask_args appdir: '/Applications' tap 'homebrew/bundle' brew 'atuin' brew 'cloudflared' brew 'imagemagick' brew 'postgresql@17' brew 'redis' brew 'ruby-build' brew 'spaceman-diff' brew 'spark' brew 'stripe/stripe-cli/stripe' brew 'stripe/stripe-mock/stripe-mock' brew 'wget' brew 'yt-dlp' cask '1password' cask 'airtable' cask 'arq' cask 'codex' cask 'conductor' cask 'diffusionbee' cask 'ghostty' cask 'handbrake-app' cask 'iina' cask 'messenger' cask 'notion-calendar' cask 'plex' cask 'qlvideo' cask 'sonos' cask 'steam' cask 'transmission' cask 'raycast' cask 'whatsapp' cask 'windsurf' cask 'visual-studio-code' cask 'vlc' cask 'zed' cask 'zoom' ================================================ FILE: LICENSE.md ================================================ The MIT License Copyright (c) Zach Holman, http://zachholman.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # holman does dotfiles Your dotfiles are how you personalize your system. These are mine. I was a little tired of having long alias files and everything strewn about (which is extremely common on other dotfiles projects, too). That led to this project being much more topic-centric. I realized I could split a lot of things up into the main areas I used (Ruby, git, system libraries, and so on), so I structured the project accordingly. If you're interested in the philosophy behind why projects like these are awesome, you might want to [read my post on the subject](http://zachholman.com/2010/08/dotfiles-are-meant-to-be-forked/). ## topical Everything's built around topic areas. If you're adding a new area to your forked dotfiles — say, "Java" — you can simply add a `java` directory and put files in there. Anything with an extension of `.zsh` will get automatically included into your shell. Anything with an extension of `.symlink` will get symlinked without extension into `$HOME` when you run `script/bootstrap`. ## what's inside A lot of stuff. Seriously, a lot of stuff. Check them out in the file browser above and see what components may mesh up with you. [Fork it](https://github.com/holman/dotfiles/fork), remove what you don't use, and build on what you do use. ## components There's a few special files in the hierarchy. - **bin/**: Anything in `bin/` will get added to your `$PATH` and be made available everywhere. - **topic/\*.zsh**: Any files ending in `.zsh` get loaded into your environment. - **topic/path.zsh**: Any file named `path.zsh` is loaded first and is expected to setup `$PATH` or similar. - **topic/completion.zsh**: Any file named `completion.zsh` is loaded last and is expected to setup autocomplete. - **topic/install.sh**: Any file named `install.sh` is executed when you run `script/install`. To avoid being loaded automatically, its extension is `.sh`, not `.zsh`. - **topic/\*.symlink**: Any file ending in `*.symlink` gets symlinked into your `$HOME`. This is so you can keep all of those versioned in your dotfiles but still keep those autoloaded files in your home directory. These get symlinked in when you run `script/bootstrap`. ## install Run this: ```sh git clone https://github.com/holman/dotfiles.git ~/.dotfiles cd ~/.dotfiles script/bootstrap ``` This will symlink the appropriate files in `.dotfiles` to your home directory. Everything is configured and tweaked within `~/.dotfiles`. The main file you'll want to change right off the bat is `zsh/zshrc.symlink`, which sets up a few paths that'll be different on your particular machine. `dot` is a simple script that installs some dependencies, sets sane macOS defaults, and so on. Tweak this script, and occasionally run `dot` from time to time to keep your environment fresh and up-to-date. You can find this script in `bin/`. ## bugs I want this to work for everyone; that means when you clone it down it should work for you even though you may not have `rbenv` installed, for example. That said, I do use this as _my_ dotfiles, so there's a good chance I may break something if I forget to make a check for a dependency. If you're brand-new to the project and run into any blockers, please [open an issue](https://github.com/holman/dotfiles/issues) on this repository and I'd love to get it fixed for you! ## thanks I forked [Ryan Bates](http://github.com/ryanb)' excellent [dotfiles](http://github.com/ryanb/dotfiles) for a couple years before the weight of my changes and tweaks inspired me to finally roll my own. But Ryan's dotfiles were an easy way to get into bash customization, and then to jump ship to zsh a bit later. A decent amount of the code in these dotfiles stem or are inspired from Ryan's original project. ================================================ FILE: atuin/env.zsh ================================================ eval "$(atuin init zsh)" ================================================ FILE: bin/a ================================================ #!/bin/sh # # Quick shortcut to ~*-~*AI*~-*~ # # Load up a current $HotThing AI client with preferable settings (which is # usually yolo-lfg style anyway; computers wouldn't do anything to us). # # USAGE: # # $ a # # => opens the AI client. yeah, easy peasy. claude --dangerously-skip-permissions ================================================ FILE: bin/battery-status ================================================ #!/bin/bash # # battery-status # # A quick little indicator for battery status on your Mac laptop, suitable for # display in your prompt. if test ! "$(uname)" = "Darwin" then printf "" exit 0 fi battstat=$(pmset -g batt) time_left=$(echo $battstat | tail -1 | cut -f2 | awk -F"; " '{print $3}' | cut -d' ' -f1 ) if [[ $(pmset -g ac) == *"No adapter attached."* ]] then emoji='🔋' else emoji='🔌' fi if [[ $time_left == *"(no"* || $time_left == *"not"* ]] then time_left='⌛️ ' fi if [[ $time_left == *"0:00"* ]] then time_left='⚡️ ' fi printf "\033[1;92m$emoji $time_left \033[0m" ================================================ FILE: bin/dns-flush ================================================ #!/bin/sh # # I literally always forget how to flush my DNS settings on macOS (in large part # because it changes every damn update). sudo killall -HUP mDNSResponder ================================================ FILE: bin/dot ================================================ #!/bin/sh # # dot # # `dot` handles installation, updates, things like that. Run it periodically # to make sure you're on the latest and greatest. set -e parentDirectory="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P)" dotfilesDirectory="$(cd "$( dirname "$parentDirectory" )" && pwd -P)" displayUsageAndExit() { echo "dot -- dotfiles management" echo "" echo "Usage: dot [options]" echo "" echo "Options:" echo " -e, --edit Open dotfiles directory for editing" echo " -h, --help Show this help message and exit" exit } while test $# -gt 0; do case "$1" in "-h"|"--help") displayUsageAndExit ;; "-e"|"--edit") exec "$EDITOR" "$dotfilesDirectory" exit ;; *) echo "Invalid option: $1" displayUsageAndExit ;; esac shift done export ZSH=$HOME/.dotfiles # Update dotfiles themselves echo "› git pull" git -C $ZSH pull # Set macOS defaults $ZSH/macos/set-defaults.sh # Set macOS hostname $ZSH/macos/set-hostname.sh # Install homebrew $ZSH/homebrew/install.sh 2>&1 # Upgrade homebrew echo "› brew update" brew update echo "› brew upgrade" brew upgrade # Install software echo "› script/install" $ZSH/script/install ================================================ FILE: bin/e ================================================ #!/bin/sh # # Quick shortcut to an editor. # # This means that as I travel back and forth between editors, hey, I don't have # to re-learn any arcane commands. Neat. # # USAGE: # # $ e # # => opens the current directory in your editor # # $ e . # $ e /usr/local # # => opens the specified directory in your editor exec "$EDITOR" "${1:-.}" ================================================ FILE: bin/ee ================================================ #!/bin/sh # # vscode requires `--wait` if you're editing interactively in a prompt. # EDITOR="$EDITOR --wait" $@ ================================================ FILE: bin/git-all ================================================ #!/bin/sh # # Stage all unstaged. git add -A ================================================ FILE: bin/git-amend ================================================ #!/bin/sh # # Use the last commit message and amend your stuffs. git commit --amend -C HEAD ================================================ FILE: bin/git-copy-branch-name ================================================ #!/bin/sh # # Copy the current branch name to the clipboard. branch=$(git rev-parse --abbrev-ref HEAD) echo $branch echo $branch | tr -d '\n' | tr -d ' ' | pbcopy ================================================ FILE: bin/git-credit ================================================ #!/bin/sh # # A very slightly quicker way to credit an author on the latest commit. # # $1 - The full name of the author. # $2 - The email address of the author. # # Examples # # git credit "Zach Holman" zach@example.com # git commit --amend --author "$1 <$2>" -C HEAD ================================================ FILE: bin/git-delete-local-merged ================================================ #!/bin/sh # # Delete all local branches that have been merged into HEAD. Stolen from # our favorite @tekkub: # # https://plus.google.com/115587336092124934674/posts/dXsagsvLakJ git branch -d `git branch --merged | grep -v '^*' | grep -v 'master' | tr -d '\n'` ================================================ FILE: bin/git-edit-new ================================================ #!/bin/sh # # Open new, unstaged files in your $EDITOR. # # This is nice to have when you run a command line generator which generates a # file or three in your working directory, and you know you want to immediately # edit them in your editor next. Why waste time clicking around like some sort # of plebian when you can just run another command? $EDITOR $(git ls-files --others --exclude-standard) ================================================ FILE: bin/git-nuke ================================================ #!/bin/sh # # Nukes a branch locally and on the origin remote. # # $1 - Branch name. # # Examples # # git nuke add-git-nuke git branch -D $1 git push origin :$1 ================================================ FILE: bin/git-promote ================================================ #!/bin/sh # # Promotes a local topic branch to a remote tracking branch of the same name, # by pushing and then setting up the git config # # Thanks to ENTP: # http://hoth.entp.com/2008/11/10/improving-my-git-workflow curr_branch=$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||') remote_branch=$(git branch -r | grep "origin/${curr_branch}") [ -z "${remote_branch}" ] && ( git push origin "${curr_branch}" ) origin=$(git config --get "branch.${curr_branch}.remote") [ -z "${origin}" ] && ( git config --add "branch.${curr_branch}.remote" origin ) merge=$(git config --get "branch.${curr_branch}.merge") [ -z "${merge}" ] && ( git config --add "branch.${curr_branch}.merge" "refs/heads/${curr_branch}" ) ================================================ FILE: bin/git-rank-contributors ================================================ #!/usr/bin/env ruby ## git-rank-contributors: a simple script to trace through the logs and ## rank contributors by the total size of the diffs they're responsible for. ## A change counts twice as much as a plain addition or deletion. ## ## Output may or may not be suitable for inclusion in a CREDITS file. ## Probably not without some editing, because people often commit from more ## than one address. ## ## git-rank-contributors Copyright 2008 William Morgan . ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or (at ## your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You can find the GNU General Public License at: ## http://www.gnu.org/licenses/ class String def obfuscate; gsub(/@/, " at the ").gsub(/\.(\w+)(>|$)/, ' dot \1s\2') end def htmlize; gsub("&", "&").gsub("<", "<").gsub(">", ">") end # Fix for invalid encodings http://stackoverflow.com/a/24037885 def clean if RUBY_VERSION >= "2.1" scrub elsif RUBY_VERSION >= "1.9" encode("UTF-16be", :invalid => :replace).encode("UTF-8") else self end end end lines = {} verbose = ARGV.delete("-v") obfuscate = ARGV.delete("-o") htmlize = ARGV.delete("-h") author = nil state = :pre_author `git log -M -C -C -p --no-color`.clean.split("\n").each do |l| case when (state == :pre_author || state == :post_author) && l =~ /Author: (.*)$/ author = $1 state = :post_author lines[author] ||= 0 when state == :post_author && l =~ /^\+\+\+/ state = :in_diff when state == :in_diff && l =~ /^[\+\-]/ lines[author] += 1 when state == :in_diff && l =~ /^commit / state = :pre_author end end lines.sort_by { |a, c| -c }.each do |a, c| a = a.obfuscate if obfuscate a = a.htmlize if htmlize if verbose puts "#{a}: #{c} lines of diff" else puts a end end ================================================ FILE: bin/git-track ================================================ #!/bin/sh # # Sets up your branch to track a remote branch. Assumes you mean # `origin/$branch-name`. branch=$(git rev-parse --abbrev-ref HEAD) git branch $branch --set-upstream-to origin/$branch ================================================ FILE: bin/git-undo ================================================ #!/bin/sh # # Undo your last commit, but don't throw away your changes git reset --soft HEAD^ ================================================ FILE: bin/git-unpushed ================================================ #!/bin/sh # # Show the diff of everything you haven't pushed yet. branch=$(git rev-parse --abbrev-ref HEAD) git diff origin/$branch..HEAD ================================================ FILE: bin/git-unpushed-stat ================================================ #!/bin/sh # # Show the diffstat of everything you haven't pushed yet. branch=$(git rev-parse --abbrev-ref HEAD) count=$(git rev-list --count HEAD origin/$branch...HEAD) if [ "$count" -eq "1" ] then s='' else s='s' fi git diff --stat origin/$branch..HEAD echo " $count commit$s total" ================================================ FILE: bin/git-up ================================================ #!/bin/sh # # Usage: git-up # git-reup # # Like git-pull but show a short and sexy log of changes # immediately after merging (git-up) or rebasing (git-reup). # # Inspired by Kyle Neath's `git up' alias: # http://gist.github.com/249223 # # Stolen from Ryan Tomayko # http://github.com/rtomayko/dotfiles/blob/rtomayko/bin/git-up set -e PULL_ARGS="$@" # when invoked as git-reup, run as `git pull --rebase' test "$(basename $0)" = "git-reup" && PULL_ARGS="--rebase $PULL_ARGS" git pull $PULL_ARGS # show diffstat of all changes if we're pulling with --rebase. not # sure why git-pull only does this when merging. test "$(basename $0)" = "git-reup" && { echo "Diff:" git --no-pager diff --color --stat HEAD@{1}.. | sed 's/^/ /' } # show an abbreviated commit log of stuff that was just merged. echo "Log:" git log --color --pretty=oneline --abbrev-commit HEAD@{1}.. | sed 's/^/ /' ================================================ FILE: bin/git-wtf ================================================ #!/usr/bin/env ruby HELP = < .git-wtfrc" and edit it. The config file is a YAML file that specifies the integration branches, any branches to ignore, and the max number of commits to display when --all-commits isn't used. git-wtf will look for a .git-wtfrc file starting in the current directory, and recursively up to the root. IMPORTANT NOTE: all local branches referenced in .git-wtfrc must be prefixed with heads/, e.g. "heads/master". Remote branches must be of the form remotes//. EOS COPYRIGHT = <. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You can find the GNU General Public License at: http://www.gnu.org/licenses/ EOS require 'yaml' CONFIG_FN = ".git-wtfrc" class Numeric; def pluralize s; "#{to_s} #{s}" + (self != 1 ? "s" : "") end end if ARGV.delete("--help") || ARGV.delete("-h") puts USAGE exit end ## poor man's trollop $long = ARGV.delete("--long") || ARGV.delete("-l") $short = ARGV.delete("--short") || ARGV.delete("-s") $all = ARGV.delete("--all") || ARGV.delete("-a") $all_commits = ARGV.delete("--all-commits") || ARGV.delete("-A") $dump_config = ARGV.delete("--dump-config") $key = ARGV.delete("--key") || ARGV.delete("-k") $show_relations = ARGV.delete("--relations") || ARGV.delete("-r") ARGV.each { |a| abort "Error: unknown argument #{a}." if a =~ /^--/ } ## search up the path for a file def find_file fn while true return fn if File.exist? fn fn2 = File.join("..", fn) return nil if File.expand_path(fn2) == File.expand_path(fn) fn = fn2 end end want_color = `git config color.wtf` want_color = `git config color.ui` if want_color.empty? $color = case want_color.chomp when "true"; true when "auto"; $stdout.tty? end def red s; $color ? "\033[31m#{s}\033[0m" : s end def green s; $color ? "\033[32m#{s}\033[0m" : s end def yellow s; $color ? "\033[33m#{s}\033[0m" : s end def cyan s; $color ? "\033[36m#{s}\033[0m" : s end def grey s; $color ? "\033[1;30m#{s}\033[0m" : s end def purple s; $color ? "\033[35m#{s}\033[0m" : s end ## the set of commits in 'to' that aren't in 'from'. ## if empty, 'to' has been merged into 'from'. def commits_between from, to if $long `git log --pretty=format:"- %s [#{yellow "%h"}] (#{purple "%ae"}; %ar)" #{from}..#{to}` else `git log --pretty=format:"- %s [#{yellow "%h"}]" #{from}..#{to}` end.split(/[\r\n]+/) end def show_commits commits, prefix=" " if commits.empty? puts "#{prefix} none" else max = $all_commits ? commits.size : $config["max_commits"] max -= 1 if max == commits.size - 1 # never show "and 1 more" commits[0 ... max].each { |c| puts "#{prefix}#{c}" } puts grey("#{prefix}... and #{commits.size - max} more (use -A to see all).") if commits.size > max end end def ahead_behind_string ahead, behind [ahead.empty? ? nil : "#{ahead.size.pluralize 'commit'} ahead", behind.empty? ? nil : "#{behind.size.pluralize 'commit'} behind"]. compact.join("; ") end def widget merged_in, remote_only=false, local_only=false, local_only_merge=false left, right = case when remote_only; %w({ }) when local_only; %w{( )} else %w([ ]) end middle = case when merged_in && local_only_merge; green("~") when merged_in; green("x") else " " end print left, middle, right end def show b have_both = b[:local_branch] && b[:remote_branch] pushc, pullc, oosync = if have_both [x = commits_between(b[:remote_branch], b[:local_branch]), y = commits_between(b[:local_branch], b[:remote_branch]), !x.empty? && !y.empty?] end if b[:local_branch] puts "Local branch: " + green(b[:local_branch].sub(/^heads\//, "")) if have_both if pushc.empty? puts "#{widget true} in sync with remote" else action = oosync ? "push after rebase / merge" : "push" puts "#{widget false} NOT in sync with remote (you should #{action})" show_commits pushc unless $short end end end if b[:remote_branch] puts "Remote branch: #{cyan b[:remote_branch]} (#{b[:remote_url]})" if have_both if pullc.empty? puts "#{widget true} in sync with local" else action = pushc.empty? ? "merge" : "rebase / merge" puts "#{widget false} NOT in sync with local (you should #{action})" show_commits pullc unless $short end end end puts "\n#{red "WARNING"}: local and remote branches have diverged. A merge will occur unless you rebase." if oosync end def show_relations b, all_branches ibs, fbs = all_branches.partition { |name, br| $config["integration-branches"].include?(br[:local_branch]) || $config["integration-branches"].include?(br[:remote_branch]) } if $config["integration-branches"].include? b[:local_branch] puts "\nFeature branches:" unless fbs.empty? fbs.each do |name, br| next if $config["ignore"].member?(br[:local_branch]) || $config["ignore"].member?(br[:remote_branch]) next if br[:ignore] local_only = br[:remote_branch].nil? remote_only = br[:local_branch].nil? name = if local_only purple br[:name] elsif remote_only cyan br[:name] else green br[:name] end ## for remote_only branches, we'll compute wrt the remote branch head. otherwise, we'll ## use the local branch head. head = remote_only ? br[:remote_branch] : br[:local_branch] remote_ahead = b[:remote_branch] ? commits_between(b[:remote_branch], head) : [] local_ahead = b[:local_branch] ? commits_between(b[:local_branch], head) : [] if local_ahead.empty? && remote_ahead.empty? puts "#{widget true, remote_only, local_only} #{name} #{local_only ? "(local-only) " : ""}is merged in" elsif local_ahead.empty? puts "#{widget true, remote_only, local_only, true} #{name} merged in (only locally)" else behind = commits_between head, (br[:local_branch] || br[:remote_branch]) ahead = remote_only ? remote_ahead : local_ahead puts "#{widget false, remote_only, local_only} #{name} #{local_only ? "(local-only) " : ""}is NOT merged in (#{ahead_behind_string ahead, behind})" show_commits ahead unless $short end end else puts "\nIntegration branches:" unless ibs.empty? # unlikely ibs.sort_by { |v, br| v }.each do |v, br| next if $config["ignore"].member?(br[:local_branch]) || $config["ignore"].member?(br[:remote_branch]) next if br[:ignore] local_only = br[:remote_branch].nil? remote_only = br[:local_branch].nil? name = remote_only ? cyan(br[:name]) : green(br[:name]) ahead = commits_between v, (b[:local_branch] || b[:remote_branch]) if ahead.empty? puts "#{widget true, local_only} merged into #{name}" else #behind = commits_between b[:local_branch], v puts "#{widget false, local_only} NOT merged into #{name} (#{ahead.size.pluralize 'commit'} ahead)" show_commits ahead unless $short end end end end #### EXECUTION STARTS HERE #### ## find config file and load it $config = { "integration-branches" => %w(heads/master heads/next heads/edge), "ignore" => [], "max_commits" => 5 }.merge begin fn = find_file CONFIG_FN if fn && (h = YAML::load_file(fn)) # yaml turns empty files into false h["integration-branches"] ||= h["versions"] # support old nomenclature h else {} end end if $dump_config puts $config.to_yaml exit end ## first, index registered remotes remotes = `git config --get-regexp ^remote\.\*\.url`.split(/[\r\n]+/).inject({}) do |hash, l| l =~ /^remote\.(.+?)\.url (.+)$/ or next hash hash[$1] ||= $2 hash end ## next, index followed branches branches = `git config --get-regexp ^branch\.`.split(/[\r\n]+/).inject({}) do |hash, l| case l when /branch\.(.*?)\.remote (.+)/ name, remote = $1, $2 hash[name] ||= {} hash[name].merge! :remote => remote, :remote_url => remotes[remote] when /branch\.(.*?)\.merge ((refs\/)?heads\/)?(.+)/ name, remote_branch = $1, $4 hash[name] ||= {} hash[name].merge! :remote_mergepoint => remote_branch end hash end ## finally, index all branches remote_branches = {} `git show-ref`.split(/[\r\n]+/).each do |l| sha1, ref = l.chomp.split " refs/" if ref =~ /^heads\/(.+)$/ # local branch name = $1 next if name == "HEAD" branches[name] ||= {} branches[name].merge! :name => name, :local_branch => ref elsif ref =~ /^remotes\/(.+?)\/(.+)$/ # remote branch remote, name = $1, $2 remote_branches["#{remote}/#{name}"] = true next if name == "HEAD" ignore = !($all || remote == "origin") branch = name if branches[name] && branches[name][:remote] == remote # nothing else name = "#{remote}/#{branch}" end branches[name] ||= {} branches[name].merge! :name => name, :remote => remote, :remote_branch => "#{remote}/#{branch}", :remote_url => remotes[remote], :ignore => ignore end end ## assemble remotes branches.each do |k, b| next unless b[:remote] && b[:remote_mergepoint] b[:remote_branch] = if b[:remote] == "." b[:remote_mergepoint] else t = "#{b[:remote]}/#{b[:remote_mergepoint]}" remote_branches[t] && t # only if it's still alive end end show_dirty = ARGV.empty? targets = if ARGV.empty? [`git symbolic-ref HEAD`.chomp.sub(/^refs\/heads\//, "")] else ARGV.map { |x| x.sub(/^heads\//, "") } end.map { |t| branches[t] or abort "Error: can't find branch #{t.inspect}." } targets.each do |t| show t show_relations t, branches if $show_relations || t[:remote_branch].nil? end modified = show_dirty && `git ls-files -m` != "" uncommitted = show_dirty && `git diff-index --cached HEAD` != "" if $key puts puts KEY end puts if modified || uncommitted puts "#{red "NOTE"}: working directory contains modified files." if modified puts "#{red "NOTE"}: staging area contains staged but uncommitted files." if uncommitted # the end! ================================================ FILE: bin/gitio ================================================ #!/usr/bin/env ruby # Usage: gitio URL [CODE] # # Turns a github.com URL # into a git.io URL # # Created by @defunkt: # https://gist.github.com/1209316 # # Copies the git.io URL to your clipboard. url = ARGV[0] code = ARGV[1] if url !~ /^(https?:\/\/)?(gist\.)?github.com/ abort "* github.com URLs only" end if url !~ /^http/ url = "https://#{url}" end if code code = "-F code=#{code}" end output = `curl -i https://git.io -F 'url=#{url}' #{code} 2> /dev/null` if output =~ /Location: (.+)\n?/ puts $1 `echo #$1 | pbcopy` else puts output end ================================================ FILE: bin/headers ================================================ #!/bin/sh # # https://github.com/rtomayko/dotfiles/blob/rtomayko/.local/bin/headers curl -sv "$@" 2>&1 >/dev/null | grep -v "^\*" | grep -v "^}" | cut -c3- ================================================ FILE: bin/search ================================================ #!/bin/sh # # Quick search in a directory for a string ($@). # set -e # use -iru to search directories ack usually ignores (like .git) if [ -x /usr/bin/ack-grep ]; then ack-grep -i "$@" else ack -i "$@" fi ================================================ FILE: bin/set-defaults ================================================ #!/bin/sh # # Sets macOS defaults by running $ZSH/macos/set-defaults.sh. exec $ZSH/macos/set-defaults.sh ================================================ FILE: bin/todo ================================================ #!/bin/sh # # Creates something for me to do. # # I've used literally every todo list, app, program, script, everything. Even # the ones you are building and haven't released yet. # # I've found that they're all nice in their nice ways, but I still don't use # them, thus defeating the purpose of a todo list. # # All `todo` does is put a file on my Desktop with the filename given. That's # it. I aggressively prune my desktop of old tasks and keep one or two on there # at a time. Once I've finished a todo, I just delete the file. That's it. # # Millions of dollars later and `touch` wins. # Run our new web 2.0 todo list application and raise millions of VC dollars. touch ~/Desktop/"$*" ================================================ FILE: bin/yt ================================================ #!/bin/sh # # Downloads the embedded video on any web page straight to the desktop. # # youtube-dlp, which is awesome: # https://github.com/yt-dlp/yt-dlp # cd ~/Desktop && yt-dlp -S "ext" "$1" ================================================ FILE: docker/aliases.zsh ================================================ alias d='docker $*' alias d-c='docker-compose $*' ================================================ FILE: editors/env.zsh ================================================ export EDITOR='zed' ================================================ FILE: editors/windsurf.zsh ================================================ export PATH="/Users/holman/.codeium/windsurf/bin:$PATH" ================================================ FILE: functions/_boom ================================================ #compdef boom local state line cmds ret=1 _arguments -C '1: :->cmds' '*: :->args' case $state in cmds) local -a cmds cmds=( 'all:show all items in all lists' 'edit:edit the boom JSON file in $EDITOR' 'help:help text' ) _describe -t commands 'boom command' cmds && ret=0 _values 'lists' $(boom | awk '{print $1}') ;; args) case $line[1] in (boom|all|edit|help) ;; *) _values 'items' `boom $line[1] | awk '{print $1}' | sed -e 's/://'` 2>/dev/null && ret=0 ;; esac ;; esac return ret ================================================ FILE: functions/_brew ================================================ #compdef brew # Brew ZSH completion function # Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions) # and rename it _brew # # altered from _fink _brew_all_formulae() { formulae=(`brew search`) } _brew_installed_formulae() { installed_formulae=(`brew list`) } local -a _1st_arguments _1st_arguments=( 'install:install a formula' 'remove:remove a formula' 'search:search for a formula (/regex/ or string)' 'list:list files in a formula or not-installed formulae' 'link:link a formula' 'unlink:unlink a formula' 'home:visit the homepage of a formula or the brew project' 'info:information about a formula' 'prune:remove dead links' 'update:freshen up links' 'log:git commit log for a formula' 'create:create a new formula' 'edit:edit a formula' 'bundle:install or upgrade all dependencies in a Brewfile' ) local -a _bundle_arguments _bundle_arguments=( 'dump:write all installed casks/formulae/taps into a Brewfile' 'cleanup:uninstall all dependencies not listed in a Brewfile' 'check:check if all dependencies are installed in a Brewfile' ) local expl local -a formula installed_formulae _arguments \ '(-v --verbose)'{-v,--verbose}'[verbose]' \ '(--version)--version[version information]' \ '(--prefix)--prefix[where brew lives on this system]' \ '(--cache)--cache[brew cache]' \ '*:: :->subcmds' && return 0 if (( CURRENT == 1 )); then _describe -t commands "brew subcommand" _1st_arguments return fi case "$words[1]" in list) _arguments \ '(--unbrewed)--unbrewed[files in brew --prefix not controlled by brew]' \ '1: :->forms' && return 0 if [[ "$state" == forms ]]; then _brew_installed_formulae _requested installed_formulae expl 'installed formulae' compadd -a installed_formulae fi ;; install|home|log|info) _brew_all_formulae _wanted formulae expl 'all formulae' compadd -a formulae ;; remove|edit|xo) _brew_installed_formulae _wanted installed_formulae expl 'installed formulae' compadd -a installed_formulae ;; bundle) _describe 'values' _bundle_arguments ;; esac ================================================ FILE: functions/_c ================================================ #compdef c _files -W $PROJECTS -/ _files -W $GOPATH/src/github.com -/ # See further documentation in `functions/c`. ================================================ FILE: functions/_git-rm ================================================ #compdef git-rm _arguments -S -A '-*' \ '-f[override the up-to-date check]' \ "-n[don't actually remove the files, just show if they exist in the index]" \ '-r[allow recursive removal when a leading directory-name is given]' \ '--cached[only remove files from the index]' && ret=0 _files ================================================ FILE: functions/c ================================================ #!/bin/zsh # # This lets you quickly jump into a project directory. # # Type: # # c # # ...to autocomplete on all of your projects in the directories specified in # `functions/_c`. Typically I'm using it like: # # c holm/bo # # ...to quickly jump into holman/boom, for example. cd "$PROJECTS/$1" ================================================ FILE: functions/extract ================================================ #!/bin/sh # # Usage: extract # Description: extracts archived files / mounts disk images # Note: .dmg/hdiutil is macOS-specific. # # credit: http://nparikh.org/notes/zshrc.txt extract () { if [ -f $1 ]; then case $1 in *.tar.bz2) tar -jxvf $1 ;; *.tar.gz) tar -zxvf $1 ;; *.bz2) bunzip2 $1 ;; *.dmg) hdiutil mount $1 ;; *.gz) gunzip $1 ;; *.tar) tar -xvf $1 ;; *.tbz2) tar -jxvf $1 ;; *.tgz) tar -zxvf $1 ;; *.zip) unzip $1 ;; *.ZIP) unzip $1 ;; *.pax) cat $1 | pax -r ;; *.pax.Z) uncompress $1 --stdout | pax -r ;; *.rar) unrar x $1 ;; *.Z) uncompress $1 ;; *) echo "'$1' cannot be extracted/mounted via extract()" ;; esac else echo "'$1' is not a valid file" fi } ================================================ FILE: functions/gf ================================================ gf() { local branch=$1 git checkout -b $branch origin/$branch } ================================================ FILE: git/aliases.zsh ================================================ # Use `hub` as our git wrapper: # http://defunkt.github.com/hub/ hub_path=$(which hub) if (( $+commands[hub] )) then alias git=$hub_path fi # The rest of my fun git aliases alias gl='git pull --prune' alias glog="git log --graph --pretty=format:'%Cred%h%Creset %an: %s - %Creset %C(yellow)%d%Creset %Cgreen(%cr)%Creset' --abbrev-commit --date=relative" alias gp='git push origin HEAD' # Remove `+` and `-` from start of diff lines; just rely upon color. alias gd='git diff --color | sed "s/^\([^-+ ]*\)[-+ ]/\\1/" | less -r' alias gc='git commit' alias gca='git commit -a' alias gco='git checkout' alias gcb='git copy-branch-name' alias gb='git branch' alias gs='git status -sb' # upgrade your git if -sb breaks for you. it's fun. alias gac='git add -A && git commit -m' alias ge='git-edit-new' ================================================ FILE: git/completion.zsh ================================================ # Uses git's autocompletion for inner commands. Assumes an install of git's # bash `git-completion` script at $completion below (this is where Homebrew # tosses it, at least). completion='$(brew --prefix)/share/zsh/site-functions/_git' if test -f $completion then source $completion fi ================================================ FILE: git/gitconfig.local.symlink.example ================================================ [user] name = AUTHORNAME email = AUTHOREMAIL [credential] helper = GIT_CREDENTIAL_HELPER ================================================ FILE: git/gitconfig.symlink ================================================ # Local/private config goes in the include [include] path = ~/.gitconfig.local [hub] protocol = https [alias] co = checkout promote = !$ZSH/bin/git-promote wtf = !$ZSH/bin/git-wtf rank-contributors = !$ZSH/bin/git-rank-contributors count = !git shortlog -sn [color] diff = auto status = auto branch = auto ui = true [core] excludesfile = ~/.gitignore editor = vim [apply] whitespace = nowarn [mergetool] keepBackup = false [difftool] prompt = false [help] autocorrect = 1 [push] # See `git help config` (search for push.default) # for more information on different options of the below setting. # # Setting to git 2.0 default to suppress warning message default = simple [credential] helper = osxkeychain [diff "spaceman-diff"] command = /opt/homebrew/bin/spaceman-diff [init] defaultBranch = main [pull] rebase = true ================================================ FILE: git/gitignore.symlink ================================================ .DS_Store *~ *.swp ================================================ FILE: homebrew/install.sh ================================================ #!/bin/sh # # Homebrew # # This installs some of the common dependencies needed (or at least desired) # using Homebrew. # Check for Homebrew if test ! $(which brew) then echo " Installing Homebrew for you." # Install the correct homebrew for each OS type if test "$(uname)" = "Darwin" then ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" elif test "$(expr substr $(uname -s) 1 5)" = "Linux" then ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install)" fi fi # Link keg-only formulas that we want in PATH brew list | grep 'postgresql@' | xargs -I {} brew link {} --force 2>/dev/null exit 0 ================================================ FILE: homebrew/path.zsh ================================================ export PATH="/opt/homebrew/bin:$PATH" ================================================ FILE: macos/set-defaults.sh ================================================ # Sets reasonable macOS defaults. # # Or, in other words, set shit how I like in macOS. # # The original idea (and a couple settings) were grabbed from: # https://github.com/mathiasbynens/dotfiles/blob/master/.macos # # Run ./set-defaults.sh and you'll be good to go. # Disable press-and-hold for keys in favor of key repeat. defaults write -g ApplePressAndHoldEnabled -bool false # Use AirDrop over every interface. srsly this should be a default. defaults write com.apple.NetworkBrowser BrowseAllInterfaces 1 # Always open everything in Finder's list view. This is important. defaults write com.apple.Finder FXPreferredViewStyle Nlsv # Show the ~/Library folder. chflags nohidden ~/Library # Set a really fast key repeat. defaults write NSGlobalDomain KeyRepeat -int 1 # Set the Finder prefs for showing a few different volumes on the Desktop. defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true # Run the screensaver if we're in the bottom-left hot corner. defaults write com.apple.dock wvous-bl-corner -int 5 defaults write com.apple.dock wvous-bl-modifier -int 0 # Hide Safari's bookmark bar. defaults write com.apple.Safari.plist ShowFavoritesBar -bool false # Always show Safari's "URL display" tab in the lower left on mouseover. Strangely # like, everyone and their LLMs on the internet thinks this is ShowStatusBar, but # it's not. defaults write com.apple.Safari ShowOverlayStatusBar -bool true # Set up Safari for development. defaults write com.apple.Safari.SandboxBroker ShowDevelopMenu -bool true defaults write com.apple.Safari.plist IncludeDevelopMenu -bool true defaults write com.apple.Safari.plist WebKitDeveloperExtrasEnabledPreferenceKey -bool true defaults write com.apple.Safari.plist "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" -bool true defaults write NSGlobalDomain WebKitDeveloperExtras -bool true ================================================ FILE: macos/set-hostname.sh ================================================ #!/bin/sh # # This corrects a shitty point of confusion with macOS where if you bounce # between wireless and wired connections, macOS will suddenly throw up its hands # and add a random-ass number to your hostname. Do it a couple times and you're # in like, the thousands appended to your hostname, which makes you look like a # chump when your machine is called "incredible-programmer-9390028", like # you're behind 9,390,027 other better programmers before you. Sheesh. # # Anyway, this runs in `dot` and only asks for your permission (usually TouchID) # if it actually needs to change your hostname for you, otherwise it's fast to # toss into `dot` anyway. # # None of this really matters in the big scheme of things, but it bothered me. hostname=$(scutil --get LocalHostName) # if hostname contains a hyphen and then a number, remove the hyphen and number normal_hostname=$(echo "$hostname" | sed 's/-[0-9]*$//') # if our hostname was changed by macOS, change it back if [ "$normal_hostname" != "$hostname" ]; then echo "Changing hostname from $hostname to $normal_hostname" scutil --set LocalHostName "$normal_hostname" scutil --set ComputerName "$normal_hostname" fi ================================================ FILE: ruby/aliases.zsh ================================================ alias sc='script/console' alias sg='script/generate' alias sd='script/destroy' ================================================ FILE: ruby/completion.zsh ================================================ # Stolen from # https://github.com/sstephenson/rbenv/blob/master/completions/rbenv.zsh if [[ ! -o interactive ]]; then return fi compctl -K _rbenv rbenv _rbenv() { local word words completions read -cA words word="${words[2]}" if [ "${#words}" -eq 2 ]; then completions="$(rbenv commands)" else completions="$(rbenv completions "${word}")" fi reply=("${(ps:\n:)completions}") } ================================================ FILE: ruby/gemrc.symlink ================================================ --- :update_sources: true :verbose: true :backtrace: false :benchmark: false gem: --no-document ================================================ FILE: ruby/irbrc.symlink ================================================ #!/usr/bin/ruby require 'irb/completion' require 'rubygems' IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb_history" IRB.conf[:PROMPT_MODE] = :SIMPLE IRB.conf[:AUTO_INDENT] = true class Object # list methods which aren't in superclass def local_methods(obj = self) (obj.methods - obj.class.superclass.instance_methods).sort end # print documentation # # ri 'Array#pop' # Array.ri # Array.ri :pop # arr.ri :pop def ri(method = nil) unless method && method =~ /^[A-Z]/ # if class isn't specified klass = self.kind_of?(Class) ? name : self.class.name method = [klass, method].compact.join('#') end puts `ri '#{method}'` end end # Copies the result of the last operation you ran in IRB to the system # clipboard (if you're on macOS). def cop last_value = IRB.CurrentContext.last_value %x[echo '#{last_value}' | pbcopy] "copied \`#{last_value}' to your clipboard" end def me User.find_by_email(`git config --get user.email`.chomp) end def r reload! end ================================================ FILE: ruby/rbenv.zsh ================================================ # fun: https://bugs.ruby-lang.org/issues/14009 export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES # init according to man page if (( $+commands[rbenv] )) then eval "$(rbenv init -)" fi ================================================ FILE: script/bootstrap ================================================ #!/usr/bin/env bash # # bootstrap installs things. cd "$(dirname "$0")/.." DOTFILES_ROOT=$(pwd -P) set -e echo '' info () { printf "\r [ \033[00;34m..\033[0m ] $1\n" } user () { printf "\r [ \033[0;33m??\033[0m ] $1\n" } success () { printf "\r\033[2K [ \033[00;32mOK\033[0m ] $1\n" } fail () { printf "\r\033[2K [\033[0;31mFAIL\033[0m] $1\n" echo '' exit } setup_gitconfig () { if ! [ -f git/gitconfig.local.symlink ] then info 'setup gitconfig' git_credential='cache' if [ "$(uname -s)" == "Darwin" ] then git_credential='osxkeychain' fi user ' - What is your github author name?' read -e git_authorname user ' - What is your github author email?' read -e git_authoremail sed -e "s/AUTHORNAME/$git_authorname/g" -e "s/AUTHOREMAIL/$git_authoremail/g" -e "s/GIT_CREDENTIAL_HELPER/$git_credential/g" git/gitconfig.local.symlink.example > git/gitconfig.local.symlink success 'gitconfig' fi } link_file () { local src=$1 dst=$2 local overwrite= backup= skip= local action= if [ -f "$dst" -o -d "$dst" -o -L "$dst" ] then if [ "$overwrite_all" == "false" ] && [ "$backup_all" == "false" ] && [ "$skip_all" == "false" ] then local currentSrc="$(readlink $dst)" if [ "$currentSrc" == "$src" ] then skip=true; else user "File already exists: $dst ($(basename "$src")), what do you want to do?\n\ [s]kip, [S]kip all, [o]verwrite, [O]verwrite all, [b]ackup, [B]ackup all?" read -n 1 action case "$action" in o ) overwrite=true;; O ) overwrite_all=true;; b ) backup=true;; B ) backup_all=true;; s ) skip=true;; S ) skip_all=true;; * ) ;; esac fi fi overwrite=${overwrite:-$overwrite_all} backup=${backup:-$backup_all} skip=${skip:-$skip_all} if [ "$overwrite" == "true" ] then rm -rf "$dst" success "removed $dst" fi if [ "$backup" == "true" ] then mv "$dst" "${dst}.backup" success "moved $dst to ${dst}.backup" fi if [ "$skip" == "true" ] then success "skipped $src" fi fi if [ "$skip" != "true" ] # "false" or empty then ln -s "$1" "$2" success "linked $1 to $2" fi } install_dotfiles () { info 'installing dotfiles' local overwrite_all=false backup_all=false skip_all=false for src in $(find -H "$DOTFILES_ROOT" -maxdepth 2 -name '*.symlink' -not -path '*.git*') do dst="$HOME/.$(basename "${src%.*}")" link_file "$src" "$dst" done } setup_gitconfig install_dotfiles # If we're on a Mac, let's install and setup homebrew. if [ "$(uname -s)" == "Darwin" ] then info "installing dependencies" if source bin/dot | while read -r data; do info "$data"; done then success "dependencies installed" else fail "error installing dependencies" fi fi echo '' echo ' All installed!' ================================================ FILE: script/install ================================================ #!/usr/bin/env bash # # Run all dotfiles installers. set -e cd "$(dirname $0)"/.. echo "› brew bundle" brew bundle # find the installers and run them iteratively find . -name install.sh | while read installer ; do sh -c "${installer}" ; done ================================================ FILE: system/_path.zsh ================================================ export PATH="./bin:$HOME/.local/bin:/usr/local/bin:/usr/local/sbin:$ZSH/bin:$PATH" export MANPATH="/usr/local/man:/usr/local/mysql/man:/usr/local/git/man:$MANPATH" ================================================ FILE: system/aliases.zsh ================================================ # grc overides for ls # Made possible through contributions from generous benefactors like # `brew install coreutils` if $(gls &>/dev/null) then alias ls="gls -F --color" alias l="gls -lAh --color" alias ll="gls -l --color" alias la='gls -A --color' fi ================================================ FILE: system/env.zsh ================================================ ================================================ FILE: system/grc.zsh ================================================ # GRC colorizes nifty unix tools all over the place if (( $+commands[grc] )) && (( $+commands[brew] )) then source `brew --prefix`/etc/grc.bashrc fi ================================================ FILE: system/keys.zsh ================================================ # Pipe my public key to my clipboard. alias pubkey="more ~/.ssh/id_rsa.pub | pbcopy | echo '=> Public key copied to pasteboard.'" ================================================ FILE: vim/vimrc.symlink ================================================ syntax on " Wrap gitcommit file types at the appropriate length filetype indent plugin on ================================================ FILE: xcode/aliases.zsh ================================================ alias ios="open -a Simulator" ================================================ FILE: yarn/path.zsh ================================================ # sup yarn # https://yarnpkg.com if (( $+commands[yarn] )) then export PATH="$PATH:`yarn global bin`" fi ================================================ FILE: zsh/aliases.zsh ================================================ alias reload!='. ~/.zshrc' alias cls='clear' # Good 'ol Clear Screen command ================================================ FILE: zsh/completion.zsh ================================================ # matches case insensitive for lowercase zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' # pasting with tabs doesn't perform completion zstyle ':completion:*' insert-tab pending ================================================ FILE: zsh/config.zsh ================================================ export LSCOLORS="exfxcxdxbxegedabagacad" export CLICOLOR=true fpath=($ZSH/functions $fpath) autoload -U $ZSH/functions/*(:t) HISTFILE=~/.zsh_history HISTSIZE=10000 SAVEHIST=10000 setopt NO_BG_NICE # don't nice background tasks setopt NO_HUP setopt NO_LIST_BEEP setopt LOCAL_OPTIONS # allow functions to have local options setopt LOCAL_TRAPS # allow functions to have local traps setopt HIST_VERIFY setopt SHARE_HISTORY # share history between sessions ??? setopt EXTENDED_HISTORY # add timestamps to history setopt PROMPT_SUBST setopt CORRECT setopt COMPLETE_IN_WORD setopt IGNORE_EOF setopt APPEND_HISTORY # adds history setopt INC_APPEND_HISTORY SHARE_HISTORY # adds history incrementally and share it across sessions setopt HIST_IGNORE_ALL_DUPS # don't record dupes in history setopt HIST_REDUCE_BLANKS # don't expand aliases _before_ completion has finished # like: git comm-[tab] setopt complete_aliases bindkey '^[^[[D' backward-word bindkey '^[^[[C' forward-word bindkey '^[[5D' beginning-of-line bindkey '^[[5C' end-of-line bindkey '^[[3~' delete-char bindkey '^?' backward-delete-char ================================================ FILE: zsh/fpath.zsh ================================================ #add each topic folder to fpath so that they can add functions and completion scripts for topic_folder ($ZSH/*) if [ -d $topic_folder ]; then fpath=($topic_folder $fpath); fi; ================================================ FILE: zsh/prompt.zsh ================================================ autoload colors && colors # cheers, @ehrenmurdick # http://github.com/ehrenmurdick/config/blob/master/zsh/prompt.zsh if (( $+commands[git] )) then git="$commands[git]" else git="/usr/bin/git" fi git_branch() { echo $($git symbolic-ref HEAD 2>/dev/null | awk -F/ {'print $NF'}) } git_dirty() { if $(! $git status -s &> /dev/null) then echo "" else if [[ $($git status --porcelain) == "" ]] then echo "on %{$fg_bold[green]%}$(git_prompt_info)%{$reset_color%}" else echo "on %{$fg_bold[red]%}$(git_prompt_info)%{$reset_color%}" fi fi } git_prompt_info () { ref=$($git symbolic-ref HEAD 2>/dev/null) || return # echo "(%{\e[0;33m%}${ref#refs/heads/}%{\e[0m%})" echo "${ref#refs/heads/}" } # This assumes that you always have an origin named `origin`, and that you only # care about one specific origin. If this is not the case, you might want to use # `$git cherry -v @{upstream}` instead. need_push () { if [ $($git rev-parse --is-inside-work-tree 2>/dev/null) ] then number=$($git cherry -v origin/$(git symbolic-ref --short HEAD) 2>/dev/null | wc -l | bc) if [[ $number == 0 ]] then echo " " else echo " with %{$fg_bold[magenta]%}$number unpushed%{$reset_color%}" fi fi } directory_name() { echo "%{$fg_bold[cyan]%}%1/%\/%{$reset_color%}" } battery_status() { if test ! "$(uname)" = "Darwin" then exit 0 fi if [[ $(sysctl -n hw.model) == *"Book"* ]] then $ZSH/bin/battery-status fi } export PROMPT=$'\n$(battery_status)in $(directory_name) $(git_dirty)$(need_push)\n› ' set_prompt () { export RPROMPT="%{$fg_bold[cyan]%}%{$reset_color%}" } precmd() { title "zsh" "%m" "%55<...<%~" set_prompt } ================================================ FILE: zsh/window.zsh ================================================ # From http://dotfiles.org/~_why/.zshrc # Sets the window title nicely no matter where you are function title() { # escape '%' chars in $1, make nonprintables visible a=${(V)1//\%/\%\%} # Truncate command, and join lines. a=$(print -Pn "%40>...>$a" | tr -d "\n") case $TERM in screen) print -Pn "\ek$a:$3\e\\" # screen title (in ^A") ;; xterm*|rxvt) print -Pn "\e]2;$2\a" # plain xterm title ($3 for pwd) ;; esac } ================================================ FILE: zsh/zshrc.symlink ================================================ # shortcut to this dotfiles path is $ZSH export ZSH=$HOME/.dotfiles # your project folder that we can `c [tab]` to export PROJECTS=~/Code # Stash your environment variables in ~/.localrc. This means they'll stay out # of your main dotfiles repository (which may be public, like this one), but # you'll have access to them in your scripts. if [[ -a ~/.localrc ]] then source ~/.localrc fi # all of our zsh files typeset -U config_files config_files=($ZSH/**/*.zsh) # load the path files for file in ${(M)config_files:#*/path.zsh} do source $file done # load everything but the path and completion files for file in ${${config_files:#*/path.zsh}:#*/completion.zsh} do source $file done # initialize autocomplete here, otherwise functions won't be loaded autoload -U compinit compinit # load every completion after autocomplete loads for file in ${(M)config_files:#*/completion.zsh} do source $file done unset config_files