diff --git a/.gitignore b/.gitignore index cca59d62..4e279478 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ vim/bundle/ vimperator/info/ tmp/ +zsh/cache Gemfile.lock diff --git a/zsh/aliases b/zsh/aliases.zsh similarity index 96% rename from zsh/aliases rename to zsh/aliases.zsh index caa79ffe..44fade6c 100644 --- a/zsh/aliases +++ b/zsh/aliases.zsh @@ -13,7 +13,10 @@ alias bru='brew update && brew upgrade --all' # Tools alias codekit='open -a CodeKit' alias ag='nocorrect noglob ag' -alias ln="${aliases[ln]:-ln} -v" # Verbose ln +alias ls="ls -G" +alias l="ls -l" +alias ll="ls -l" +alias ln="ln -v" # Verbose ln alias wget='wget -c' # Resume dl if possible alias rsyncd='rsync -va --delete' # Hard sync two directories zman() { PAGER="less -g -s '+/^ "$1"'" man zshall; } @@ -40,7 +43,6 @@ if is-callable 'transmission-remote'; then fi # Editors -unalias e v() { [ $# -eq 0 ] && vim . || vim $@ } e() { # emacs local input diff --git a/zsh/completion.zsh b/zsh/completion.zsh new file mode 100644 index 00000000..e7087a4f --- /dev/null +++ b/zsh/completion.zsh @@ -0,0 +1,117 @@ +# Return if requirements are not found. +[[ "$TERM" == 'dumb' ]] && return 1 + +# Load and initialize the completion system ignoring insecure directories. +autoload -Uz compinit && compinit -i + +## Options +setopt COMPLETE_IN_WORD # Complete from both ends of a word. +setopt ALWAYS_TO_END # Move cursor to the end of a completed word. +setopt PATH_DIRS # Perform path search even on command names with slashes. +setopt AUTO_MENU # Show completion menu on a successive tab press. +setopt AUTO_LIST # Automatically list choices on ambiguous completion. +setopt AUTO_PARAM_SLASH # If completed parameter is a directory, add a trailing slash. +unsetopt MENU_COMPLETE # Do not autoselect the first completion entry. +unsetopt FLOW_CONTROL # Disable start/stop characters in shell editor. + +# Use caching to make completion for commands such as dpkg and apt usable. +zstyle ':completion::complete:*' use-cache on +zstyle ':completion::complete:*' cache-path "${ZDOTDIR:-$HOME}/.zcompcache" + +# Case-insensitive (all), partial-word, and then substring completion. +zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' +unsetopt CASE_GLOB + +# Group matches and describe. +zstyle ':completion:*:*:*:*:*' menu select +zstyle ':completion:*:matches' group 'yes' +zstyle ':completion:*:options' description 'yes' +zstyle ':completion:*:options' auto-description '%d' +zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f' +zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f' +zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f' +zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f' +zstyle ':completion:*:default' list-prompt '%S%M matches%s' +zstyle ':completion:*' format ' %F{yellow}-- %d --%f' +zstyle ':completion:*' group-name '' +zstyle ':completion:*' verbose yes + +# Fuzzy match mistyped completions. +zstyle ':completion:*' completer _complete _match _approximate +zstyle ':completion:*:match:*' original only +zstyle ':completion:*:approximate:*' max-errors 1 numeric + +# Increase the number of errors based on the length of the typed word. +zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)' + +# Don't complete unavailable commands. +zstyle ':completion:*:functions' ignored-patterns '(_*|pre(cmd|exec))' + +# Array completion element sorting. +zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters + +# Directories +zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} +zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories +zstyle ':completion:*:*:cd:*:directory-stack' menu yes select +zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand' +zstyle ':completion:*' squeeze-slashes true + +# History +zstyle ':completion:*:history-words' stop yes +zstyle ':completion:*:history-words' remove-all-dups yes +zstyle ':completion:*:history-words' list false +zstyle ':completion:*:history-words' menu yes + +# Environmental Variables +zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-} + +# Populate hostname completion. +zstyle -e ':completion:*:hosts' hosts 'reply=( + ${=${=${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) 2>/dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ } + ${=${(f)"$(cat /etc/hosts(|)(N) <<(ypcat hosts 2>/dev/null))"}%%\#*} + ${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2>/dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}} +)' + +# Don't complete uninteresting users... +zstyle ':completion:*:*:*:users' ignored-patterns \ + adm amanda apache avahi beaglidx bin cacti canna clamav daemon \ + dbus distcache dovecot fax ftp games gdm gkrellmd gopher \ + hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \ + mailman mailnull mldonkey mysql nagios \ + named netdump news nfsnobody nobody nscd ntp nut nx openvpn \ + operator pcap postfix postgres privoxy pulse pvm quagga radvd \ + rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs '_*' + +# ... unless we really want to. +zstyle '*' single-ignored show + +# Ignore multiple entries. +zstyle ':completion:*:(rm|kill|diff):*' ignore-line other +zstyle ':completion:*:rm:*' file-patterns '*:all-files' + +# Kill +zstyle ':completion:*:*:*:*:processes' command 'ps -u $LOGNAME -o pid,user,command -w' +zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01' +zstyle ':completion:*:*:kill:*' menu yes select +zstyle ':completion:*:*:kill:*' force-list always +zstyle ':completion:*:*:kill:*' insert-ids single + +# Man +zstyle ':completion:*:manuals' separate-sections true +zstyle ':completion:*:manuals.(^1*)' insert-sections true + +# Media Players +zstyle ':completion:*:*:mpg123:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories' +zstyle ':completion:*:*:mpg321:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories' +zstyle ':completion:*:*:ogg123:*' file-patterns '*.(ogg|OGG|flac):ogg\ files *(-/):directories' +zstyle ':completion:*:*:mocp:*' file-patterns '*.(wav|WAV|mp3|MP3|ogg|OGG|flac):ogg\ files *(-/):directories' + +# SSH/SCP/RSYNC +zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *' +zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr +zstyle ':completion:*:ssh:*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *' +zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr +zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost +zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*' +zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*' diff --git a/zsh/completion/doing.completion.zsh b/zsh/completion/doing.completion.zsh deleted file mode 100644 index a55d42f9..00000000 --- a/zsh/completion/doing.completion.zsh +++ /dev/null @@ -1,151 +0,0 @@ -#compdef doing - -local ret=1 state - -_arguments \ - ':subcommand:->subcommand' \ - '*::options:->options' && ret=0 - -case $state in - subcommand) - local -a subcommands - subcommands=( - 'help:Shows a list of commands or help for one command' - 'now:Add an entry' - 'note:Add a note to the last entry' - 'meanwhile:Finish any running @meanwhile tasks and optionally create a new one' - 'later:Add an item to the Later section' - 'done:Add a completed item with @done(date). No argument finishes last entry.' - 'finish:Mark last X entries as @done' - 'tag:Tag last entry' - 'mark:Mark last entry as highlighted' - 'show:List all entries' - 'grep:Search for entries' - 'recent:List recent entries' - 'today:List entries from today' - 'yesterday:List entries from yesterday' - 'last:Show the last entry' - 'sections:List sections' - 'choose:Select a section to display from a menu' - 'add_section:Add a new section to the "doing" file' - 'view:Display a user-created view' - 'views:List available custom views' - 'archive:Move entries in between sections' - 'open:Open the "doing" file in an editor' - 'config:Edit the configuration file' - 'undo:Undo the last change to the doing_file' - ) - _describe -t subcommands 'doing subcommand' subcommands && ret=0 - ;; - - options) - age=({-a,--age=}"[Age (oldest/newest) (default: newest)]") - app=({-a,--app=}"[Edit entry with specified app (default: none)") - archive=({-a,--archive}"[Archive previous @meanwhile entry]") - back="--back=[Backdate start time (4pm|20m|2h|yesterday noon) (default: none)]" - boolean=({-b,--boolean=}"[Tag boolean (AND,OR,NONE) (default: OR)]") - bool=({-b,--bool=}"[Tag boolean (default: AND)]") - count=({-c,--count=}"[How many recent entries to tag (default: 1)]") - count=({-c,--count=}"[Max count to show (default: 0)]") - date=({-d,--date}"[Include date (default: enabled)]") - editor=( {-e,--editor}"[Edit entry with $EDITOR]") - finish=({-f,--finish_last}"[Timed entry, marks last entry in section as @done]") - file=({-f,--file=}"[Specify alternate doing file (default: none)]") - noarchive="--no-archive[Don't archive previous @meanwhile entry]" - nodate="--no-date[Don't include date]" - noeditor="--no-editor[Don't edit entry with $EDITOR]" - note=({-n,--note=}"[Note (default: none)]") - notimes="--no-times[Don't show time intervals on @done tasks.]" - nototals="--no-totals[Don't show intervals with totals at the end of output]" - output=({-o,--output=}"[Output to export format (csv|html) (default: none)]") - remove=({-r,--remove}"[Replace/Remove last entry's note]") - section=({-s,--section=}"[Section (default: Currently)]") - sort=({-s,--sort=}"[Sort order (asc/desc) (default: asc)]") - times=({-t,--times}"[Show time intervals on @done tasks (default: enabled)]") - took=({-t,--took=}"[Set completion date to start date plus XX(mhd) or (HH:MM) (default: none)]") - totals="--totals[Show intervals with totals at the end of output]" - - case $words[1] in - now) - args=( $back $noeditor $editor $note $section $finish ) - ;; - - note) - args=( $section $editor $remove ) - ;; - - meanwhile) - args=( $back $noeditor $editor $note $section $archive $noarchive ) - ;; - - later) - args=( $back $noeditor $editor $note $app ) - ;; - - done) - args=( $back $took $section {-r,--remove}"[Remove @done tag]" $date $nodate $archive $editor $noeditor ) - ;; - - finish) - args=( $back $took $section $date $nodate $archive $editor $noeditor ) - ;; - - tag) - args=( $section $count $date $remove ) - ;; - - mark) - args=( $section $remove ) - ;; - - show) - args=( $boolean $count $age $sort $output $times $notimes $totals $nototals ) - ;; - - grep) - args=( $section $output $times $notimes $totals $nototals ) - ;; - - recent) - args=( $section $times $notimes $totals $nototals ) - ;; - - today) - args=( $output $times $notimes $totals $nototals ) - ;; - - yesterday) - args=( $output $times $notimes $totals $nototals ) - ;; - - view) - args=( $section $count $output $times $notimes $totals $nototals ) - ;; - - archive) - args=( $keep $to $bool ) - ;; - - open) - args=( - "-a [open with app name (default:none)" - "-b [open with app bundle id (default: none)" - "-e [open with $EDITOR]" - ) - ;; - - config) - args=( $editor ) - ;; - - undo) - args=( $file ) - ;; - - esac - - _arguments $args && ret=0 - ;; -esac - -return ret diff --git a/zsh/config.zsh b/zsh/config.zsh new file mode 100644 index 00000000..7402984b --- /dev/null +++ b/zsh/config.zsh @@ -0,0 +1,25 @@ +# Allow command line editing in an external editor. +autoload -Uz edit-command-line +zle -N edit-command-line + +export GIT_MERGE_AUTOEDIT=no +unsetopt CORRECT_ALL + +setopt append_history share_history extended_history +setopt histignorealldups histignorespace +setopt extended_glob +setopt longlistjobs +setopt nonomatch +setopt notify +setopt hash_list_all + +# Don't send SIGHUP to background processes when the shell exits. +setopt nohup + +setopt auto_cd +setopt auto_pushd +setopt pushd_ignore_dups +setopt nobeep +setopt noglobdots +setopt noshwordsplit +setopt unset diff --git a/zsh/config b/zsh/keybinds.zsh similarity index 54% rename from zsh/config rename to zsh/keybinds.zsh index a385495d..8d0e4c8e 100644 --- a/zsh/config +++ b/zsh/keybinds.zsh @@ -1,26 +1,44 @@ -export GIT_MERGE_AUTOEDIT=no -unsetopt CORRECT_ALL - - -################# -# Keybindings # -################# - bindkey -v bindkey '^ ' edit-command-line bindkey -M viins '^w' backward-kill-word -bindkey -M viins '^a' beginning-of-line -bindkey -M viins '^e' end-of-line bindkey -M viins '^[w' forward-word bindkey -M viins '^[b' backward-word +bindkey -M vicmd 'yy' vi-yank-whole-line +bindkey -M vicmd 'Y' vi-yank-eol + +bindkey -M vicmd '^r' redo + bindkey -M viins ' ' magic-space bindkey -M viins 'jk' vi-cmd-mode bindkey -M viins '^x^f' fasd-complete-f # C-x C-f to do fasd-complete-f (only files) bindkey -M viins '^x^d' fasd-complete-d # C-x C-d to do fasd-complete-d (only directories) +bindkey -M viins '^q' push-line-or-edit + +bindkey -M vicmd "?" history-incremental-pattern-search-backward +bindkey -M vicmd "/" history-incremental-pattern-search-forward + +# bind UP and DOWN arrow keys +zmodload zsh/terminfo +bindkey "$terminfo[kcuu1]" history-substring-search-up +bindkey "$terminfo[kcud1]" history-substring-search-down +# bind UP and DOWN arrow keys (compatibility fallback +# for Ubuntu 12.04, Fedora 21, and MacOSX 10.9 users) +bindkey '^[[A' history-substring-search-up +bindkey '^[[B' history-substring-search-down]]]] + +# Edit command in an external editor. +bindkey -M vicmd "v" edit-command-line + +# # Undo/Redo +bindkey -M vicmd "u" undo +bindkey -M vicmd "$key_info[Control]R" redo + +bindkey -M viins "." expand-dot-to-parent-directory-path + # Completing words in buffer in tmux if [ -n "$TMUX" ]; then _tmux_pane_words() { @@ -44,3 +62,13 @@ if [ -n "$TMUX" ]; then zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' ignore-line current zstyle ':completion:tmux-pane-words-anywhere:*' matcher-list 'b:=* m:{A-Za-z}={a-zA-Z}' fi + +# Expands .... to ../.. +function expand-dot-to-parent-directory-path { + if [[ $LBUFFER = *.. ]]; then + LBUFFER+='/..' + else + LBUFFER+='.' + fi +} +zle -N expand-dot-to-parent-directory-path diff --git a/zsh/preztorc b/zsh/preztorc deleted file mode 100644 index 36e30724..00000000 --- a/zsh/preztorc +++ /dev/null @@ -1,111 +0,0 @@ -# Sets Prezto options. - -[[ -s "${ZDOTDIR:-$HOME}/.zprezto/init.zsh" ]] -source "${ZDOTDIR:-$HOME}/.zprezto/init.zsh" - -# General - -zstyle ':prezto:module:prompt' theme 'pure' - -# Set case-sensitivity for completion, history lookup, etc. -# zstyle ':prezto:*:*' case-sensitive 'yes' - -# Color output (auto set to 'no' on dumb terminals). -zstyle ':prezto:*:*' color 'yes' - -# Set the Zsh modules to load (man zshmodules). -# zstyle ':prezto:load' zmodule 'attr' 'stat' - -# Set the Zsh functions to load (man zshcontrib). -zstyle ':prezto:load' zfunction 'zmv' - -# Set the Prezto modules to load (browse modules). -# The order matters. -if [[ -z "$EMACS" ]]; then - zstyle ':prezto:load' pmodule \ - 'environment' \ - 'terminal' \ - 'editor' \ - 'opp' \ - 'history' \ - 'history-substring-search' \ - 'directory' \ - 'spectrum' \ - 'utility' \ - 'completion' \ - 'prompt' \ - 'syntax-highlighting' \ - 'git' \ - 'osx' -else - zstyle ':prezto:load' pmodule \ - 'environment' \ - 'history' \ - 'directory' \ - 'spectrum' \ - 'utility' \ - 'git' \ - 'osx' -fi - - -# Editor - -# Set the key mapping style to 'emacs' or 'vi'. -zstyle ':prezto:module:editor' key-bindings 'vi' - -# Auto convert .... to ../.. -zstyle ':prezto:module:editor' dot-expansion 'yes' - - -# Git - -# Ignore submodules when they are 'dirty', 'untracked', 'all', or 'none'. -zstyle ':prezto:module:git:status:ignore' submodules 'all' - - -# GNU Utility - -# Set the command prefix on non-GNU systems. -# zstyle ':prezto:module:gnu-utility' prefix 'g' - - -# History Substring Search - -# Set the query found color. -# zstyle ':prezto:module:history-substring-search:color' found '' - -# Set the query not found color. -# zstyle ':prezto:module:history-substring-search:color' not-found '' - -# Set the search globbing flags. -# zstyle ':prezto:module:history-substring-search' globbing-flags '' - - -# SSH - -# Set the SSH identities to load into the agent. -zstyle ':prezto:module:ssh:load' identities 'id_rsa' 'id_rsa2' 'id_github' - - -# Syntax Highlighting - -# Set syntax highlighters. -# By default, only the main highlighter is enabled. -zstyle ':prezto:module:syntax-highlighting' highlighters \ - 'main' \ - 'brackets' \ - 'pattern' \ - 'cursor' \ - 'root' - -# Terminal - -# Auto set the tab and window titles. -zstyle ':prezto:module:terminal' auto-title 'yes' - -# Set the window title format. -# zstyle ':prezto:module:terminal:window-title' format '%n@%m: %s' - -# Set the tab title format. -# zstyle ':prezto:module:terminal:tab-title' format '%m: %s' diff --git a/zsh/prompt.zsh b/zsh/prompt.zsh new file mode 100644 index 00000000..9cd1ec2c --- /dev/null +++ b/zsh/prompt.zsh @@ -0,0 +1,132 @@ +# Based off Pure + +# For my own and others sanity +# git: +# %b => current branch +# %a => current action (rebase/merge) +# prompt: +# %F => color dict +# %f => reset color +# %~ => current path +# %* => time +# %n => username +# %m => shortname host +# %(?..) => prompt conditional - %(condition.true.false) + +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +prompt_pure_human_time() { + echo -n " " + local tmp=$1 + local days=$(( tmp / 60 / 60 / 24 )) + local hours=$(( tmp / 60 / 60 % 24 )) + local minutes=$(( tmp / 60 % 60 )) + local seconds=$(( tmp % 60 )) + (( $days > 0 )) && echo -n "${days}d " + (( $hours > 0 )) && echo -n "${hours}h " + (( $minutes > 0 )) && echo -n "${minutes}m " + echo "${seconds}s" +} + +# fastest possible way to check if repo is dirty +prompt_pure_git_dirty() { + # check if we're in a git repo + [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] || return + # check if it's dirty + [[ "$PURE_GIT_UNTRACKED_DIRTY" == 0 ]] && local umode="-uno" || local umode="-unormal" + command test -n "$(git status --porcelain --ignore-submodules ${umode})" + + (($? == 0)) && echo '*' +} + +# displays the exec time of the last command if set threshold was exceeded +prompt_pure_cmd_exec_time() { + local stop=$EPOCHSECONDS + local start=${cmd_timestamp:-$stop} + integer elapsed=$stop-$start + (($elapsed > ${PURE_CMD_MAX_EXEC_TIME:=5})) && prompt_pure_human_time $elapsed +} + +prompt_pure_preexec() { + cmd_timestamp=$EPOCHSECONDS + + # shows the current dir and executed command in the title when a process is active + print -Pn "\e]0;" + echo -nE "$PWD:t: $2" + print -Pn "\a" +} + +# string length ignoring ansi escapes +prompt_pure_string_length() { + # Subtract one since newline is counted as two characters + echo $(( ${#${(S%%)1//(\%([KF1]|)\{*\}|\%[Bbkf])}} - 1 )) +} + +prompt_pure_precmd() { + # shows the full path in the title + print -Pn '\e]0;%~\a' + + # git info + vcs_info + + local prompt_pure_preprompt="%F{blue}%~%F{242}$vcs_info_msg_0_`prompt_pure_git_dirty`$prompt_pure_username%f%F{yellow}`prompt_pure_cmd_exec_time`%f"'$(vi_mode_prompt_info)' + # print -P $prompt_pure_preprompt + RPROMPT=$prompt_pure_preprompt + + # check async if there is anything to pull + (( ${PURE_GIT_PULL:-1} )) && { + # check if we're in a git repo + [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] && + # make sure working tree is not $HOME + [[ "$(command git rev-parse --show-toplevel)" != "$HOME" ]] && + # check check if there is anything to pull + command git -c gc.auto=0 fetch &>/dev/null && + # check if there is an upstream configured for this branch + command git rev-parse --abbrev-ref @'{u}' &>/dev/null && { + local arrows='' + (( $(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows='⇣' + (( $(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows+='⇡' + RPROMPT+="\e7\e[A\e[1G\e[`prompt_pure_string_length $prompt_pure_preprompt`C%F{cyan}${arrows}%f\e8" + } + } &! + + # reset value since `preexec` isn't always triggered + unset cmd_timestamp +} + +prompt_pure_setup() { + # prevent percentage showing up + # if output doesn't end with a newline + export PROMPT_EOL_MARK='' + + # disable auth prompting on git 2.3+ + export GIT_TERMINAL_PROMPT=0 + + prompt_opts=(cr subst percent) + + setopt PROMPTSUBST + zmodload zsh/datetime + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + add-zsh-hook precmd prompt_pure_precmd + add-zsh-hook preexec prompt_pure_preexec + + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:*' use-simple true + zstyle ':vcs_info:git*' formats ' %b' + zstyle ':vcs_info:git*' actionformats ' %b|%a' + + # show username@host if logged in through SSH + [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username=' %n@%m' + + # show username@host if root, with username in white + [[ $UID -eq 0 ]] && prompt_pure_username=' %F{white}%n%F{242}@%m' + + # prompt turns red if the previous command didn't exit with 0 + N_MODE=" --NORMAL--" + I_MODE="" + PROMPT='%(?.%F{green}.%F{red}❯%F{green})❯ %f' +} + +prompt_pure_setup "$@" diff --git a/zsh/prompts/prompt_pure_setup b/zsh/prompts/prompt_pure_setup deleted file mode 100644 index c59e4b8a..00000000 --- a/zsh/prompts/prompt_pure_setup +++ /dev/null @@ -1,133 +0,0 @@ -# Based off Pure - -# For my own and others sanity -# git: -# %b => current branch -# %a => current action (rebase/merge) -# prompt: -# %F => color dict -# %f => reset color -# %~ => current path -# %* => time -# %n => username -# %m => shortname host -# %(?..) => prompt conditional - %(condition.true.false) - -# turns seconds into human readable time -# 165392 => 1d 21h 56m 32s -prompt_pure_human_time() { - echo -n " " - local tmp=$1 - local days=$(( tmp / 60 / 60 / 24 )) - local hours=$(( tmp / 60 / 60 % 24 )) - local minutes=$(( tmp / 60 % 60 )) - local seconds=$(( tmp % 60 )) - (( $days > 0 )) && echo -n "${days}d " - (( $hours > 0 )) && echo -n "${hours}h " - (( $minutes > 0 )) && echo -n "${minutes}m " - echo "${seconds}s" -} - -# fastest possible way to check if repo is dirty -prompt_pure_git_dirty() { - # check if we're in a git repo - [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] || return - # check if it's dirty - [[ "$PURE_GIT_UNTRACKED_DIRTY" == 0 ]] && local umode="-uno" || local umode="-unormal" - command test -n "$(git status --porcelain --ignore-submodules ${umode})" - - (($? == 0)) && echo '*' -} - -# displays the exec time of the last command if set threshold was exceeded -prompt_pure_cmd_exec_time() { - local stop=$EPOCHSECONDS - local start=${cmd_timestamp:-$stop} - integer elapsed=$stop-$start - (($elapsed > ${PURE_CMD_MAX_EXEC_TIME:=5})) && prompt_pure_human_time $elapsed -} - -prompt_pure_preexec() { - cmd_timestamp=$EPOCHSECONDS - - # shows the current dir and executed command in the title when a process is active - print -Pn "\e]0;" - echo -nE "$PWD:t: $2" - print -Pn "\a" -} - -# string length ignoring ansi escapes -prompt_pure_string_length() { - # Subtract one since newline is counted as two characters - echo $(( ${#${(S%%)1//(\%([KF1]|)\{*\}|\%[Bbkf])}} - 1 )) -} - -prompt_pure_precmd() { - # shows the full path in the title - print -Pn '\e]0;%~\a' - - # git info - vcs_info - - local prompt_pure_preprompt="%F{blue}%~%F{242}$vcs_info_msg_0_`prompt_pure_git_dirty`$prompt_pure_username%f%F{yellow}`prompt_pure_cmd_exec_time`%f" - # print -P $prompt_pure_preprompt - RPROMPT=$prompt_pure_preprompt - - # check async if there is anything to pull - (( ${PURE_GIT_PULL:-1} )) && { - # check if we're in a git repo - [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]] && - # make sure working tree is not $HOME - [[ "$(command git rev-parse --show-toplevel)" != "$HOME" ]] && - # check check if there is anything to pull - command git -c gc.auto=0 fetch &>/dev/null && - # check if there is an upstream configured for this branch - command git rev-parse --abbrev-ref @'{u}' &>/dev/null && { - local arrows='' - (( $(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows='⇣' - (( $(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows+='⇡' - RPROMPT+="\e7\e[A\e[1G\e[`prompt_pure_string_length $prompt_pure_preprompt`C%F{cyan}${arrows}%f\e8" - } - } &! - - # reset value since `preexec` isn't always triggered - unset cmd_timestamp -} - -prompt_pure_setup() { - # prevent percentage showing up - # if output doesn't end with a newline - export PROMPT_EOL_MARK='' - - # disable auth prompting on git 2.3+ - export GIT_TERMINAL_PROMPT=0 - - prompt_opts=(cr subst percent) - - zmodload zsh/datetime - autoload -Uz add-zsh-hook - autoload -Uz vcs_info - - add-zsh-hook precmd prompt_pure_precmd - add-zsh-hook preexec prompt_pure_preexec - - zstyle ':vcs_info:*' enable git - zstyle ':vcs_info:*' use-simple true - zstyle ':vcs_info:git*' formats ' %b' - zstyle ':vcs_info:git*' actionformats ' %b|%a' - - # show username@host if logged in through SSH - [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username=' %n@%m' - - # show username@host if root, with username in white - [[ $UID -eq 0 ]] && prompt_pure_username=' %F{white}%n%F{242}@%m' - - zstyle ':prezto:module:editor:info:keymap:primary' format "❯%f" - zstyle ':prezto:module:editor:info:keymap:alternate' format "#%f" - - # prompt turns red if the previous command didn't exit with 0 - PROMPT=' -%(?.%F{green}.%F{red}❯%F{green})${editor_info[keymap]} ' -} - -prompt_pure_setup "$@" diff --git a/zsh/prompts/prompt_v0_setup b/zsh/prompts/prompt_v0_setup deleted file mode 100644 index 63c010ef..00000000 --- a/zsh/prompts/prompt_v0_setup +++ /dev/null @@ -1,61 +0,0 @@ -# -# A simple theme based off sorin -# - -# Load dependencies. -pmodload 'helper' - -# Show the hostname if this is an SSH session -if [ ! -z "$SSH_CLIENT" ]; then - __prompt_host="%B%F{blue}[$(hostname | sed -e 's/\.local$//')]%f%b " -fi - -function _prompt_pwd { - local pwd="${PWD/#$HOME/~}" - - if [[ "$pwd" == (#m)[/~] ]]; then - __prompt_pwd="$MATCH" - unset MATCH - else - __prompt_pwd="${${${(@j:/:M)${(@s:/:)pwd}##.#?}:h}%/}/${pwd:t}" - fi -} - -# Why not use prezto's git module? Because git-info seems like overkill. -function _prompt_git { - __prompt_git=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) - if [[ -n "$__prompt_git" ]]; then - __prompt_git=" :%F{yellow}$__prompt_git" - if ! git -c diff.autorefreshindex=true diff --quiet -- .; then - __prompt_git+="%F{white}+" - fi - fi -} - -function prompt_v0_setup { - setopt LOCAL_OPTIONS - unsetopt XTRACE KSH_ARRAYS - prompt_opts=(cr percent subst) - - # Load required functions. - autoload -Uz add-zsh-hook - - # Add hook for calling git-info before each command. - add-zsh-hook precmd _prompt_git - add-zsh-hook precmd _prompt_pwd - - # Set editor-info parameters. - zstyle ':prezto:module:editor:info:completing' format '%B%F{red}...%f%b' - zstyle ':prezto:module:editor:info:keymap:primary' format '%B%F{red}❯%f%b' - zstyle ':prezto:module:editor:info:keymap:primary:overwrite' format '%F{red}♺%f' - zstyle ':prezto:module:editor:info:keymap:alternate' format '%B%F{green}❯%f%b' - - # Add newline before prompt - precmd() { print "" } - - # Define prompts. - PROMPT='${__prompt_host}%F{cyan}${__prompt_pwd} ${editor_info[keymap]} ' - RPROMPT='%F{yellow}${__prompt_git:- }' -} - -prompt_v0_setup "$@" diff --git a/zsh/zgen b/zsh/zgen new file mode 160000 index 00000000..5517f92a --- /dev/null +++ b/zsh/zgen @@ -0,0 +1 @@ +Subproject commit 5517f92ae5658d05c555225490cc4bede12db00b diff --git a/zshrc b/zshrc index 63400dfc..6d53a31d 100644 --- a/zshrc +++ b/zshrc @@ -1,20 +1,38 @@ -# Source Prezto. -if [[ -s "${ZDOTDIR:-$HOME}/.zprezto/init.zsh" ]]; then - source ~/.zsh/preztorc - source "${ZDOTDIR:-$HOME}/.zprezto/init.zsh" -else - echo "Prezto isn't installed! Run ~/.dotfiles/install.sh" - exit 1 -fi - -source ~/.zsh/aliases +function is-callable { + (( $+commands[$1] )) || (( $+functions[$1] )) || (( $+aliases[$1] )) +} # Source component rcfiles if [[ -z "$EMACS" ]]; then - source ~/.zsh/config - is-callable 'fasd' && eval "$(fasd --init auto)" + source ~/.zsh/zgen/zgen.zsh + if ! zgen saved; then + echo "Creating zgen save" + + zgen load zsh-users/zsh-syntax-highlighting + zgen load zsh-users/zsh-history-substring-search + zgen load zsh-users/zsh-completions src + zgen load clvv/fasd + zgen load hchbaw/opp.zsh + zgen load Tarrasch/zsh-bd + zgen load houjunchen/zsh-vim-mode + + zgen save + fi + + source ~/.zsh/aliases.zsh + source ~/.zsh/config.zsh + source ~/.zsh/keybinds.zsh + source ~/.zsh/prompt.zsh + + fasd_cache="$HOME/.fasd-cache" + if [ "$(command -v fasd)" -nt "$fasd_cache" -o ! -s "$fasd_cache" ]; then + fasd --init posix-alias zsh-hook zsh-ccomp zsh-ccomp-install >| "$fasd_cache" + fi + source "$fasd_cache" + unset fasd_cache fi +## PATHS ############################################### if [ -d ~/.rbenv ]; then export PATH=~/.rbenv/bin:$PATH eval "$(rbenv init - --no-rehash)"