diff --git a/.gitignore b/.gitignore index 31cc75cb9..fb1de5bb1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -locals.zsh -log/.zsh_history -projects.zsh -cache +*.zwc +*.zwc.old +plugins/*/cache.zsh diff --git a/.gitmodules b/.gitmodules index 0773e109c..ee195ba26 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "plugins/zsh-history-substring-search"] path = plugins/zsh-history-substring-search url = git://github.com/sunaku/zsh-history-substring-search.git +[submodule "completions"] + path = completions + url = https://github.com/zsh-users/zsh-completions.git diff --git a/README.md b/README.md new file mode 100644 index 000000000..e65dff8c4 --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# Oh My Zsh + +OMZ is a configuration framework for [Zsh](http://www.zsh.org) that enriches +the command line interface environment with sane defaults, aliases, functions, +auto completion, and prompt themes. + +## Installation + +Oh My Zsh will work with any recent release of Zsh, but the minimum recommended +version is 4.3.10. + +1. Clone the repository: + + `git clone https://github.com/sorin-ionescu/oh-my-zsh.git ~/.oh-my-zsh` + +2. Initialize the submodules: + + `git submodule update --init --recursive` + +3. Create a new Zsh configuration by copying the Zsh template provided: + + `cp ~/.oh-my-zsh/templates/zshrc.zsh ~/.zshrc` + +4. Set Zsh as your default shell: + + `chsh -s /bin/zsh` + +5. Open a new Zsh terminal window or tab. + +### Mac OS X + +If you have administrator privileges, you must fix an Apple miss configuration +in Mac OS X 10.7 Lion by renaming `/etc/zshenv` to `/etc/zprofile`, or Zsh will +have the wrong `PATH` when executed non-interactively by scripts. + +### Troubleshooting + +If you are not able to find certain commands after switching to *Oh My Zsh*, +modify the `PATH` variable in `environment.zsh` then open a new Zsh terminal +window or tab. + +## Usage + +Oh My Zsh has many features disabled by default. Read the source code and +accompanying README files to learn of what is available. + +### Plugins + +1. Browse `plugins/` to see what is available. +2. Load the plugins you need in `~/.zshrc` then open a new Zsh terminal window + or tab. + +### Themes + +1. For a list of themes, type `prompt -l`. +2. To preview a theme, type `prompt -p name`. +3. Load the theme you like in `~/.zshrc` then open a new Zsh terminal window or + tab. + ![sorin theme](http://i.imgur.com/aipDQ.png "sorin theme") + +## Customization + +The project is managed via [Git](http://git-scm.com). It is highly recommend +that you commit your changes and push them to [GitHub](http://github.com) to +not lose them. If you do not know how to use Git, follow this +[tutorial](http://gitimmersion.com) and bookmark this +[reference](http://gitref.org). + +### Completions + +Submit program completions to the +[zsh-completions](https://github.com/zsh-users/zsh-completions) project. The Oh +My Zsh completions directory will be synched against it. + +## Resources + +The [Zsh Reference Card](http://www.bash2zsh.com/zsh_refcard/refcard.pdf) is +indispensable. + +## Contribute + +This project would not exist without all of its users and +[contributors](https://github.com/sorin-ionescu/oh-my-zsh/contributors). + +If you have ideas on how to make the configuration easier to maintain or +improve its performance, do not hesitate to fork and send pull requests. + +## License + +(The MIT License) + +Copyright (c) 2009-2012 Robby Russell, Sorin Ionescu, and contributors. + +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. + diff --git a/README.textile b/README.textile index c176540fd..e69de29bb 100644 --- a/README.textile +++ b/README.textile @@ -1,55 +0,0 @@ -A handful of functions, auto-complete helpers, and stuff that makes you shout... - -bq. "OH MY ZSHELL!" - -h2. Setup - -@oh-my-zsh@ should work with any recent release of "zsh":http://www.zsh.org/, the minimum recommended version is 4.3.9. - -1. Clone the repository - - @git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh@ - -2. Create a new zsh config by copying the zsh template we've provided. - - *NOTE*: If you already have a ~/.zshrc file, you should back it up. @cp ~/.zshrc ~/.zshrc.orig@ in case you want to go back to your original settings. - - @cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc@ - -3. Set zsh as your default shell: - - @chsh -s /bin/zsh@ - -4. Start / restart zsh (open a new terminal is easy enough...) - -h3. Problems? - -You _might_ need to modify your PATH in ~/.zshrc if you're not able to find some commands after switching to _Oh My Zsh_. - -h2. Usage - -* enable the plugins you want in your @~/.zshrc@ (take a look at @plugins/@ to see what's possible) -** example: @plugins=(git osx ruby)@ -* Theme support: Change the @ZSH_THEME@ environment variable in @~/.zshrc@. -** Take a look at the "current themes":https://wiki.github.com/robbyrussell/oh-my-zsh/themes that come bundled with _Oh My Zsh_. -* much much more... take a look at @lib/@ what _Oh My Zsh_ offers... - -h2. Useful - -the "refcard":http://www.bash2zsh.com/zsh_refcard/refcard.pdf is pretty tasty for tips. - -h3. Customization - -If you have many functions which go good together you can put them as a *.plugin.zsh file in the @custom/plugins/@ directory and then enable this plugin. - -h2. Help out! - -I'm far from being a zsh-expert and suspect there are many ways to improve. If you have ideas on how to make the configuration easier to maintain (and faster), don't hesitate to fork and send pull requests! - -h2. Contributors - -This project wouldn't exist without all of our awesome users and contributors. - -* "View our growing list of contributors":https://github.com/robbyrussell/oh-my-zsh/contributors - -Thank you so much! diff --git a/alias.zsh b/alias.zsh new file mode 100644 index 000000000..38499d5d4 --- /dev/null +++ b/alias.zsh @@ -0,0 +1,130 @@ +# +# Defines general aliases. +# +# Authors: +# Sorin Ionescu +# + +setopt CORRECT # Correct commands. + +# The 'ls' Family +if zstyle -t ':omz:alias:ls' color; then + if [[ -f "$HOME/.dir_colors" ]] && (( $+commands[dircolors] )); then + eval $(dircolors "$HOME/.dir_colors") + alias ls='ls -hF --group-directories-first --color=auto' + else + export CLICOLOR=1 + export LSCOLORS="exfxcxdxbxegedabagacad" + alias ls='ls -G -F' + fi +fi + +alias l='ls -1A' # Show files in one column. +alias ll='ls -lh' # Show human readable. +alias la='ls -lhA' # Show hidden files. +alias lx='ls -lhXB' # Sort by extension. +alias lk='ls -lhSr' # Sort by size, biggest last. +alias lc='ls -lhtcr' # Sort by and show change time, most recent last. +alias lu='ls -lhtur' # Sort by and show access time, most recent last. +alias lt='ls -lhtr' # Sort by date, most recent last. +alias lm='ls -lha | more' # Pipe through 'more'. +alias lr='ls -lhR' # Recursive ls. +alias sl='ls' # I often screw this up. + +# General +alias _='sudo' +alias b="$BROWSER" +alias cd='nocorrect cd' +alias cp='nocorrect cp -i' +alias df='df -kh' +alias du='du -kh' +alias e="$EDITOR" +alias find='noglob find' +alias fc='noglob fc' +alias gcc='nocorrect gcc' +alias history='noglob history' +alias ln='nocorrect ln -i' +alias locate='noglob locate' +alias man='nocorrect man' +alias mkdir='nocorrect mkdir -p' +alias mv='nocorrect mv -i' +alias p="$PAGER" +alias po='popd' +alias pu='pushd' +alias rake='noglob rake' +alias rm='nocorrect rm -i' +alias scp='nocorrect scp' +alias type='type -a' + +# Mac OS X +if [[ "$OSTYPE" != darwin* ]]; then + alias open='xdg-open' + alias get='wget --continue --progress=bar' + + if (( $+commands[xclip] )); then + alias pbcopy='xclip -selection clipboard -in' + alias pbpaste='xclip -selection clipboard -out' + fi + + if (( $+commands[xsel] )); then + alias pbcopy='xsel --clipboard --input' + alias pbpaste='xsel --clipboard --output' + fi +else + alias get='curl --continue-at - --location --progress-bar --remote-name' +fi + +alias o='open' +alias pbc='pbcopy' +alias pbp='pbpaste' + +# Top +if (( $+commands[htop] )); then + alias top=htop +else + alias topm='top -o vsize' + alias topc='top -o cpu' +fi + +# Diff/Make +if zstyle -t ':omz:alias:diff' color; then + function diff() { + if (( $+commands[colordiff] )); then + "$commands[diff]" --unified "$@" | colordiff --difftype diffu + elif (( $+commands[git] )); then + git --no-pager diff --color=auto --no-ext-diff --no-index "$@" + else + "$commands[diff]" --unified "$@" + fi + } + + function wdiff() { + if (( $+commands[wdiff] )); then + "$commands[wdiff]" \ + --avoid-wraps \ + --start-delete="$(print -n $FG[red])" \ + --end-delete="$(print -n $FG[none])" \ + --start-insert="$(print -n $FG[green])" \ + --end-insert="$(print -n $FG[none])" \ + "$@" \ + | sed 's/^\(@@\( [+-][[:digit:]]*,[[:digit:]]*\)\{2\} @@\)$/;5;6m\10m/g' + elif (( $+commands[git] )); then + git --no-pager diff --color=auto --no-ext-diff --no-index --color-words "$@" + else + print "zsh: command not found: $0" >&2 + fi + } + + if (( $+commands[colormake] )); then + alias make='colormake' + compdef colormake=make + fi +fi + +# Miscellaneous +(( $+commands[ack] )) && alias afind='nocorrect ack' +(( $+commands[ebuild] )) && alias ebuild='nocorrect ebuild' +(( $+commands[gist] )) && alias gist='nocorrect gist' +(( $+commands[heroku] )) && alias heroku='nocorrect heroku' +(( $+commands[mysql] )) && alias mysql='nocorrect mysql' + diff --git a/completion.zsh b/completion.zsh new file mode 100644 index 000000000..02d256107 --- /dev/null +++ b/completion.zsh @@ -0,0 +1,138 @@ +# +# Sets completion options. +# +# Authors: +# Robby Russell +# Sorin Ionescu +# + +# Dumb terminals lack support. +if [[ "$TERM" == 'dumb' ]]; then + return +fi + +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 succesive 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. + +# Treat these characters as part of a word. +WORDCHARS='*?_-.[]~&;!#$%^(){}<>' + +# Use caching to make completion for cammands such as dpkg and apt usable. +zstyle ':completion::complete:*' use-cache on +zstyle ':completion::complete:*' cache-path "$HOME/.zcache" + +# Case-insensitive (all), partial-word, and then substring completion. +if zstyle -t ':omz:completion:*' case-sensitive; then + zstyle ':completion:*' matcher-list 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' + setopt CASE_GLOB +else + zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' + unsetopt CASE_GLOB +fi + +# 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:*' 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)"}%%[#| ]*}//,/ } + ${=${(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 yes +zstyle ':completion:*:rm:*' file-patterns '*:all-files' + +# Kill +zstyle ':completion:*:*:*:*:processes' command 'ps -u $USER -o pid,user,comm -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' + +# Mutt +if [[ -f ~/.mutt/aliases ]]; then + zstyle ':completion:*:*:mutt:*' menu yes select + zstyle ':completion:*:mutt:*' users ${${${(f)"$(<~/.mutt/aliases)"}#alias[[:space:]]}%%[[:space:]]*} +fi + +# SSH/SCP/RSYNC +zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-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 users 'hosts:-host hosts:-domain:domain hosts:-ipaddr:ip\ address *' +zstyle ':completion:*:ssh:*' group-order hosts-domain hosts-host users hosts-ipaddr +zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*.*' loopback localhost +zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^*.*' '*@*' +zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^<->.<->.<->.<->' '127.0.0.<->' + diff --git a/completions b/completions new file mode 160000 index 000000000..4009c2ace --- /dev/null +++ b/completions @@ -0,0 +1 @@ +Subproject commit 4009c2ace429c58d9eeaf1f21a8501d537d2f258 diff --git a/directory.zsh b/directory.zsh new file mode 100644 index 000000000..322dee077 --- /dev/null +++ b/directory.zsh @@ -0,0 +1,26 @@ +# +# Sets directory options and defines directory aliases. +# +# Authors: +# James Cox +# Sorin Ionescu +# + +setopt AUTO_CD # Auto cd to a directory without typing cd. +setopt AUTO_PUSHD # Push the old directory onto the stack on cd. +setopt PUSHD_IGNORE_DUPS # Don't store duplicates in the stack. +setopt PUSHD_SILENT # Do not print the directory stack after pushd or popd. +setopt PUSHD_TO_HOME # Push to home directory when no argument is given. +setopt CDABLE_VARS # Change directory to a path stored in a variable. +setopt AUTO_NAME_DIRS # Auto add variable-stored paths to ~ list. +setopt MULTIOS # Write to multiple descriptors. +setopt EXTENDED_GLOB # Use extended globbing syntax. +unsetopt CLOBBER # Don't overwrite existing files with > and >>. + # Use >! and >>! to bypass. + +# Aliases +for index in {1..9}; do + alias "$index"="cd +${index}" +done +unset index + diff --git a/environment.zsh b/environment.zsh new file mode 100644 index 000000000..d00d7a50b --- /dev/null +++ b/environment.zsh @@ -0,0 +1,107 @@ +# +# Sets general shell options and defines environment variables. +# +# Authors: +# Sorin Ionescu +# + +# Smart URLs +autoload -Uz url-quote-magic +zle -N self-insert url-quote-magic + +# General +setopt RC_QUOTES # Allow 'Henry''s Garage' instead of 'Henry'\''s Garage'. +unsetopt MAIL_WARNING # Don't print a warning message if a mail file has been accessed + +# Jobs +setopt LONG_LIST_JOBS # List jobs in the long format by default. +setopt AUTO_RESUME # Attempt to resume existing job before creating a new process. +setopt NOTIFY # Report status of background jobs immediately. +unsetopt BG_NICE # Don't run all background jobs at a lower priority. +unsetopt HUP # Don't kill jobs on shell exit. +unsetopt CHECK_JOBS # Don't report on jobs when shell exit. + +# PATH +typeset -U cdpath fpath infopath manpath path + +cdpath=( + $HOME + $HOME/Developer +) + +infopath=( + $HOME/.tilde/share/info + $HOME/.tilde/opt/share/info + /usr/local/share/info + /usr/share/info +) + +manpath=( + $HOME/.tilde/share/man + $HOME/.tilde/opt/share/man + /usr/local/share/man + /usr/share/man +) + +for path_file in /etc/manpaths.d/*(.N); do + manpath+=($(<$path_file)) +done + +path=( + $HOME/.tilde/{bin,sbin} + $HOME/.tilde/opt/{bin,sbin} + /usr/local/{bin,sbin} + /usr/{bin,sbin} + /{bin,sbin} +) + +for path_file in /etc/paths.d/*(.N); do + path+=($(<$path_file)) +done + +# Language +if [[ -z "$LANG" ]]; then + eval "$(locale)" +fi + +# Editors +export EDITOR="vim" +export VISUAL="vim" +export PAGER='less' + +# Grep +if zstyle -t ':omz:environment:grep' color; then + export GREP_COLOR='37;45' + export GREP_OPTIONS='--color=auto' +fi + +# Browser (Default) +if (( $+commands[xdg-open] )); then + export BROWSER='xdg-open' +fi + +if (( $+commands[open] )); then + export BROWSER='open' +fi + +# Less +export LESSCHARSET="UTF-8" +export LESSHISTFILE='-' +export LESSEDIT='vim ?lm+%lm. %f' +export LESS='-F -g -i -M -R -S -w -X -z-4' + +if (( $+commands[lesspipe.sh] )); then + export LESSOPEN='| /usr/bin/env lesspipe.sh %s 2>&-' +fi + +# Termcap +if zstyle -t ':omz:environment:termcap' color; then + export LESS_TERMCAP_mb=$'\E[01;31m' # begin blinking + export LESS_TERMCAP_md=$'\E[01;31m' # begin bold + export LESS_TERMCAP_me=$'\E[0m' # end mode + export LESS_TERMCAP_se=$'\E[0m' # end standout-mode + export LESS_TERMCAP_so=$'\E[00;47;30m' # begin standout-mode + export LESS_TERMCAP_ue=$'\E[0m' # end underline + export LESS_TERMCAP_us=$'\E[01;32m' # begin underline +fi + diff --git a/functions/duh b/functions/duh new file mode 100644 index 000000000..10439f1b7 --- /dev/null +++ b/functions/duh @@ -0,0 +1,20 @@ +# +# Displays human readable disk usage. +# +# Authors: +# Suraj N. Kurapati +# Sorin Ionescu +# + +function duh() { + (( $# == 0 )) && set -- * + if [[ "$OSTYPE" == linux* ]]; then + du -khsc "$@" | sort -h -r + else + du -kcs "$@" | awk '{ printf "%9.1fM %s\n", $1 / 1024, $2 } ' | sort -n -r + fi +} +compdef _du duh + +duh "$@" + diff --git a/functions/reload b/functions/reload new file mode 100644 index 000000000..bf84916d1 --- /dev/null +++ b/functions/reload @@ -0,0 +1,14 @@ +# +# Reloads the Zsh configuration. +# +# Authors: +# Sorin Ionescu +# + +# Reloads ~/.zshrc. +local zshrc="$HOME/.zshrc" +if [[ -n "$1" ]]; then + zshrc="$1" +fi +source "$zshrc" + diff --git a/helper.zsh b/helper.zsh new file mode 100644 index 000000000..dd101a5e2 --- /dev/null +++ b/helper.zsh @@ -0,0 +1,57 @@ +# +# Defines helper functions. +# +# Authors: +# Sorin Ionescu +# + +# Checks if a file can be autoloaded by trying to load it in a subshell. +function autoloadable() { + ( unfunction $1 ; autoload -U +X $1 ) &> /dev/null +} + +# Checks boolean variable for "true" (case insensitive "1", "y", "yes", "t", "true", "o", and "on"). +function is-true() { + [[ -n "$1" && "$1" == (1|[Yy]([Ee][Ss]|)|[Tt]([Rr][Uu][Ee]|)|[Oo]([Nn]|)) ]] +} + +# Trap signals were generated with 'kill -l'. +# DEBUG, EXIT, and ZERR are Zsh signals. +TRAP_SIGNALS=( + ABRT ALRM BUS CHLD CONT EMT FPE HUP ILL INFO INT IO KILL PIPE PROF QUIT + SEGV STOP SYS TERM TRAP TSTP TTIN TTOU URG USR1 USR2 VTALRM WINCH XCPU XFSZ + DEBUG EXIT ZERR +) + +# Adds a function to a list to be called when a trap is triggered. +function add-zsh-trap() { + if (( $# < 2 )); then + print "usage: $0 type function" >&2 + return 1 + fi + + if [[ -z "$TRAP_SIGNALS[(r)$1]" ]]; then + print "$0: unknown signal: $1" >&2 + return 1 + fi + + local trap_functions="TRAP${1}_FUNCTIONS" + if (( ! ${(P)+trap_functions} )); then + typeset -gaU "$trap_functions" + fi + eval "$trap_functions+="$2"" + + if (( ! $+functions[TRAP${1}] )); then + eval " + function TRAP${1}() { + for trap_function in \"\$TRAP${1}_FUNCTIONS[@]\"; do + if (( \$+functions[\$trap_function] )); then + \"\$trap_function\" \"\$1\" + fi + done + return \$(( 128 + \$1 )) + } + " + fi +} + diff --git a/history.zsh b/history.zsh new file mode 100644 index 000000000..5b5b9b369 --- /dev/null +++ b/history.zsh @@ -0,0 +1,26 @@ +# +# Sets history options. +# +# Authors: +# Robby Russell +# Sorin Ionescu +# + +HISTFILE="$HOME/.zhistory" +HISTSIZE=10000 +SAVEHIST=10000 + +setopt BANG_HIST # Treat the '!' character specially during expansion. +setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format. +setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits. +setopt SHARE_HISTORY # Share history between all sessions. +setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history. +setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again. +setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate. +setopt HIST_FIND_NO_DUPS # Do not display a line previously found. +setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space. +setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file. +setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry. +setopt HIST_VERIFY # Don't execute immediately upon history expansion. +setopt HIST_BEEP # Beep when accessing nonexistent history. + diff --git a/init.zsh b/init.zsh new file mode 100644 index 000000000..ec218ddc8 --- /dev/null +++ b/init.zsh @@ -0,0 +1,100 @@ +# +# Initializes Oh My Zsh. +# +# Authors: +# Robby Russell +# Sorin Ionescu +# + +# Check for the minimum supported version. +min_zsh_version='4.3.10' +if ! autoload -Uz is-at-least || ! is-at-least "$min_zsh_version"; then + print "omz: old shell detected, minimum required: $min_zsh_version" >&2 +fi +unset min_zsh_version + +# Disable color and theme in dumb terminals. +if [[ "$TERM" == 'dumb' ]]; then + zstyle ':omz:*:*' color 'no' + zstyle ':omz:prompt' theme 'off' +fi + +# Get enabled plugins. +zstyle -a ':omz:load' plugin 'plugins' + +# Add functions to fpath. +fpath=( + ${0:h}/themes/*(/FN) + ${plugins:+${0:h}/plugins/${^plugins}/{functions,completions}(/FN)} + ${0:h}/{functions,completions}(/FN) + $fpath +) + +# Load and initialize the completion system ignoring insecure directories. +autoload -Uz compinit && compinit -i + +# Source files (the order matters). +source "${0:h}/helper.zsh" +source "${0:h}/environment.zsh" +source "${0:h}/terminal.zsh" +source "${0:h}/keyboard.zsh" +source "${0:h}/completion.zsh" +source "${0:h}/history.zsh" +source "${0:h}/directory.zsh" +source "${0:h}/alias.zsh" +source "${0:h}/spectrum.zsh" +source "${0:h}/utility.zsh" + +# Autoload Zsh functions. +autoload -Uz age +autoload -Uz zargs +autoload -Uz zcalc +autoload -Uz zmv + +# Source plugins defined in ~/.zshrc. +for plugin in "$plugins[@]"; do + zstyle ":omz:plugin:$plugin" enable 'yes' + + if [[ ! -d "${0:h}/plugins/$plugin" ]]; then + print "omz: no such plugin: $plugin" >&2 + fi + + if [[ -f "${0:h}/plugins/$plugin/init.zsh" ]]; then + source "${0:h}/plugins/$plugin/init.zsh" + fi +done +unset plugin plugins + +# Autoload Oh My Zsh functions. +for fdir in "$fpath[@]"; do + if [[ "$fdir" == ${0:h}/(|*/)functions ]]; then + for func in $fdir/[^_.]*(N.:t); do + autoload -Uz $func + done + fi +done +unset fdir func + +# Set environment variables for launchd processes. +if [[ "$OSTYPE" == darwin* ]]; then + for env_var in PATH MANPATH; do + launchctl setenv "$env_var" "${(P)env_var}" &! + done + unset env_var +fi + +# Load and run the prompt theming system. +autoload -Uz promptinit && promptinit + +# Load the prompt theme. +zstyle -a ':omz:prompt' theme 'prompt_argv' +prompt "$prompt_argv[@]" +unset prompt_argv + +# Compile the completion dump, to increase startup speed. +dump_file="$HOME/.zcompdump" +if [[ "$dump_file" -nt "${dump_file}.zwc" || ! -f "${dump_file}.zwc" ]]; then + zcompile "$dump_file" +fi +unset dump_file + diff --git a/keyboard.zsh b/keyboard.zsh new file mode 100644 index 000000000..6dcf1002e --- /dev/null +++ b/keyboard.zsh @@ -0,0 +1,336 @@ +# +# Sets keyboard bindings. +# +# Authors: +# Sorin Ionescu +# + +# Dumb terminals lack support. +if [[ "$TERM" == 'dumb' ]]; then + return +fi + +# The default styles. + +# Indicator to notify of vi command mode. +zstyle ':omz:prompt' vicmd '<<<' + +# Indicator to notify of generating completion. +zstyle ':omz:completion' indicator '...' + +# Beep on error in line editor. +setopt BEEP + +# Reset to default key bindings. +bindkey -d + +# Allow command line editing in an external editor. +autoload -Uz edit-command-line +zle -N edit-command-line + +# Use human-friendly identifiers. +zmodload zsh/terminfo +typeset -g -A keyinfo +keyinfo=( + 'Control' '\C-' + 'Escape' '\e' + 'Meta' '\M-' + 'F1' "$terminfo[kf1]" + 'F2' "$terminfo[kf2]" + 'F3' "$terminfo[kf3]" + 'F4' "$terminfo[kf4]" + 'F5' "$terminfo[kf5]" + 'F6' "$terminfo[kf6]" + 'F7' "$terminfo[kf7]" + 'F8' "$terminfo[kf8]" + 'F9' "$terminfo[kf9]" + 'F10' "$terminfo[kf10]" + 'F11' "$terminfo[kf11]" + 'F12' "$terminfo[kf12]" + 'Backspace' "$terminfo[kbs]" + 'Insert' "$terminfo[kich1]" + 'Home' "$terminfo[khome]" + 'PageUp' "$terminfo[kpp]" + 'Delete' "$terminfo[kdch1]" + 'End' "$terminfo[kend]" + 'PageDown' "$terminfo[knp]" + 'Up' "$terminfo[kcuu1]" + 'Left' "$terminfo[kcub1]" + 'Down' "$terminfo[kcud1]" + 'Right' "$terminfo[kcuf1]" + 'BackTab' "$terminfo[kcbt]" +) + +zstyle -s ':omz:editor' keymap 'keymap' +if [[ "$keymap" == (emacs|) ]]; then + # Use Emacs key bindings. + bindkey -e + + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]b" emacs-backward-word + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]f" emacs-forward-word + [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Left]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]$keyinfo[Left]" emacs-backward-word + [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Right]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]$keyinfo[Right]" emacs-forward-word + + # Kill to the beginning of the line. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]u" backward-kill-line + + # Kill to the beginning of the word. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]w" backward-kill-word + + # Undo/Redo + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]_" undo + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]_" redo + + # Search character. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]]" vi-find-next-char + [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]$keyinfo[Control]]" vi-find-prev-char + + # Edit command in an external editor. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]x$keyinfo[Control]e" edit-command-line + + # Expand .... to ../.. + if zstyle -t ':omz:editor' dot-expansion; then + bindkey -M emacs "." expand-dot-to-parent-directory-path + fi + + # Bind to history substring search plugin if enabled; + # otherwise, bind to built-in Zsh history search. + if (( $+widgets[history-incremental-pattern-search-backward] )); then + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]r" history-incremental-pattern-search-backward + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]s" history-incremental-pattern-search-forward + else + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]r" history-incremental-search-backward + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]s" history-incremental-search-forward + fi +elif [[ "$keymap" == vi ]]; then + # Use vi key bindings. + bindkey -v + + # Restores RPROMPT when exiting vicmd. + function vi-restore-rprompt() { + if (( $+RPROMPT_CACHED )); then + RPROMPT="$RPROMPT_CACHED" + unset RPROMPT_CACHED + zle reset-prompt + return 0 + fi + return 1 + } + add-zsh-trap INT vi-restore-rprompt + + # Displays the current vi mode (command). + function zle-keymap-select() { + if ! vi-restore-rprompt && [[ "$KEYMAP" == 'vicmd' ]]; then + RPROMPT_CACHED="$RPROMPT" + zstyle -s ':omz:prompt' vicmd RPROMPT + zle reset-prompt + fi + } + zle -N zle-keymap-select + + # Resets the prompt after exiting edit-command-line. + function zle-line-init() { + vi-restore-rprompt + } + zle -N zle-line-init + + # Resets the prompt after the line has been accepted. + function zle-line-finish() { + vi-restore-rprompt + } + zle -N zle-line-finish + + # Edit command in an external editor. + bindkey -M vicmd "v" edit-command-line + + # Show cursor position. + bindkey -M vicmd "ga" what-cursor-position + + # Undo/Redo + bindkey -M vicmd "u" undo + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M vicmd "$keyinfo[Control]r" redo + + # Expand .... to ../.. + if zstyle -t ':omz:editor' dot-expansion; then + bindkey -M viins "." expand-dot-to-parent-directory-path + fi + + # Switch to command mode. + bindkey -M viins "jk" vi-cmd-mode + bindkey -M viins "kj" vi-cmd-mode + + # Emacs key bindings in insert mode. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]a" beginning-of-line + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]b" backward-char + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M viins "$keyinfo[Escape]b" emacs-backward-word + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]d" delete-char-or-list + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M viins "$keyinfo[Escape]d" kill-word + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]e" end-of-line + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]f" forward-char + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M viins "$keyinfo[Escape]f" emacs-forward-word + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]k" kill-line + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]u" backward-kill-line + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]w" backward-kill-word + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M viins "$keyinfo[Escape]w" copy-region-as-kill + [[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M viins "$keyinfo[Escape]h" run-help + [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Left]" ]] && \ + bindkey -M viins "$keyinfo[Escape]$keyinfo[Left]" emacs-backward-word + [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Right]" ]] && \ + bindkey -M viins "$keyinfo[Escape]$keyinfo[Right]" emacs-forward-word + + # History + bindkey -M vicmd "gg" beginning-of-history + bindkey -M vicmd "G" end-of-history + + # Bind to history substring search plugin if enabled; + # otherwise, bind to built-in Zsh history search. + if (( $+plugins[(er)history-substring-search] )); then + bindkey -M vicmd "k" history-substring-search-up + bindkey -M vicmd "j" history-substring-search-down + else + bindkey -M vicmd "k" up-line-or-history + bindkey -M vicmd "j" down-line-or-history + fi + + if (( $+widgets[history-incremental-pattern-search-backward] )); then + bindkey -M vicmd "?" history-incremental-pattern-search-backward + bindkey -M vicmd "/" history-incremental-pattern-search-forward + + # Emacs key bindings in insert mode. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]r" history-incremental-pattern-search-backward + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]s" history-incremental-pattern-search-forward + else + bindkey -M vicmd "?" history-incremental-search-backward + bindkey -M vicmd "/" history-incremental-search-forward + + # Emacs key bindings in insert mode. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]r" history-incremental-search-backward + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M viins "$keyinfo[Control]s" history-incremental-search-forward + fi +else + print "omz: invalid keymap: $keymap" >&2 + unset keymap + return 1 +fi +unset keymap + +# The next key bindings are for both Emacs and Vi. +[[ -n "$keyinfo[Home]" ]] && \ + bindkey "$keyinfo[Home]" beginning-of-line +[[ -n "$keyinfo[End]" ]] && \ + bindkey "$keyinfo[End]" end-of-line + +[[ -n "$keyinfo[Insert]" ]] && \ + bindkey "$keyinfo[Insert]" overwrite-mode +[[ -n "$keyinfo[Delete]" ]] && \ + bindkey "$keyinfo[Delete]" delete-char +[[ -n "$keyinfo[Backspace]" ]] && \ + bindkey "$keyinfo[Backspace]" backward-delete-char + +[[ -n "$keyinfo[Left]" ]] && \ + bindkey "$keyinfo[Left]" backward-char +[[ -n "$keyinfo[Right]" ]] && \ + bindkey "$keyinfo[Right]" forward-char + +# Expand history on space. +bindkey ' ' magic-space + +if (( $+plugins[(er)history-substring-search] )); then + [[ -n "$keyinfo[Up]" ]] && \ + bindkey "$keyinfo[Up]" history-substring-search-up + [[ -n "$keyinfo[Down]" ]] && \ + bindkey "$keyinfo[Down]" history-substring-search-down + [[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]p" history-substring-search-up + [[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]n" history-substring-search-down +else + [[ -n "$keyinfo[Up]" ]] && \ + bindkey "$keyinfo[Up]" up-line-or-history + [[ -n "$keyinfo[Down]" ]] && \ + bindkey "$keyinfo[Down]" down-line-or-history + [[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]p" up-line-or-history + [[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]n" down-line-or-history +fi + +# Clear screen. +[[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]l" clear-screen + +# Expand command name to full path. +[[ -n "$keyinfo[Escape]" ]] && \ + bindkey "$keyinfo[Escape]e" expand-cmd-path + +# Duplicate the previous word. +[[ -n "$keyinfo[Escape]" ]] && \ + bindkey "$keyinfo[Escape]m" copy-prev-shell-word + +# Bind Shift + Tab to go to the previous menu item. +[[ -n "$keyinfo[BackTab]" ]] && \ + bindkey "$keyinfo[BackTab]" reverse-menu-complete + +# Complete in the middle of word. +[[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]i" expand-or-complete-prefix + +# Convert .... to ../.. automatically. +if zstyle -t ':omz:editor' dot-expansion; then + function expand-dot-to-parent-directory-path() { + if [[ $LBUFFER = *.. ]]; then + LBUFFER+=/.. + else + LBUFFER+=. + fi + } + zle -N expand-dot-to-parent-directory-path + # Do not expand .... to ../.. during incremental search. + bindkey -M isearch . self-insert 2>/dev/null +fi + +# Display an indicator when completing. +function expand-or-complete-prefix-with-indicator() { + local indicator + zstyle -s ':omz:completion' indicator 'indicator' + print -Pn "$indicator" + zle expand-or-complete-prefix + zle redisplay +} +zle -N expand-or-complete-prefix-with-indicator +[[ -n "$keyinfo[Control]" ]] && \ + bindkey "$keyinfo[Control]i" expand-or-complete-prefix-with-indicator + diff --git a/plugins/archive/completions/_extract b/plugins/archive/completions/_extract new file mode 100644 index 000000000..901a8489d --- /dev/null +++ b/plugins/archive/completions/_extract @@ -0,0 +1,14 @@ +#compdef extract +#autoload + +# +# Completes extract. +# +# Authors: +# Sorin Ionescu +# + +_arguments \ + '(-r --remove)'{-r,--remove}'[remove archive]' \ + "*::archive file:_files -g '(#i)*.(tar|tgz|tbz|tbz2|txz|tlz|gz|bz2|xz|lzma|Z|zip|rar|7z|deb)(-.)'" && return 0 + diff --git a/plugins/archive/completions/_ls-archive b/plugins/archive/completions/_ls-archive new file mode 100644 index 000000000..00453c4f9 --- /dev/null +++ b/plugins/archive/completions/_ls-archive @@ -0,0 +1,14 @@ +#compdef ls-archive +#autoload + +# +# Completes ls-archive. +# +# Authors: +# Sorin Ionescu +# + +_arguments \ + '(-v --verbose)'{-v,--remove}'[verbose archive listing]' \ + "*::archive file:_files -g '(#i)*.(tar|tgz|tbz|tbz2|txz|tlz|gz|bz2|xz|lzma|Z|zip|rar|7z)(-.)'" && return 0 + diff --git a/plugins/archive/functions/extract b/plugins/archive/functions/extract new file mode 100644 index 000000000..a18f50683 --- /dev/null +++ b/plugins/archive/functions/extract @@ -0,0 +1,77 @@ +# +# Extracts the contents of popular archive formats. +# +# Authors: +# Sorin Ionescu +# + +local remove_archive +local success +local file_name +local extract_dir + +if (( $# == 0 )); then + cat >&2 <. +EOF +fi + +remove_archive=1 +if [[ "$1" == "-r" || "$1" == "--remove" ]]; then + remove_archive=0 + shift +fi + +while (( $# > 0 )); do + if [[ ! -f "$1" ]]; then + print "$0: file not valid: $1" >&2 + shift + continue + fi + + success=0 + file_name="${1:t}" + extract_dir="${file_name:r}" + case "$1" in + (*.tar.gz|*.tgz) tar xvzf "$1" ;; + (*.tar.bz2|*.tbz|*.tbz2) tar xvjf "$1" ;; + (*.tar.xz|*.txz) tar --xz --help &> /dev/null \ + && tar --xz -xvf "$1" \ + || xzcat "$1" | tar xvf - ;; + (*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \ + && tar --lzma -xvf "$1" \ + || lzcat "$1" | tar xvf - ;; + (*.tar) tar xvf "$1" ;; + (*.gz) gunzip "$1" ;; + (*.bz2) bunzip2 "$1" ;; + (*.xz) unxz "$1" ;; + (*.lzma) unlzma "$1" ;; + (*.Z) uncompress "$1" ;; + (*.zip) unzip "$1" -d $extract_dir ;; + (*.rar) unrar e -ad "$1" ;; + (*.7z) 7za x "$1" ;; + (*.deb) + mkdir -p "$extract_dir/control" + mkdir -p "$extract_dir/data" + cd "$extract_dir"; ar vx "../${1}" > /dev/null + cd control; tar xzvf ../control.tar.gz + cd ../data; tar xzvf ../data.tar.gz + cd ..; rm *.tar.gz debian-binary + cd .. + ;; + (*) + print "$0: cannot extract: $1" >&2 + success=1 + ;; + esac + + (( success = $success > 0 ? $success : $? )) + (( $success == 0 )) && (( $remove_archive == 0 )) && rm "$1" + shift +done + diff --git a/plugins/archive/functions/ls-archive b/plugins/archive/functions/ls-archive new file mode 100644 index 000000000..fb7a503d5 --- /dev/null +++ b/plugins/archive/functions/ls-archive @@ -0,0 +1,54 @@ +# +# Lists the contents of popular archive formats. +# +# Authors: +# Sorin Ionescu +# + +local verbose + +if (( $# == 0 )); then + cat >&2 <. +EOF +fi + +if [[ "$1" == "-v" || "$1" == "--verbose" ]]; then + verbose=0 + shift +fi + +while (( $# > 0 )); do + if [[ ! -f "$1" ]]; then + print "$0: file not valid: $1" >&2 + shift + continue + fi + + case "$1" in + (*.tar.gz|*.tgz) tar t${verbose:+v}vzf "$1" ;; + (*.tar.bz2|*.tbz|*.tbz2) tar t${verbose:+v}jf "$1" ;; + (*.tar.xz|*.txz) tar --xz --help &> /dev/null \ + && tar --xz -t${verbose:+v}f "$1" \ + || xzcat "$1" | tar t${verbose:+v}f - ;; + (*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \ + && tar --lzma -t${verbose:+v}f "$1" \ + || lzcat "$1" | tar x${verbose:+v}f - ;; + (*.tar) tar t${verbose:+v}f "$1" ;; + (*.zip) unzip -l${verbose:+v} "$1" ;; + (*.rar) unrar ${${verbose:+v}:-l} "$1" ;; + (*.7z) 7za l "$1" ;; + (*) + print "$0: cannot list: $1" >&2 + success=1 + ;; + esac + + shift +done + diff --git a/plugins/command-not-found/init.zsh b/plugins/command-not-found/init.zsh new file mode 100644 index 000000000..ac9468bd3 --- /dev/null +++ b/plugins/command-not-found/init.zsh @@ -0,0 +1,11 @@ +# +# Displays installation information for not found commands. +# +# Authors: +# Joseph Jon Booker +# + +if [[ -f /etc/zsh_command_not_found ]]; then + source /etc/zsh_command_not_found +fi + diff --git a/plugins/compleat/init.zsh b/plugins/compleat/init.zsh new file mode 100644 index 000000000..a9c684fe7 --- /dev/null +++ b/plugins/compleat/init.zsh @@ -0,0 +1,20 @@ +# +# Loads Compleat completions. +# +# Authors: +# Sorin Ionescu +# + +if (( ${+commands[compleat]} )); then + compleat_setup="${commands[compleat]:h:h}/share/compleat-1.0/compleat_setup" + + if [[ -f "$compleat_setup" ]]; then + if autoloadable bashcompinit; then + autoload -Uz bashcompinit && bashcompinit + fi + + source "$compleat_setup" + unset compleat_setup + fi +fi + diff --git a/plugins/dpkg/functions/apt-copy b/plugins/dpkg/functions/apt-copy new file mode 100644 index 000000000..c77b0cebc --- /dev/null +++ b/plugins/dpkg/functions/apt-copy @@ -0,0 +1,16 @@ +# +# Generates a script that can be used to duplicate a dpkg-based system. +# +# Authors: +# Daniel Bolton +# Sorin Ionescu +# + +print '#!/bin/sh'"\n" > apt-copy.sh + +list=$(perl -m'AptPkg::Cache' -e '$c=AptPkg::Cache->new; for (keys %$c){ push @a, $_ if $c->{$_}->{'CurrentState'} eq 'Installed';} print "$_ " for sort @a;') + +print 'aptitude install '"$list\n" >> apt-copy.sh + +chmod +x apt-copy.sh + diff --git a/plugins/dpkg/functions/apt-history b/plugins/dpkg/functions/apt-history new file mode 100644 index 000000000..5ae1446a8 --- /dev/null +++ b/plugins/dpkg/functions/apt-history @@ -0,0 +1,37 @@ +# +# Displays dpkg history. +# +# Authors: +# Peter Leung +# Benjamin Boudreau +# Sorin Ionescu +# + +case "$1" in + (install) + zgrep --no-filename 'install ' $(ls -rt /var/log/dpkg*) + ;; + (upgrade|remove) + zgrep --no-filename $1 $(ls -rt /var/log/dpkg*) + ;; + (rollback) + zgrep --no-filename upgrade $(ls -rt /var/log/dpkg*) | \ + grep "$2" -A10000000 | \ + grep "$3" -B10000000 | \ + awk '{print $4"="$5}' + ;; + (list) + zcat $(ls -rt /var/log/dpkg*) + ;; + (*) + cat >&2 < +# Sorin Ionescu +# + +MAKEFLAGS='' # Temporarily unset MAKEFLAGS ('-j3' will fail). +appendage='-custom' # Displayed in $(uname -r). +revision=$(date +"%Y%m%d") # Displayed in the dpkg package file name. + +make-kpkg clean + +time fakeroot make-kpkg --append-to-version "$appendage" --revision \ + "$revision" kernel_image kernel_headers + diff --git a/plugins/dpkg/init.zsh b/plugins/dpkg/init.zsh new file mode 100644 index 000000000..44c879da4 --- /dev/null +++ b/plugins/dpkg/init.zsh @@ -0,0 +1,31 @@ +# +# Defines dpkg aliases. +# +# Authors: +# Daniel Bolton +# Benjamin Boudreau +# Sorin Ionescu +# + +# Aliases +alias as="aptitude -F \"* %p -> %d \n(%v/%V)\" --no-gui --disable-columns search" # Search package. +alias ad="sudo apt-get update" # Update packages lists. +alias au="sudo apt-get update && sudo apt-get dselect-upgrade" # Upgrade packages. +alias ai="sudo apt-get install" # Install package. +alias ar="sudo apt-get remove --purge && sudo apt-get autoremove --purge" # Remove package. +alias ap="apt-cache policy" # Apt policy. +alias av="apt-cache show" # Show package info. +alias acs="apt-cache search" # Search package. +alias ac="sudo apt-get clean && sudo apt-get autoclean" # Clean apt cache. +alias afs='apt-file search --regexp' # Find file's packake. + +# Install all .deb files in the current directory. +# WARNING: you will need to put the glob in single quotes if you use glob_subst. +alias debi='su -c "dpkg -i ./*.deb"' + +# Create a basic .deb package. +alias debc='time dpkg-buildpackage -rfakeroot -us -uc' + +# Remove ALL kernel images and headers EXCEPT the one in use. +alias kclean='su -c '\''aptitude remove -P ?and(~i~nlinux-(ima|hea) ?not(~n`uname -r`))'\'' root' + diff --git a/plugins/git/.gitignore b/plugins/git/.gitignore new file mode 100644 index 000000000..6c3310897 --- /dev/null +++ b/plugins/git/.gitignore @@ -0,0 +1 @@ +_git diff --git a/plugins/git/alias.zsh b/plugins/git/alias.zsh new file mode 100644 index 000000000..5a9be8dea --- /dev/null +++ b/plugins/git/alias.zsh @@ -0,0 +1,254 @@ +# +# Defines Git aliases. +# +# Authors: +# Sorin Ionescu +# + +# Git +alias g='git' +compdef g=git + +# Branch (b) +alias gb='git branch' +compdef _git gb=git-branch +alias gbc='git checkout -b' +compdef _git gbc=git-checkout +alias gbl='git branch -v' +compdef _git gbl=git-branch +alias gbL='git branch -av' +compdef _git gbL=git-branch +alias gbx='git branch -d' +compdef _git gbx=git-branch +alias gbX='git branch -D' +compdef _git gbX=git-branch +alias gbm='git branch -m' +compdef _git gbm=git-branch +alias gbM='git branch -M' +compdef _git gbM=git-branch + +# Commit (c) +alias gc='git commit' +compdef _git gc=git-commit +alias gca='git commit --all' +compdef _git gca=git-commit +alias gcm='git commit --message' +compdef _git gcm=git-commit +alias gco='git checkout' +compdef _git gco=git-checkout +alias gcO='git checkout HEAD --' +compdef _git gcO=git-checkout +alias gcf='git commit --amend --reuse-message HEAD' +compdef _git gcf=git-commit +alias gcp='git cherry-pick --ff' +compdef _git gcp=git-cherry-pick +alias gcP='git cherry-pick --no-commit' +compdef _git gcP=git-cherry-pick +alias gcr='git revert' +compdef _git gcr=git-revert +alias gcR='git reset "HEAD^"' +compdef _git gcR=git-reset +alias gcs='git show' +compdef _git gcs=git-show +alias gcv='git fsck | awk '\''/dangling commit/ {print $3}'\'' | git show --format="SHA1: %C(green)%h%C(reset) %f" --stdin | awk '\''/SHA1/ {sub("SHA1: ", ""); print}'\''' + +# Data (d) +alias gd='git ls-files' +compdef _git gd=git-ls-files +alias gdc='git ls-files --cached' +compdef _git gdc=git-ls-files +alias gdx='git ls-files --deleted' +compdef _git gdx=git-ls-files +alias gdm='git ls-files --modified' +compdef _git gdm=git-ls-files +alias gdu='git ls-files --other --exclude-standard' +compdef _git gdu=git-ls-files +alias gdk='git ls-files --killed' +compdef _git gdk=git-ls-files +alias gdi='git status --porcelain --short --ignored | sed -n "s/^!! //p"' + +# Fetch (f) +alias gf='git fetch' +compdef _git gf=git-fetch +alias gfc='git clone' +compdef _git gfc=git-clone +alias gfm='git pull' +compdef _git gfm=git-pull +alias gfr='git pull --rebase' +compdef _git gfr=git-pull + +# Index (i) +alias gia='git add' +compdef _git gia=git-add +alias giA='git add --patch' +compdef _git giA=git-add +alias giu='git add --update' +compdef _git giu=git-add +alias gid='git diff --no-ext-diff --cached' +compdef _git gid=git-diff +function giD() { git diff --no-ext-diff --cached --ignore-all-space "$@" | view - } +compdef _git giD=git-diff +alias gir='git reset' +compdef _git gir=git-reset +alias giR='git reset --mixed' +compdef _git giR=git-reset +alias gix='git rm -r --cached' +compdef _git gix=git-rm +alias giX='git rm -rf --cached' +compdef _git giX=git-rm +alias gig='git grep --cached' +compdef _git gig=git-grep + +# Konflict (k) +alias gkl='git status | sed -n "s/^.*both [a-z]*ed: *//p"' +alias gka='git add $(gkl)' +compdef _git gka=git-add +alias gke='git mergetool $(gkl)' +alias gko='git checkout --ours --' +compdef _git gko=git-checkout +alias gkO='gko $(gkl)' +alias gkt='git checkout --theirs --' +compdef _git gkt=git-checkout +alias gkT='gkt $(gkl)' + +# Log (l) +git_log_format_medium='--pretty=format:%C(bold)Commit:%C(reset) %C(green)%H%C(red)%d%n%C(bold)Author:%C(reset) %C(cyan)%an <%ae>%n%C(bold)Date:%C(reset) %C(blue)%ai (%ar)%C(reset)%n%+B' +git_log_format_oneline='--pretty=format:%C(green)%h%C(reset) %s%n' +git_log_format_brief='--pretty=format:%C(green)%h%C(reset) %s%n%C(blue)(%ar by %an)%C(red)%d%C(reset)%n' + +alias gl='git log --topo-order ${git_log_format_medium}' +compdef _git gl=git-log +alias gls='git log --topo-order --stat ${git_log_format_medium}' +compdef _git gls=git-log +alias gld='git log --topo-order --stat --patch --full-diff ${git_log_format_medium}' +compdef _git gld=git-log +alias glo='git log --topo-order ${git_log_format_oneline}' +compdef _git glo=git-log +alias glg='git log --topo-order --all --graph ${git_log_format_oneline}' +compdef _git glg=git-log +alias glb='git log --topo-order ${git_log_format_brief}' +compdef _git glb=git-log +alias glc='git shortlog --summary --numbered' +compdef _git glc=git-shortlog + +# Merge (m) +alias gm='git merge' +compdef _git gm=git-merge +alias gmC='git merge --no-commit' +compdef _git gmC=git-merge +alias gmF='git merge --no-ff' +compdef _git gmF=git-merge +alias gma='git merge --abort' +compdef _git gma=git-merge +alias gmt='git mergetool' +compdef _git gmt=git-mergetool + +# Push (p) +alias gp='git push' +compdef _git gp=git-push +alias gpf='git push --force' +compdef _git gpf=git-push +alias gpa='git push --all' +compdef _git gpa=git-push +alias gpA='git push --all && git push --tags' +compdef _git gpA=git-push +alias gpt='git push --tags' +compdef _git gpt=git-push +alias gpc='git push --set-upstream origin "$(git-branch)"' +compdef _git gpc=git-push +alias gpp='git pull origin "$(git-branch)" && git push origin "$(git-branch)"' + +# Rebase (r) +alias gr='git rebase' +compdef _git gr=git-rebase +alias gra='git rebase --abort' +compdef _git gra=git-rebase +alias grc='git rebase --continue' +compdef _git grc=git-rebase +alias gri='git rebase --interactive' +compdef _git gri=git-rebase +alias grs='git rebase --skip' +compdef _git grs=git-rebase + +# Remote (R) +alias gR='git remote' +compdef _git gh=git-remote +alias gRl='git remote --verbose' +compdef _git gRl=git-remote +alias gRa='git remote add' +compdef _git gRa=git-remote +alias gRx='git remote rm' +compdef _git gRx=git-remote +alias gRm='git remote rename' +compdef _git gRm=git-remote +alias gRu='git remote update' +compdef _git gRu=git-remote +alias gRc='git remote prune' +compdef _git gRc=git-remote +alias gRs='git remote show' +compdef _git gRs=git-remote +alias gRb='git-hub' +compdef _git-hub gRb=git-hub + +# Stash (s) +alias gs='git stash' +compdef _git gs=git-stash +alias gsa='git stash apply' +compdef _git gsa=git-stash +alias gsc='git stash clear' +compdef _git gsc=git-stash +alias gsx='git stash drop' +compdef _git gsx=git-stash +alias gsl='git stash list' +compdef _git gsl=git-stash +alias gsL='git stash show --patch --stat' +compdef _git gsL=git-stash +alias gsp='git stash pop' +compdef _git gsp=git-stash +alias gss='git stash save --include-untracked' +compdef _git gss=git-stash +alias gsS='git stash save --patch --no-keep-index' +compdef _git gsS=git-stash + +# Submodule (S) +alias gS='git submodule' +compdef _git gS=git-submodule +alias gSa='git submodule add' +compdef _git gSa=git-submodule +alias gSf='git submodule foreach' +compdef _git gSf=git-submodule +alias gSi='git submodule init' +compdef _git gSi=git-submodule +alias gSl='git submodule status' +compdef _git gSl=git-submodule +alias gSs='git submodule sync' +compdef _git gSs=git-submodule +alias gSu='git submodule update' +compdef _git gSu=git-submodule +alias gSU='git submodule update --init --recursive' +compdef _git gSU=git-submdoule + +# Working Copy (w) +alias gws='git status --short' +compdef _git gws=git-status +alias gwS='git status' +compdef _git gwS=git-status +alias gwd='git diff --no-ext-diff' +compdef _git gwd=git-diff +function gwD() { git diff --no-ext-diff --ignore-all-space "$@" | view - } +compdef _git gwD=git-diff +alias gwr='git reset --soft' +compdef _git gwr=git-reset +alias gwR='git reset --hard' +compdef _git gwR=git-reset +alias gwc='git clean -n' +compdef _git gwc=git-clean +alias gwC='git clean -f' +compdef _git gwC=git-clean +alias gwx='git rm -r' +compdef _git gwx=git-rm +alias gwX='git rm -rf' +compdef _git gwX=git-rm +alias gwg='git grep' +compdef _git gwg=git-grep + diff --git a/plugins/git/completion.zsh b/plugins/git/completion.zsh new file mode 100644 index 000000000..8c4a56872 --- /dev/null +++ b/plugins/git/completion.zsh @@ -0,0 +1,28 @@ +# +# Gets the latest Git completion. +# +# Authors: +# Sorin Ionescu +# + +completion_file="${0:h}/completions/_git" +completion_file_url='http://zsh.git.sourceforge.net/git/gitweb.cgi?p=zsh/zsh;a=blob_plain;f=Completion/Unix/Command/_git;hb=HEAD' +if [[ ! -e "$completion_file" ]] && (( $+commands[git] )); then + # Remove empty completions directory. + if [[ -d "${completion_file:h}"(/^F) ]]; then + rmdir "${completion_file:h}" 2> /dev/null + fi + + if mkdir -p "${completion_file:h}" > /dev/null; then + if (( $+commands[curl] )); then + curl -L "$completion_file_url" -o "$completion_file" &> /dev/null &! + fi + + if (( $+commmands[wget] )); then + wget -C "$completion_file_url" -O "$completion_file" &> /dev/null &! + fi + fi +fi +unset completion_file +unset completion_file_url + diff --git a/plugins/git/completions/_git-hub b/plugins/git/completions/_git-hub new file mode 100644 index 000000000..ac17fd27a --- /dev/null +++ b/plugins/git/completions/_git-hub @@ -0,0 +1,44 @@ +#compdef git-hub +#autoload + +# +# Completes git-hub. +# +# Authors: +# Sorin Ionescu +# + +local state remotes remote branches files ret=1 + +_arguments -C -s -S \ + '1::args:->remote' \ + '2::args:->branch' \ + '3::args:->file' && ret=0 + +case "$state" in + (remote) + remotes=($( + git config -l \ + | grep 'remote\.[^.]*\.url' \ + | cut -d'.' -f2)) + _describe -t branch 'remotes' remotes && ret=0 + ;; + (branch) + remote="$words[(($CURRENT - 1))]" + branches=($( + git branch -r \ + | grep "${remote}/" \ + | sed \ + -e "/${remote}\/HEAD -> ${remote}/d" \ + -e "s/^[[:space:]]*${remote}\///g" + )) + _describe -t branch 'branches' branches && ret=0 + ;; + (file) + files=(${(0)"$(_call_program files git ls-files -z --exclude-standard 2>/dev/null)"}) + _wanted file expl 'file' _multi_parts - / files && ret=0 + ;; +esac + +return $ret + diff --git a/plugins/git/completions/_git-info b/plugins/git/completions/_git-info new file mode 100644 index 000000000..0357c6d8f --- /dev/null +++ b/plugins/git/completions/_git-info @@ -0,0 +1,15 @@ +#compdef git-info +#autoload + +# +# Completes git-info. +# +# Authors: +# Sorin Ionescu +# + +_arguments "1:toggle:(( + on\:'enable in-prompt information for the current repository' + off\:'disable in-prompt information for the current repository' +))" && return 0 + diff --git a/plugins/git/functions/git-branch b/plugins/git/functions/git-branch new file mode 100644 index 000000000..3078ad13b --- /dev/null +++ b/plugins/git/functions/git-branch @@ -0,0 +1,15 @@ +# +# Displays the current Git branch. +# +# Authors: +# Sorin Ionescu +# + +local ref="$(git symbolic-ref HEAD 2> /dev/null)" +if [[ -n "$ref" ]]; then + print "${ref#refs/heads/}" + return 0 +else + return 1 +fi + diff --git a/plugins/git/functions/git-hub b/plugins/git/functions/git-hub new file mode 100644 index 000000000..59cb82a2e --- /dev/null +++ b/plugins/git/functions/git-hub @@ -0,0 +1,45 @@ +# +# Opens a GitHub repository in the default browser. +# +# Authors: +# Sorin Ionescu +# + +local remote branches branch current_branch file url + +remote="${1:-origin}" +url=$( + git config -l \ + | grep "remote.${remote}.url" \ + | sed -En "s/remote.${remote}.url=(git|https?)(@|:\/\/)github.com(:|\/)(.+)\/(.+).git/https:\/\/github.com\/\4\/\5/p" +) +branches=($( + git branch -r | sed -e "/${remote}\/HEAD -> ${remote}/d" -e "s/^[[:space:]]*${remote}\///g" +)) +current_branch="$(git-branch)" +branch="${2:-master}" +file="$3" + +if [[ -z "$2" ]]; then + if (( $branches[(I)$current_branch] != 0 )); then + branch="$current_branch" + else + branch='master' + fi +fi + +if [[ -n "$url" ]]; then + url="${url}/tree/${branch}/${file}" + + if (( $+commands[$BROWSER] )); then + "$BROWSER" "$url" + return 0 + else + print "$0: browser not set or set to a non-existent browser" >&2 + return 1 + fi +else + print "$0: not a Git repository or remote origin not set" >&2 + return 1 +fi + diff --git a/plugins/git/functions/git-info b/plugins/git/functions/git-info new file mode 100644 index 000000000..5d0e7d3a5 --- /dev/null +++ b/plugins/git/functions/git-info @@ -0,0 +1,371 @@ +# +# Displays Git repository information. +# +# Authors: +# Sorin Ionescu +# + +# Gets the Git special action (am, merge, rebase, etc.). +# Borrowed from vcs_info and edited. +function _git-action() { + local action='' + local action_dir + local git_dir="$(git-root)/.git" + + for action_dir in \ + "${git_dir}/rebase-apply" \ + "${git_dir}/rebase" \ + "${git_dir}/../.dotest"; do + if [[ -d "$action_dir" ]] ; then + if [[ -f "${action_dir}/rebasing" ]] ; then + action='rebase' + elif [[ -f "${action_dir}/applying" ]] ; then + action='am' + else + action='am/rebase' + fi + print "$action" + return 0 + fi + done + + for action_dir in \ + "${git_dir}/rebase-merge/interactive" \ + "${git_dir}/.dotest-merge/interactive"; do + if [[ -f "$action_dir" ]]; then + print 'rebase-i' + return 0 + fi + done + + for action_dir in \ + "${git_dir}/rebase-merge" \ + "${git_dir}/.dotest-merge"; do + if [[ -d "$action_dir" ]]; then + print 'rebase-m' + return 0 + fi + done + + if [[ -f "${git_dir}/MERGE_HEAD" ]]; then + print 'merge' + return 0 + fi + + if [[ -f "${git_dir}/CHERRY_PICK_HEAD" ]]; then + print 'cherry-pick' + return 0 + fi + + if [[ -f "${git_dir}/BISECT_LOG" ]]; then + print 'bisect' + return 0 + fi + + return 1 +} + +# Turns off git-info for the current repository. +function _git-info-abort() { + if ! is-true "$_git_info_executing"; then + return 1 + fi + + cat >&2 </dev/null)"; then + return 1 + fi + + if (( $# > 0 )); then + if [[ "$1" == [Oo][Nn] ]]; then + git config --bool prompt.showinfo true + elif [[ "$1" == [Oo][Ff][Ff] ]]; then + git config --bool prompt.showinfo false + else + print "usage: $0 [ on | off ]" >&2 + fi + return 0 + fi + + # Return if git-info is disabled. + if ! is-true "${$(git config --bool prompt.showinfo):-true}"; then + return 1 + fi + + # Used to abort and turn git-info off on SIGINT. + _git_info_executing=true + + # Use short status for easy parsing. + status_cmd='git status --short --branch' + + # Ignore submodule status. + zstyle -b \ + ':omz:plugin:git:prompt:ignore' submodule 'ignore_submodule' + zstyle -s \ + ':omz:plugin:git:prompt:ignore:submodule' when 'ignore_submodule_when' + if is-true "$ignore_submodule"; then + status_cmd+=" --ignore-submodules=${ignore_submodule_when:-all}" + fi + + # Get commit. + commit="$(git rev-parse HEAD 2>/dev/null)" + + # Format commit (short). + commit_short="$commit[1,7]" + zstyle -s ':omz:plugin:git:prompt' commit 'commit_format' + zformat -f commit_formatted "$commit_format" "c:$commit_short" + + # Stashed + if [[ -f "$(git-root)/.git/refs/stash" ]]; then + stashed="$(git stash list 2>/dev/null | wc -l)" + zstyle -s ':omz:plugin:git:prompt' stashed 'stashed_format' + zformat -f stashed_formatted "$stashed_format" "S:$stashed" + fi + + # Assume that the working copy is clean. + zstyle -s ':omz:plugin:git:prompt' clean 'clean_formatted' + + while IFS=$'\n' read line; do + (( line_number++ )) + + if (( line_number == 1 )) && [[ "$line" == *'(no branch)'* ]]; then + # Set branch to commit (short) when the branch is not found. + branch="$commit_short" + + # Get action. + action="$(_git-action)" + if [[ -n "$action" ]]; then + zstyle -s ':omz:plugin:git:prompt' action 'action_format' + zformat -f action_formatted "$action_format" "s:$action" + fi + elif (( line_number == 1 )) \ + && [[ "$line" == (#b)'## Initial commit on '(?##) ]]; + then + branch="$match[1]" + elif (( line_number == 1 )); then + # Split the line into an array for parsing. + branch_info=(${(s: :)line}) + + # Match: master...origin/master + if [[ "$branch_info[2]" == (#b)(?##)...(?##/?##) ]]; then + branch="$match[1]" + remote="$match[2]" + + # Match: [ahead or [behind + if [[ "$branch_info[3]" == (#b)\[(ahead|behind) ]]; then + ahead_or_behind="$match[1]" + if [[ "$ahead_or_behind" == 'behind' ]]; then + # Extract digits: 10] + behind="${branch_info[4]%\]}" + else + # Extract digits: 10] or 10, + ahead="${branch_info[4]%[,\]]}" + # Extract digits: 10] + behind="${branch_info[6]%\]}" + fi + fi + # Match: master + elif [[ "$branch_info[2]" == (#b)(?##) ]]; then + branch="$match[1]" + fi + else + # Format dirty. + if [[ -z "$dirty" ]]; then + zstyle -s ':omz:plugin:git:prompt' dirty 'dirty_formatted' + if [[ -z "$dirty_formatted" ]]; then + unset clean_formatted + fi + fi + + # Count: added/deleted/modified/renamed/unmerged/untracked + [[ "$line" == (((A|M|D|T) )|(AD|AM|AT|MM))\ * ]] && (( added++ )) + [[ "$line" == ( D|AD)\ * ]] && (( deleted++ )) + [[ "$line" == (( (M|T))|(AM|AT|MM))\ * ]] && (( modified++ )) + [[ "$line" == R\ \ * ]] && (( renamed++ )) + [[ "$line" == UU\ * ]] && (( unmerged++ )) + [[ "$line" == \?\?\ * ]] && (( untracked++ )) + fi + done < <("${(z)status_cmd}" 2>/dev/null) + + # Format branch. + zstyle -s ':omz:plugin:git:prompt' branch 'branch_format' + zformat -f branch_formatted "$branch_format" "b:$branch" + + # Format remote. + if [[ "$branch" != "$commit" ]]; then + if [[ -z "$remote" ]]; then + remote="${$( \ + git rev-parse \ + --verify ${branch}@{upstream} \ + --symbolic-full-name 2>/dev/null)#refs/remotes/}" + fi + zstyle -s ':omz:plugin:git:prompt' remote 'remote_format' + zformat -f remote_formatted "$remote_format" "R:$remote" + fi + + # Format ahead. + if [[ -n "$ahead" ]]; then + zstyle -s ':omz:plugin:git:prompt' ahead 'ahead_format' + zformat -f ahead_formatted "$ahead_format" "A:$ahead" + fi + + # Format behind. + if [[ -n "$behind" ]]; then + zstyle -s ':omz:plugin:git:prompt' behind 'behind_format' + zformat -f behind_formatted "$behind_format" "B:$behind" + fi + + # Format added. + if (( $added > 0 )); then + zstyle -s ':omz:plugin:git:prompt' added 'added_format' + zformat -f added_formatted "$added_format" "a:$added_format" + fi + + # Format deleted. + if (( $deleted > 0 )); then + zstyle -s ':omz:plugin:git:prompt' deleted 'deleted_format' + zformat -f deleted_formatted "$deleted_format" "d:$deleted_format" + fi + + # Format modified. + if (( $modified > 0 )); then + zstyle -s ':omz:plugin:git:prompt' modified 'modified_format' + zformat -f modified_formatted "$modified_format" "m:$modified" + fi + + # Format renamed. + if (( $renamed > 0 )); then + zstyle -s ':omz:plugin:git:prompt' renamed 'renamed_format' + zformat -f renamed_formatted "$renamed_format" "r:$renamed" + fi + + # Format unmerged. + if (( $unmerged > 0 )); then + zstyle -s ':omz:plugin:git:prompt' unmerged 'unmerged_format' + zformat -f unmerged_formatted "$unmerged_format" "U:$unmerged" + fi + + # Format untracked. + if (( $untracked > 0 )); then + zstyle -s ':omz:plugin:git:prompt' untracked 'untracked_format' + zformat -f untracked_formatted "$untracked_format" "u:$untracked" + fi + + # Format prompts. + zstyle -s ':omz:plugin:git:prompt' prompt 'prompt_format' + zstyle -s ':omz:plugin:git:prompt' rprompt 'rprompt_format' + + git_info_vars=( + git_prompt_info "$prompt_format" + git_rprompt_info "$rprompt_format" + ) + + for git_info_var in ${(k)git_info_vars}; do + zformat -f "$git_info_var" "$git_info_vars[$git_info_var]" \ + "s:$action_formatted" \ + "a:$added_formatted" \ + "A:$ahead_formatted" \ + "B:$behind_formatted" \ + "b:$branch_formatted" \ + "C:$clean_formatted" \ + "c:$commit_formatted" \ + "d:$deleted_formatted" \ + "D:$dirty_formatted" \ + "m:$modified_formatted" \ + "R:$remote_formatted" \ + "r:$renamed_formatted" \ + "S:$stashed_formatted" \ + "U:$unmerged_formatted" \ + "u:$untracked_formatted" + done + + unset _git_info_executing + return 0 +} + +git-info "$@" + diff --git a/plugins/git/functions/git-root b/plugins/git/functions/git-root new file mode 100644 index 000000000..d704eff1a --- /dev/null +++ b/plugins/git/functions/git-root @@ -0,0 +1,15 @@ +# +# Displays the Git repository root. +# +# Authors: +# Sorin Ionescu +# + +local root="$(git rev-parse --show-toplevel 2> /dev/null)" +if [[ -n "$root" ]]; then + print "$root" + return 0 +else + return 1 +fi + diff --git a/plugins/git/hub.zsh b/plugins/git/hub.zsh new file mode 100644 index 000000000..8ff40594a --- /dev/null +++ b/plugins/git/hub.zsh @@ -0,0 +1,14 @@ +# +# Adds GitHub knowledge to the Git command. +# +# Authors: +# Chris Wanstrath +# Sorin Ionescu +# + +if (( $+commands[hub] )); then + function git() { + hub "$@" + } +fi + diff --git a/plugins/git/init.zsh b/plugins/git/init.zsh new file mode 100644 index 000000000..9e7b18c0c --- /dev/null +++ b/plugins/git/init.zsh @@ -0,0 +1,13 @@ +# +# Provides Git aliases and functions. +# +# Authors: +# Sorin Ionescu +# + +# Source plugin files. +source "${0:h}/alias.zsh" +source "${0:h}/hub.zsh" +source "${0:h}/style.zsh" +source "${0:h}/completion.zsh" + diff --git a/plugins/git/style.zsh b/plugins/git/style.zsh new file mode 100644 index 000000000..9f0a6102c --- /dev/null +++ b/plugins/git/style.zsh @@ -0,0 +1,64 @@ +# +# Defines Git information display styles. +# +# Authors: +# Sorin Ionescu +# + +# %s - Special action name (am, merge, rebase). +zstyle ':omz:plugin:git:prompt' action 'action:%s' + +# %a - Indicator to notify of added files. +zstyle ':omz:plugin:git:prompt' added 'added:%a' + +# %A - Indicator to notify of ahead branch. +zstyle ':omz:plugin:git:prompt' ahead 'ahead:%A' + +# %B - Indicator to notify of behind branch. +zstyle ':omz:plugin:git:prompt' behind 'behind:%B' + +# %b - Branch name. +zstyle ':omz:plugin:git:prompt' branch '%b' + +# %C - Indicator to notify of clean branch. +zstyle ':omz:plugin:git:prompt' clean 'clean' + +# %c - SHA-1 hash. +zstyle ':omz:plugin:git:prompt' commit 'commit:%c' + +# %d - Indicator to notify of deleted files. +zstyle ':omz:plugin:git:prompt' deleted 'deleted:%d' + +# %D - Indicator to notify of dirty branch. +zstyle ':omz:plugin:git:prompt' dirty 'dirty' + +# %m - Indicator to notify of modified files. +zstyle ':omz:plugin:git:prompt' modified 'modified:%m' + +# %R - Remote name. +zstyle ':omz:plugin:git:prompt' remote '%R' + +# %r - Indicator to notify of renamed files. +zstyle ':omz:plugin:git:prompt' renamed 'renamed:%r' + +# %S - Indicator to notify of stashed files. +zstyle ':omz:plugin:git:prompt' stashed 'stashed:%S' + +# %U - Indicator to notify of unmerged files. +zstyle ':omz:plugin:git:prompt' unmerged 'unmerged:%U' + +# %u - Indicator to notify of untracked files. +zstyle ':omz:plugin:git:prompt' untracked 'untracked:%u' + +# Left prompt. +zstyle ':omz:plugin:git:prompt' prompt ' git:(%b %D%C)' + +# Right prompt. +zstyle ':omz:plugin:git:prompt' rprompt '' + +# Ignore submodule. +zstyle ':omz:plugin:git:prompt:ignore' submodule 'no' + +# Ignore submodule when it is 'dirty', 'untracked', 'all', or 'none'. +zstyle ':omz:plugin:git:prompt:ignore:submodule' when 'all' + diff --git a/plugins/gnu-utils/init.zsh b/plugins/gnu-utils/init.zsh new file mode 100644 index 000000000..8c6ca6a69 --- /dev/null +++ b/plugins/gnu-utils/init.zsh @@ -0,0 +1,70 @@ +# +# Provides for the interactive usage of GNU Coreutils on BSD systems. +# +# Authors: +# Sorin Ionescu +# + +if (( $+commands[gdircolors] )); then + function __gnu_utils() { + emulate -L zsh + local gcmds + local gcmd + local cmd + local prefix + + # GNU Coreutils. + gcmds=('g[' 'gbase64' 'gbasename' 'gcat' 'gchcon' 'gchgrp' 'gchmod' + 'gchown' 'gchroot' 'gcksum' 'gcomm' 'gcp' 'gcsplit' 'gcut' 'gdate' + 'gdd' 'gdf' 'gdir' 'gdircolors' 'gdirname' 'gdu' 'gecho' 'genv' 'gexpand' + 'gexpr' 'gfactor' 'gfalse' 'gfmt' 'gfold' 'ggroups' 'ghead' 'ghostid' + 'gid' 'ginstall' 'gjoin' 'gkill' 'glink' 'gln' 'glogname' 'gls' 'gmd5sum' + 'gmkdir' 'gmkfifo' 'gmknod' 'gmktemp' 'gmv' 'gnice' 'gnl' 'gnohup' 'gnproc' + 'god' 'gpaste' 'gpathchk' 'gpinky' 'gpr' 'gprintenv' 'gprintf' 'gptx' 'gpwd' + 'greadlink' 'grm' 'grmdir' 'gruncon' 'gseq' 'gsha1sum' 'gsha224sum' + 'gsha256sum' 'gsha384sum' 'gsha512sum' 'gshred' 'gshuf' 'gsleep' 'gsort' + 'gsplit' 'gstat' 'gstty' 'gsum' 'gsync' 'gtac' 'gtail' 'gtee' 'gtest' + 'gtimeout' 'gtouch' 'gtr' 'gtrue' 'gtruncate' 'gtsort' 'gtty' 'guname' + 'gunexpand' 'guniq' 'gunlink' 'guptime' 'gusers' 'gvdir' 'gwc' 'gwho' + 'gwhoami' 'gyes') + + # Not part of coreutils, installed separately. + gcmds+=('ggrep' 'gsed' 'gtar' 'gtime') + + for gcmd in "$gcmds[@]"; do + # + # This method allows for builtin commands to be primary but it's + # lost if hash -r or rehash -f is executed. Thus, those two + # functions have to be wrapped. + # + if (( $+commands[$gcmd] )); then + hash "$gcmd[2,-1]"="$commands[$gcmd]" + fi + done + + return 0 + } + __gnu_utils; + + function hash() { + if (( $+argv[(er)-r] )) || (( $+argv[(er)-f] )); then + builtin hash "$@" + __gnu_utils + else + builtin hash "$@" + fi + } + + function rehash() { + hash -r "$@" + } + + # A sensible default for ls. + if zstyle -t ':omz:alias:ls' color && [[ -f "$HOME/.dir_colors" ]]; then + eval $(gdircolors "$HOME/.dir_colors") + alias ls='ls -hF --group-directories-first --color=auto' + else + alias ls='ls -hF --group-directories-first' + fi +fi + diff --git a/plugins/gpg-agent/init.zsh b/plugins/gpg-agent/init.zsh new file mode 100644 index 000000000..f646271b3 --- /dev/null +++ b/plugins/gpg-agent/init.zsh @@ -0,0 +1,35 @@ +# +# Provides for an easier use of gpg-agent. +# +# Authors: +# Florian Walch +# Sorin Ionescu +# + +local GPG_ENV="$HOME/.gnupg/gpg-agent.env" + +if (( ! $+commands[gpg-agent] )); then + return +fi + +function _gpg-agent-start() { + /usr/bin/env gpg-agent --daemon --enable-ssh-support --write-env-file "${GPG_ENV}" > /dev/null + chmod 600 "${GPG_ENV}" + source "${GPG_ENV}" > /dev/null +} + +# Source GPG agent settings, if applicable. +if [[ -f "${GPG_ENV}" ]]; then + source "${GPG_ENV}" > /dev/null + ps -ef | grep "${SSH_AGENT_PID}" | grep gpg-agent > /dev/null || { + _gpg-agent-start + } +else + _gpg-agent-start +fi + +export GPG_AGENT_INFO +export SSH_AUTH_SOCK +export SSH_AGENT_PID +export GPG_TTY="$(tty)" + diff --git a/plugins/history-substring-search/README b/plugins/history-substring-search/README new file mode 100644 index 000000000..0726ccffe --- /dev/null +++ b/plugins/history-substring-search/README @@ -0,0 +1,8 @@ +To activate this script, load it into an interactive Zsh session: + + % source history-substring-search.zsh + +See the "history-substring-search.zsh" file for more information: + + % sed -n '2,/^$/s/^#//p' history-substring-search.zsh | more + diff --git a/plugins/history-substring-search/history-substring-search.zsh b/plugins/history-substring-search/history-substring-search.zsh new file mode 100644 index 000000000..d0854b199 --- /dev/null +++ b/plugins/history-substring-search/history-substring-search.zsh @@ -0,0 +1,554 @@ +#!/usr/bin/env zsh +############################################################################## +# +# Copyright (c) 2009 Peter Stephenson +# Copyright (c) 2011 Guido van Steen +# Copyright (c) 2011 Suraj N. Kurapati +# Copyright (c) 2011 Sorin Ionescu +# Copyright (c) 2011 Vincent Guerci +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the FIZSH nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################## + +#----------------------------------------------------------------------------- +# configuration variables +#----------------------------------------------------------------------------- + +HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold' +HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold' +HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i' + +#----------------------------------------------------------------------------- +# the main ZLE widgets +#----------------------------------------------------------------------------- + +function history-substring-search-up() { + _history-substring-search-begin + + _history-substring-search-up-history || + _history-substring-search-up-buffer || + _history-substring-search-up-search + + _history-substring-search-end +} + +function history-substring-search-down() { + _history-substring-search-begin + + _history-substring-search-down-history || + _history-substring-search-down-buffer || + _history-substring-search-down-search + + _history-substring-search-end +} + +zle -N history-substring-search-up +zle -N history-substring-search-down + +bindkey '\e[A' history-substring-search-up +bindkey '\e[B' history-substring-search-down + +#----------------------------------------------------------------------------- +# implementation details +#----------------------------------------------------------------------------- + +zmodload -F zsh/parameter + +# +# We have to "override" some keys and widgets if the +# zsh-syntax-highlighting plugin has not been loaded: +# +# https://github.com/nicoulaj/zsh-syntax-highlighting +# +if [[ $+functions[_zsh_highlight] -eq 0 ]]; then + # + # Dummy implementation of _zsh_highlight() + # that simply removes existing highlights + # + function _zsh_highlight() { + region_highlight=() + } + + # + # Remove existing highlights when the user + # inserts printable characters into $BUFFER + # + function ordinary-key-press() { + if [[ $KEYS == [[:print:]] ]]; then + region_highlight=() + fi + zle .self-insert + } + zle -N self-insert ordinary-key-press + + # + # The following snippet was taken from the zsh-syntax-highlighting project: + # + # https://github.com/zsh-users/zsh-syntax-highlighting/blob/56b134f5d62ae3d4e66c7f52bd0cc2595f9b305b/zsh-syntax-highlighting.zsh#L126-161 + # + # Copyright (c) 2010-2011 zsh-syntax-highlighting contributors + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # + # * Neither the name of the zsh-syntax-highlighting contributors nor the + # names of its contributors may be used to endorse or promote products + # derived from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + #--------------8<-------------------8<-------------------8<----------------- + # Rebind all ZLE widgets to make them invoke _zsh_highlights. + _zsh_highlight_bind_widgets() + { + # Load Zsh module zsh/zleparameter, needed to override user defined widgets. + zmodload zsh/zleparameter 2>/dev/null || { + print 'history-substring-search: failed loading: zsh/zleparameter' >&2 + return 1 + } + + # Override ZLE widgets to make them invoke _zsh_highlight. + local cur_widget + for cur_widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|run-help|which-command|beep)}; do + case $widgets[$cur_widget] in + + # Already rebound event: do nothing. + user:$cur_widget|user:_zsh_highlight_widget_*);; + + # User defined widget: override and rebind old one with prefix "orig-". + user:*) eval "zle -N orig-$cur_widget ${widgets[$cur_widget]#*:}; \ + _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \ + zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; + + # Completion widget: override and rebind old one with prefix "orig-". + completion:*) eval "zle -C orig-$cur_widget ${${widgets[$cur_widget]#*:}/:/ }; \ + _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \ + zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; + + # Builtin widget: override and make it call the builtin ".widget". + builtin) eval "_zsh_highlight_widget_$cur_widget() { builtin zle .$cur_widget -- \"\$@\" && _zsh_highlight }; \ + zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; + + # Default: unhandled case. + *) print "history-substring-search: unhandled ZLE widget: $cur_widget" >&2 ;; + esac + done + } + #-------------->8------------------->8------------------->8----------------- + + _zsh_highlight_bind_widgets +fi + +function _history-substring-search-begin() { + setopt LOCAL_OPTIONS EXTENDED_GLOB + + _history_substring_search_move_cursor_eol=false + _history_substring_search_query_highlight= + + # + # Continue using the previous $_history_substring_search_result by default, + # unless the current query was cleared or a new/different query was entered. + # + if [[ -z $BUFFER || $BUFFER != $_history_substring_search_result ]]; then + # + # For the purpose of highlighting we will also keep + # a version without doubly-escaped meta characters. + # + _history_substring_search_query=$BUFFER + + # + # $BUFFER contains the text that is in the command-line currently. + # we put an extra "\\" before meta characters such as "\(" and "\)", + # so that they become "\\\(" and "\\\)". + # + _history_substring_search_query_escaped=${BUFFER//(#m)[\][()|\\*?#<>~^]/\\$MATCH} + + # + # Find all occurrences of the search query in the history file. + # + # (k) turns it an array of line numbers. + # + # (on) seems to remove duplicates, which are default + # options. They can be turned off by (ON). + # + _history_substring_search_matches=(${(kon)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)*${_history_substring_search_query_escaped}*]}) + + # + # Define the range of values that $_history_substring_search_match_index + # can take: [0, $_history_substring_search_matches_count_plus]. + # + _history_substring_search_matches_count=$#_history_substring_search_matches + _history_substring_search_matches_count_plus=$(( _history_substring_search_matches_count + 1 )) + _history_substring_search_matches_count_sans=$(( _history_substring_search_matches_count - 1 )) + + # + # If $_history_substring_search_match_index is equal to + # $_history_substring_search_matches_count_plus, this indicates that we + # are beyond the beginning of $_history_substring_search_matches. + # + # If $_history_substring_search_match_index is equal to 0, this indicates + # that we are beyond the end of $_history_substring_search_matches. + # + # If we have initially pressed "up" we have to initialize + # $_history_substring_search_match_index to + # $_history_substring_search_matches_count_plus so that it will be + # decreased to $_history_substring_search_matches_count. + # + # If we have initially pressed "down" we have to initialize + # $_history_substring_search_match_index to + # $_history_substring_search_matches_count so that it will be increased to + # $_history_substring_search_matches_count_plus. + # + if [[ $WIDGET == history-substring-search-down ]]; then + _history_substring_search_match_index=$_history_substring_search_matches_count + else + _history_substring_search_match_index=$_history_substring_search_matches_count_plus + fi + fi +} + +function _history-substring-search-end() { + setopt LOCAL_OPTIONS EXTENDED_GLOB + + _history_substring_search_result=$BUFFER + + # move the cursor to the end of the command line + if [[ $_history_substring_search_move_cursor_eol == true ]]; then + CURSOR=${#BUFFER} + fi + + # highlight command line using zsh-syntax-highlighting + _zsh_highlight + + # highlight the search query inside the command line + if [[ -n $_history_substring_search_query_highlight && -n $_history_substring_search_query ]]; then + # + # The following expression yields a variable $MBEGIN, which + # indicates the begin position + 1 of the first occurrence + # of _history_substring_search_query_escaped in $BUFFER. + # + : ${(S)BUFFER##(#m$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)($_history_substring_search_query##)} + local begin=$(( MBEGIN - 1 )) + local end=$(( begin + $#_history_substring_search_query )) + region_highlight+=("$begin $end $_history_substring_search_query_highlight") + fi + + # For debugging purposes: + # zle -R "mn: "$_history_substring_search_match_index" m#: "${#_history_substring_search_matches} + # read -k -t 200 && zle -U $REPLY + + # Exit successfully from the history-substring-search-* widgets. + true +} + +function _history-substring-search-up-buffer() { + # + # Check if the UP arrow was pressed to move the cursor within a multi-line + # buffer. This amounts to three tests: + # + # 1. $#buflines -gt 1. + # + # 2. $CURSOR -ne $#BUFFER. + # + # 3. Check if we are on the first line of the current multi-line buffer. + # If so, pressing UP would amount to leaving the multi-line buffer. + # + # We check this by adding an extra "x" to $LBUFFER, which makes + # sure that xlbuflines is always equal to the number of lines + # until $CURSOR (including the line with the cursor on it). + # + local buflines XLBUFFER xlbuflines + buflines=(${(f)BUFFER}) + XLBUFFER=$LBUFFER"x" + xlbuflines=(${(f)XLBUFFER}) + + if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xlbuflines -ne 1 ]]; then + zle up-line-or-history + return true + fi + + false +} + +function _history-substring-search-down-buffer() { + # + # Check if the DOWN arrow was pressed to move the cursor within a multi-line + # buffer. This amounts to three tests: + # + # 1. $#buflines -gt 1. + # + # 2. $CURSOR -ne $#BUFFER. + # + # 3. Check if we are on the last line of the current multi-line buffer. + # If so, pressing DOWN would amount to leaving the multi-line buffer. + # + # We check this by adding an extra "x" to $RBUFFER, which makes + # sure that xrbuflines is always equal to the number of lines + # from $CURSOR (including the line with the cursor on it). + # + local buflines XRBUFFER xrbuflines + buflines=(${(f)BUFFER}) + XRBUFFER="x"$RBUFFER + xrbuflines=(${(f)XRBUFFER}) + + if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xrbuflines -ne 1 ]]; then + zle down-line-or-history + return true + fi + + false +} + +function _history-substring-search-up-history() { + # + # Behave like up in Zsh, except clear the $BUFFER + # when beginning of history is reached like in Fish. + # + if [[ -z $_history_substring_search_query ]]; then + + # we have reached the absolute top of history + if [[ $HISTNO -eq 1 ]]; then + BUFFER= + + # going up from somewhere below the top of history + else + zle up-line-or-history + fi + + return true + fi + + false +} + +function _history-substring-search-down-history() { + # + # Behave like down-history in Zsh, except clear the + # $BUFFER when end of history is reached like in Fish. + # + if [[ -z $_history_substring_search_query ]]; then + + # going down from the absolute top of history + if [[ $HISTNO -eq 1 && -z $BUFFER ]]; then + BUFFER=${history[1]} + _history_substring_search_move_cursor_eol=true + + # going down from somewhere above the bottom of history + else + zle down-line-or-history + fi + + return true + fi + + false +} + +function _history-substring-search-up-search() { + _history_substring_search_move_cursor_eol=true + + # + # Highlight matches during history-substring-up-search: + # + # The following constants have been initialized in + # _history-substring-search-up/down-search(): + # + # $_history_substring_search_matches is the current list of matches + # $_history_substring_search_matches_count is the current number of matches + # $_history_substring_search_matches_count_plus is the current number of matches + 1 + # $_history_substring_search_matches_count_sans is the current number of matches - 1 + # $_history_substring_search_match_index is the index of the current match + # + # The range of values that $_history_substring_search_match_index can take + # is: [0, $_history_substring_search_matches_count_plus]. A value of 0 + # indicates that we are beyond the end of + # $_history_substring_search_matches. A value of + # $_history_substring_search_matches_count_plus indicates that we are beyond + # the beginning of $_history_substring_search_matches. + # + # In _history-substring-search-up-search() the initial value of + # $_history_substring_search_match_index is + # $_history_substring_search_matches_count_plus. This value is set in + # _history-substring-search-begin(). _history-substring-search-up-search() + # will initially decrease it to $_history_substring_search_matches_count. + # + if [[ $_history_substring_search_match_index -ge 2 ]]; then + # + # Highlight the next match: + # + # 1. Decrease the value of $_history_substring_search_match_index. + # + # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + # to highlight the current buffer. + # + (( _history_substring_search_match_index-- )) + BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]] + _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + + elif [[ $_history_substring_search_match_index -eq 1 ]]; then + # + # We will move beyond the end of $_history_substring_search_matches: + # + # 1. Decrease the value of $_history_substring_search_match_index. + # + # 2. Save the current buffer in $_history_substring_search_old_buffer, + # so that it can be retrieved by + # _history-substring-search-down-search() later. + # + # 3. Make $BUFFER equal to $_history_substring_search_query. + # + # 4. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND + # to highlight the current buffer. + # + (( _history_substring_search_match_index-- )) + _history_substring_search_old_buffer=$BUFFER + BUFFER=$_history_substring_search_query + _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND + + elif [[ $_history_substring_search_match_index -eq $_history_substring_search_matches_count_plus ]]; then + # + # We were beyond the beginning of $_history_substring_search_matches but + # UP makes us move back to $_history_substring_search_matches: + # + # 1. Decrease the value of $_history_substring_search_match_index. + # + # 2. Restore $BUFFER from $_history_substring_search_old_buffer. + # + # 3. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + # to highlight the current buffer. + # + (( _history_substring_search_match_index-- )) + BUFFER=$_history_substring_search_old_buffer + _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + fi +} + +function _history-substring-search-down-search() { + _history_substring_search_move_cursor_eol=true + + # + # Highlight matches during history-substring-up-search: + # + # The following constants have been initialized in + # _history-substring-search-up/down-search(): + # + # $_history_substring_search_matches is the current list of matches + # $_history_substring_search_matches_count is the current number of matches + # $_history_substring_search_matches_count_plus is the current number of matches + 1 + # $_history_substring_search_matches_count_sans is the current number of matches - 1 + # $_history_substring_search_match_index is the index of the current match + # + # The range of values that $_history_substring_search_match_index can take + # is: [0, $_history_substring_search_matches_count_plus]. A value of 0 + # indicates that we are beyond the end of + # $_history_substring_search_matches. A value of + # $_history_substring_search_matches_count_plus indicates that we are beyond + # the beginning of $_history_substring_search_matches. + # + # In _history-substring-search-down-search() the initial value of + # $_history_substring_search_match_index is + # $_history_substring_search_matches_count. This value is set in + # _history-substring-search-begin(). + # _history-substring-search-down-search() will initially increase it to + # $_history_substring_search_matches_count_plus. + # + if [[ $_history_substring_search_match_index -le $_history_substring_search_matches_count_sans ]]; then + # + # Highlight the next match: + # + # 1. Increase $_history_substring_search_match_index by 1. + # + # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + # to highlight the current buffer. + # + (( _history_substring_search_match_index++ )) + BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]] + _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + + elif [[ $_history_substring_search_match_index -eq $_history_substring_search_matches_count ]]; then + # + # We will move beyond the beginning of $_history_substring_search_matches: + # + # 1. Increase $_history_substring_search_match_index by 1. + # + # 2. Save the current buffer in $_history_substring_search_old_buffer, so + # that it can be retrieved by _history-substring-search-up-search() + # later. + # + # 3. Make $BUFFER equal to $_history_substring_search_query. + # + # 4. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND + # to highlight the current buffer. + # + (( _history_substring_search_match_index++ )) + _history_substring_search_old_buffer=$BUFFER + BUFFER=$_history_substring_search_query + _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND + + elif [[ $_history_substring_search_match_index -eq 0 ]]; then + # + # We were beyond the end of $_history_substring_search_matches but DOWN + # makes us move back to the $_history_substring_search_matches: + # + # 1. Increase $_history_substring_search_match_index by 1. + # + # 2. Restore $BUFFER from $_history_substring_search_old_buffer. + # + # 3. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + # to highlight the current buffer. + # + (( _history_substring_search_match_index++ )) + BUFFER=$_history_substring_search_old_buffer + _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + fi +} + +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et + diff --git a/plugins/history-substring-search/init.zsh b/plugins/history-substring-search/init.zsh new file mode 100644 index 000000000..8d3403f2d --- /dev/null +++ b/plugins/history-substring-search/init.zsh @@ -0,0 +1,19 @@ +# +# Integrates history-substring-search into Oh My Zsh. +# +# Authors: +# Suraj N. Kurapati +# Sorin Ionescu +# + +source "${0:h}/history-substring-search.zsh" + +if zstyle -t ':omz:plugin:history-substring-search' case-sensitive; then + unset HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS +fi + +if ! zstyle -t ':omz:plugin:history-substring-search' color; then + unset HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND + unset HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND +fi + diff --git a/plugins/macports/init.zsh b/plugins/macports/init.zsh new file mode 100644 index 000000000..c07ad2d62 --- /dev/null +++ b/plugins/macports/init.zsh @@ -0,0 +1,15 @@ +# +# Defines MacPorts aliases. +# +# Authors: +# Matt Cable +# + +# Aliases +alias pc="sudo port clean --all installed" +alias pi="sudo port install $1" +alias psu="sudo port selfupdate" +alias puni="sudo port uninstall inactive" +alias puo="sudo port upgrade outdated" +alias pup="psu && puo" + diff --git a/plugins/node/functions/node-docs b/plugins/node/functions/node-docs new file mode 100644 index 000000000..155b131b0 --- /dev/null +++ b/plugins/node/functions/node-docs @@ -0,0 +1,10 @@ +# +# Opens the Node.js online API documentation in the default browser. +# +# Authors: +# Sorin Ionescu +# + +# TODO: Make the sections easier to use. +open "http://nodejs.org/docs/$(node --version | sed 's/-.*//')/api/all.html#${1}" + diff --git a/plugins/node/init.zsh b/plugins/node/init.zsh new file mode 100644 index 000000000..0e1658837 --- /dev/null +++ b/plugins/node/init.zsh @@ -0,0 +1,17 @@ +# +# Completes npm. +# +# Authors: +# Sorin Ionescu +# + +cache_file="${0:h}/cache.zsh" +if [[ ! -f "$cache_file" ]] && (( $+commands[npm] )); then + # npm is slow; cache its output. + npm completion >! "$cache_file" 2> /dev/null + source "$cache_file" +else + source "$cache_file" +fi +unset cache_file + diff --git a/plugins/osx/README.md b/plugins/osx/README.md new file mode 100644 index 000000000..3c12b4d15 --- /dev/null +++ b/plugins/osx/README.md @@ -0,0 +1,13 @@ +Provides the following commands: + +- `tab` create a new tab (works in both _Terminal_ and _iTerm_). +- `pfd` print current _Finder_ directory. +- `pfs` print current _Finder_ selection. +- `cdf` cd to current _Finder_ directory. +- `pushdf` pushd to current _Finder_ directory. +- `ql` quick look at files. +- `manp` open MAN pages in _Preview.app_. +- `manb` open MAN pages in _Bwana.app_. +- `trash` move files and folders to _Trash_. +- `rm-osx-cruft` delete .DS_Store, \__MACOSX cruft. + diff --git a/plugins/osx/functions/manb b/plugins/osx/functions/manb new file mode 100644 index 000000000..f8377393e --- /dev/null +++ b/plugins/osx/functions/manb @@ -0,0 +1,24 @@ +# +# Opens man pages in Bwana.app. +# +# Authors: +# Sorin Ionescu +# + +function manb() { + local page + if (( $# > 0 )); then + for page in "$@"; do + open "man:$page" 2>/dev/null + if (( $? != 0 )); then + print "$0: Bwana is not installed" >&2 + break + fi + done + else + print 'What manual page do you want?' >&2 + fi +} +compdef _man manb +manb "$@" + diff --git a/plugins/osx/functions/manp b/plugins/osx/functions/manp new file mode 100644 index 000000000..87da47ab8 --- /dev/null +++ b/plugins/osx/functions/manp @@ -0,0 +1,20 @@ +# +# Opens man pages in Preview.app. +# +# Authors: +# Sorin Ionescu +# + +function manp() { + local page + if (( $# > 0 )); then + for page in "$@"; do + man -t "$page" | open -f -a Preview + done + else + print 'What manual page do you want?' >&2 + fi +} +compdef _man manp +manp "$@" + diff --git a/plugins/osx/functions/pfd b/plugins/osx/functions/pfd new file mode 100644 index 000000000..3e038a68b --- /dev/null +++ b/plugins/osx/functions/pfd @@ -0,0 +1,13 @@ +# +# Displays the current Finder.app directory. +# +# Authors: +# Sorin Ionescu +# + +osascript 2>/dev/null < +# + +osascript 2>/dev/null < +# + +local command="cd \\\"$PWD\\\"" +(( $# > 0 )) && command="${command}; $*" + +the_app=$( + osascript 2>/dev/null </dev/null </dev/null < +# + +print -N "${@:a}" | xargs -0 osascript -e ' + on run theFilePaths + tell application "Finder" + set thePOSIXFiles to {} + repeat with aFilePath in theFilePaths + set aPOSIXFile to aFilePath as POSIX file + if exists aPOSIXFile + set end of thePOSIXFiles to aPOSIXFile + end if + end repeat + move every item of thePOSIXFiles to trash + end tell + end run +' &>/dev/null + +if (( $? != 0)); then + print "$0: failed to move one or more items" >&2 + return 1 +fi + diff --git a/plugins/osx/init.zsh b/plugins/osx/init.zsh new file mode 100644 index 000000000..83d5b17ca --- /dev/null +++ b/plugins/osx/init.zsh @@ -0,0 +1,26 @@ +# +# Defines Mac OS X aliases and functions. +# +# Authors: +# Sorin Ionescu +# + +# Change directory to the current Finder directory. +alias cdf='cd "$(pfd)"' + +# Push directory to the current Finder directory. +alias pushdf='pushd "$(pfd)"' + +# Open files in Quick Look. +function ql() { + (( $# > 0 )) && qlmanage -p "$@" &> /dev/null +} + +# Delete .DS_Store and __MACOSX directories. +function rm-osx-cruft() { + find "${@:-$PWD}" \( \ + -type f -name '.DS_Store' -o \ + -type d -name '__MACOSX' \ + \) -print0 | xargs -0 rm -rf +} + diff --git a/plugins/pacman/functions/pacdisowned b/plugins/pacman/functions/pacdisowned new file mode 100644 index 000000000..81edf0ac6 --- /dev/null +++ b/plugins/pacman/functions/pacdisowned @@ -0,0 +1,23 @@ +# +# Lists pacman disowned files. +# +# Authors: +# Benjamin Boudreau +# Sorin Ionescu +# + +tmp="${TMPDIR-/tmp}/pacman-disowned-$UID-$$" +db="$tmp/db" +fs="$tmp/fs" + +mkdir "$tmp" +trap 'rm -rf "$tmp"' EXIT + +pacman -Qlq | sort -u > "$db" + +find /bin /etc /lib /sbin /usr \ + ! -name lost+found \ + \( -type d -printf '%p/\n' -o -print \) | sort > "$fs" + +comm -23 "$fs" "$db" + diff --git a/plugins/pacman/functions/paclist b/plugins/pacman/functions/paclist new file mode 100644 index 000000000..3f83dc8bc --- /dev/null +++ b/plugins/pacman/functions/paclist @@ -0,0 +1,11 @@ +# +# Lists explicitly installed pacman packages. +# +# Authors: +# Benjamin Boudreau +# Sorin Ionescu +# + +sudo pacman -Qei $(pacman -Qu|cut -d" " -f 1) \ + | awk ' BEGIN {FS=":"}/^Name/{printf("\033[1;36m%s\033[1;37m", $2)}/^Description/{print $2}' + diff --git a/plugins/pacman/init.zsh b/plugins/pacman/init.zsh new file mode 100644 index 000000000..645139ed9 --- /dev/null +++ b/plugins/pacman/init.zsh @@ -0,0 +1,110 @@ +# +# Defines pacman aliases. +# +# Authors: +# Benjamin Boudreau +# Sorin Ionescu +# +# Tips: +# https://wiki.archlinux.org/index.php/Pacman_Tips +# + +# Yaourt Aliases +if (( $+commands[yaourt] )); then + # Upgrade Arch Linux. + alias arch-upgrade='yaourt -Syu' + + # Fix all configuration files with vimdiff. + alias yaconf='yaourt -C' + + # Synchronize with repositories before upgrading packages that are out of date on the local system. + alias yaupg='yaourt -Syu' + + # Install specific package(s) from the repositories. + alias yain='yaourt -S' + + # Install specific package(s) not from the repositories but from a file . + alias yains='yaourt -U' + + # Remove the specified package(s), retaining its configuration(s) and required dependencies. + alias yare='yaourt -R' + + # Remove the specified package(s), its configuration(s) and unneeded dependencies. + alias yarem='yaourt -Rns' + + # Display information about a given package in the repositories. + alias yarep='yaourt -Si' + + # Search for package(s) in the repositories. + alias yareps='yaourt -Ss' + + # Display information about a given package in the local database. + alias yaloc='yaourt -Qi' + + # Search for package(s) in the local database. + alias yalocs='yaourt -Qs' + + # Force refresh of all package lists after updating /etc/pacman.d/mirrorlist + alias yamir='yaourt -Syy' + + # Install given package(s) as dependencies of another package + alias yainsd='yaourt -S --asdeps' + + # Update and refresh the local package and ABS databases against repositories. + if (( $+commands[abs] )); then + alias yaupd='yaourt -Sy && sudo abs' + else + alias yaupd='yaourt -Sy' + fi +else + # Upgrade Arch Linux. + alias arch-upgrade='sudo pacman -Syu' +fi + +# Pacman Aliases +# Synchronize with repositories before upgrading packages that are out of date on the local system. +alias pacupg='sudo pacman -Syu' + +# Install specific package(s) from the repositories. +alias pacin='sudo pacman -S' + +# Install specific package not from the repositories but from a file. +alias pacins='sudo pacman -U' + +# Remove the specified package(s), retaining its configuration(s) and required dependencies. +alias pacre='sudo pacman -R' + +# Remove the specified package(s), its configuration(s) and unneeded dependencies. +alias pacrem='sudo pacman -Rns' + +# Display information about a given package in the repositories. +alias pacrep='pacman -Si' + +# Search for package(s) in the repositories. +alias pacreps='pacman -Ss' + +# Display information about a given package in the local database. +alias pacloc='pacman -Qi' + +# Search for package(s) in the local database. +alias paclocs='pacman -Qs' + +# Install given package(s) as dependencies of another package. +alias pacinsd='sudo pacman -S --asdeps' + +# Force refresh of all package lists after updating /etc/pacman.d/mirrorlist. +alias pacmir='sudo pacman -Syy' + +# List orphan packages(s). +alias paclsorphans='sudo pacman -Qdt' + +# Remove orphan package(s). +alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)' + +# Update and refresh the local package and ABS databases against repositories. +if (( $+commands[abs] )); then + alias pacupd='sudo pacman -Sy && sudo abs' +else + alias pacupd='sudo pacman -Sy' +fi + diff --git a/plugins/perl/completions/_prep b/plugins/perl/completions/_prep new file mode 100644 index 000000000..8ecc7fd7b --- /dev/null +++ b/plugins/perl/completions/_prep @@ -0,0 +1,19 @@ +#compdef prep +#autoload + +# +# Completes prep. +# +# Authors: +# Sorin Ionescu +# + +_arguments \ + '-i[ignore case]' \ + '-m[^ and $ match the start and the end of a line]' \ + '-s[. matches newline]' \ + '-v[invert match]' \ + '-x[ignore whitespace and comments]' \ + '1::pattern:' \ + '2::files:_files' && return 0 + diff --git a/plugins/perl/completions/_psub b/plugins/perl/completions/_psub new file mode 100644 index 000000000..cd8bcfe78 --- /dev/null +++ b/plugins/perl/completions/_psub @@ -0,0 +1,20 @@ +#compdef psub +#autoload + +# +# Completes psub. +# +# Authors: +# Sorin Ionescu +# + +_arguments \ + '-g[match globally]' \ + '-i[ignore case]' \ + '-m[^ and $ match the start and the end of a line]' \ + '-s[. matches newline]' \ + '-x[ignore whitespace and comments]' \ + '1::pattern:' \ + '2::replacement:' \ + '3::files:_files' && return 0 + diff --git a/plugins/perl/functions/prep b/plugins/perl/functions/prep new file mode 100644 index 000000000..c61487bb0 --- /dev/null +++ b/plugins/perl/functions/prep @@ -0,0 +1,53 @@ +# +# Provides a grep-like pattern search. +# +# Authors: +# Sorin Ionescu +# + +local usage pattern modifiers invert + +usage="$( +cat <&2 + print "$usage" >&2 + return 1 + ;; + ([?]) + print "$0: unknown option: $OPTARG" >&2 + print "$usage" >&2 + return 1 + ;; + esac +done +shift $(( $OPTIND - 1 )) + +if (( $# < 1 )); then + print "$usage" >&2 + return 1 +fi + +pattern="$1" +shift + +perl -n -l -e "print if ${invert:+not} m/${pattern//\//\\/}/${modifiers}" "$@" + diff --git a/plugins/perl/functions/psub b/plugins/perl/functions/psub new file mode 100644 index 000000000..4f2c06e3c --- /dev/null +++ b/plugins/perl/functions/psub @@ -0,0 +1,54 @@ +# +# Provides a sed-like pattern substitution. +# +# Authors: +# Sorin Ionescu +# + +local usage pattern replacement modifiers + +usage="$( +cat <&2 + print "$usage" >&2 + return 1 + ;; + ([?]) + print "$0: unknown option: $OPTARG" >&2 + print "$usage" >&2 + return 1 + ;; + esac +done +shift $(( $OPTIND - 1 )) + +if (( $# < 2 )); then + print "$usage" >&2 + return 1 +fi + +pattern="$1" +replacement="$2" +repeat 2 shift + +perl -i'.orig' -n -l -e "s/${pattern//\//\\/}/${replacement//\//\\/}/${modifiers}; print" "$@" + diff --git a/plugins/perl/init.zsh b/plugins/perl/init.zsh new file mode 100644 index 000000000..b807bb693 --- /dev/null +++ b/plugins/perl/init.zsh @@ -0,0 +1,49 @@ +# +# Enables local Perl module installation on Mac OS X and defines aliases. +# +# Authors: +# Sorin Ionescu +# + +# For Perl older than 5.10.14, install local::lib. +# curl -L -C - -O http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/local-lib-1.008004.tar.gz +# tar xvf local-lib-1.008004.tar.gz +# cd local-lib-1.008004 +# perl Makefile.PL --bootstrap=$HOME/Library/Perl/5.12 +# make && make test && make install +# +# Install cpanminus: +# curl -L http://cpanmin.us | perl - --self-upgrade +# +if [[ "$OSTYPE" == darwin* ]]; then + # Perl is slow; cache its output. + cache_file="${0:h}/cache.zsh" + perl_path="$HOME/Library/Perl/5.12" + if [[ -f "$perl_path/lib/perl5/local/lib.pm" ]]; then + manpath=("$perl_path/man" $manpath) + if [[ ! -f "$cache_file" ]]; then + perl -I$perl_path/lib/perl5 -Mlocal::lib=$perl_path >! "$cache_file" + source "$cache_file" + else + source "$cache_file" + fi + fi + unset perl_path + unset cache_file + + # Set environment variables for launchd processes. + for env_var in PERL_LOCAL_LIB_ROOT PERL_MB_OPT PERL_MM_OPT PERL5LIB; do + launchctl setenv "$env_var" "${(P)env_var}" &! + done + unset env_var +fi + +# Aliases +alias pbi='perlbrew install' +alias pbl='perlbrew list' +alias pbo='perlbrew off' +alias pbs='perlbrew switch' +alias pbu='perlbrew use' +alias ple='perl -wlne' +alias pd='perldoc' + diff --git a/plugins/python/init.zsh b/plugins/python/init.zsh new file mode 100644 index 000000000..0c181fdb9 --- /dev/null +++ b/plugins/python/init.zsh @@ -0,0 +1,18 @@ +# +# Enables local Python package installation. +# +# Authors: +# Sorin Ionescu +# + +# Prepend PEP 370 per user site packages directory, which defaults to +# ~/Library/Python on Mac OS X and ~/.local elsewhere, to PATH/MANPATH. +if [[ "$OSTYPE" == darwin* ]]; then + path=($HOME/Library/Python/*/bin(N) $path) + manpath=($HOME/Library/Python/*/{,share/}man(N) $manpath) +else + # This is subject to change. + path=($HOME/.local/bin $path) + manpath=($HOME/.local/{,share/}man(N) $manpath) +fi + diff --git a/plugins/rails/init.zsh b/plugins/rails/init.zsh new file mode 100644 index 000000000..53bbda69e --- /dev/null +++ b/plugins/rails/init.zsh @@ -0,0 +1,30 @@ +# +# Defines Ruby on Rails aliases. +# +# Authors: +# Robby Russell +# Jake Bell +# Sorin Ionescu +# + +# Aliases (compatible with Rails 2) +alias rc='_rails-command console' +alias rd='_rails-command destroy' +alias rdb='_rails-command dbconsole' +alias rdbm='rake db:migrate db:test:clone' +alias rg='_rails-command generate' +alias rp='_rails-command plugin' +alias rr='_rails-command runner' +alias rs='_rails-command server' +alias rsd='_rails-command server --debugger' +alias devlog='tail -f log/development.log' + +# Functions +function _rails-command() { + if [[ -e "script/server" ]]; then + ruby script/"$@" + else + ruby script/rails "$@" + fi +} + diff --git a/plugins/rsync/init.zsh b/plugins/rsync/init.zsh new file mode 100644 index 000000000..caf705a96 --- /dev/null +++ b/plugins/rsync/init.zsh @@ -0,0 +1,27 @@ +# +# Defines rsync aliases. +# +# Authors: +# Sorin Ionescu +# + +# Aliases +rsync_cmd='rsync --verbose --progress --human-readable --compress --archive --hard-links --one-file-system' + +# Mac OS X and HFS+ Enhancements +# http://www.bombich.com/rsync.html +if [[ "$OSTYPE" == darwin* ]] && grep -q 'file-flags' <(rsync --help 2>&1); then + rsync_cmd="${rsync_cmd} --crtimes --acls --xattrs --fileflags --protect-decmpfs --force-change" +fi + +alias rsync-copy="${rsync_cmd}" +compdef _rsync rsync-copy=rsync +alias rsync-move="${rsync_cmd} --remove-source-files" +compdef _rsync rsync-move=rsync +alias rsync-update="${rsync_cmd} --update" +compdef _rsync rsync-upate=rsync +alias rsync-synchronize="${rsync_cmd} --update --delete" +compdef _rsync rsync-synchronize=rsync + +unset rsync_cmd + diff --git a/plugins/ruby/init.zsh b/plugins/ruby/init.zsh new file mode 100644 index 000000000..1d87e7183 --- /dev/null +++ b/plugins/ruby/init.zsh @@ -0,0 +1,43 @@ +# +# Configures Ruby gem installation and loads rvm/rbenv. +# +# Authors: +# Sorin Ionescu +# + +# Loads RVM into the shell session. +if [[ -s "$HOME/.rvm/scripts/rvm" ]]; then + # Auto adding variable-stored paths to ~ list conflicts with RVM. + unsetopt AUTO_NAME_DIRS + + # Source RVM. + source "$HOME/.rvm/scripts/rvm" +# Loads manually installed rbenv into the shell session. +elif [[ -s "$HOME/.rbenv/bin/rbenv" ]]; then + path=("$HOME/.rbenv/bin" $path) + eval "$(rbenv init - zsh)" +# Loads package manager installed rbenv into the shell session. +elif (( $+commands[rbenv] )); then + eval "$(rbenv init - zsh)" +else + # Install local gems according to Mac OS X conventions. + if [[ "$OSTYPE" == darwin* ]]; then + export GEM_HOME="$HOME/Library/Ruby/Gems/1.8" + path=("$GEM_HOME/bin" $path) + fi +fi + +# Aliases +alias b='bundle' +alias be='b exec' +alias bi='b install --path vendor/bundle' +alias bl='b list' +alias bo='b open' +alias bp='b package' +alias bu='b update' +alias bI='bi \ + && b package \ + && print .bundle >>! .gitignore \ + && print vendor/bundle >>! .gitignore \ + && print vendor/cache >>! .gitignore' + diff --git a/plugins/screen/init.zsh b/plugins/screen/init.zsh new file mode 100644 index 000000000..791ea3069 --- /dev/null +++ b/plugins/screen/init.zsh @@ -0,0 +1,35 @@ +# +# Defines GNU Screen aliases and provides for auto launching it at start-up. +# +# Authors: +# Sorin Ionescu +# +# Usage: +# To auto start it, add the following to zshrc: +# +# # Auto launch GNU Screen at start-up. +# zstyle -t ':omz:plugin:screen:auto' start 'yes' +# + +# Aliases +alias sl="screen -list" +alias sn="screen -U -S" +alias sr="screen -a -A -U -D -R" + +# Auto Start +if (( $SHLVL == 1 )) && zstyle -t ':omz:plugin:screen:auto' start; then + (( SHLVL += 1 )) && export SHLVL + + session="$( + screen -list 2> /dev/null \ + | sed '1d;$d' \ + | awk '{print $1}' \ + | head -1)" + + if [[ -n "$session" ]]; then + exec screen -x "$session" + else + exec screen -a -A -U -D -R -m "$SHELL" -l + fi +fi + diff --git a/plugins/ssh-agent/init.zsh b/plugins/ssh-agent/init.zsh new file mode 100644 index 000000000..4996f22fc --- /dev/null +++ b/plugins/ssh-agent/init.zsh @@ -0,0 +1,66 @@ +# +# Provides for an easier use of ssh-agent. +# +# Authors: +# Robby Russell +# Theodore Robert Campbell Jr +# Joseph M. Reagle Jr. +# Florent Thoumie +# Jonas Pfenniger +# gwjo +# Sorin Ionescu +# +# Usage: +# To enable agent forwarding, add the following to your .zshrc: +# +# zstyle ':omz:plugin:ssh-agent' forwarding 'yes' +# +# To load multiple identies, add the following to your .zshrc: +# +# zstyle ':omz:plugin:ssh-agent' identities 'id_rsa' 'id_rsa2' 'id_github' +# + +_ssh_agent_env="$HOME/.ssh/environment-$HOST" +_ssh_agent_forwarding= + +function _ssh-agent-start() { + local -a identities + + # Start ssh-agent and setup the environment. + rm -f "${_ssh_agent_env}" + ssh-agent > "${_ssh_agent_env}" + chmod 600 "${_ssh_agent_env}" + source "${_ssh_agent_env}" > /dev/null + + # Load identies. + zstyle -a ':omz:plugin:ssh-agent' identities 'identities' + + print starting ssh-agent... + + if [[ ! -n "${identities}" ]]; then + ssh-add + else + ssh-add "$HOME/.ssh/${^identities}" + fi +} + +# Test if agent-forwarding is enabled. +zstyle -b ':omz:plugin:ssh-agent' forwarding '_ssh_agent_forwarding' +if is-true "${_ssh_agent_forwarding}" && [[ -n "$SSH_AUTH_SOCK" ]]; then + # Add a nifty symlink for screen/tmux if agent forwarding. + [[ -L "$SSH_AUTH_SOCK" ]] || ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USER-screen +elif [ -f "${_ssh_agent_env}" ]; then + # Source SSH settings, if applicable. + source "${_ssh_agent_env}" > /dev/null + ps -ef | grep "${SSH_AGENT_PID}" | grep ssh-agent$ > /dev/null || { + _ssh-agent-start; + } +else + _ssh-agent-start; +fi + +# Tidy up after ourselves. +unfunction _ssh-agent-start +unset _ssh_agent_forwarding +unset _ssh_agent_env + diff --git a/plugins/tmux/init.zsh b/plugins/tmux/init.zsh new file mode 100644 index 000000000..d0c7988e4 --- /dev/null +++ b/plugins/tmux/init.zsh @@ -0,0 +1,33 @@ +# +# Defines tmux aliases and provides for auto launching it at start-up. +# +# Authors: +# Sorin Ionescu +# +# Usage: +# To auto start it, add the following to zshrc: +# +# # Auto launch tmux at start-up. +# zstyle -t ':omz:plugin:tmux:auto' start 'yes' +# + +# Aliases +alias ta="tmux attach-session" +alias tl="tmux list-sessions" + +# Auto Start +if (( $SHLVL == 1 )) && zstyle -t ':omz:plugin:tmux:auto' start; then + (( SHLVL += 1 )) && export SHLVL + + session="$( + tmux list-sessions 2> /dev/null \ + | cut -d':' -f1 \ + | head -1)" + + if [[ -n "$session" ]]; then + exec tmux attach-session -t "$session" + else + exec tmux new-session "$SHELL -l" + fi +fi + diff --git a/plugins/wakeonlan/README b/plugins/wakeonlan/README new file mode 100644 index 000000000..c728aea4d --- /dev/null +++ b/plugins/wakeonlan/README @@ -0,0 +1,30 @@ +This plugin provides a wrapper around the "wakeonlan" tool available from most +distributions' package repositories, or from the following website: + +http://gsd.di.uminho.pt/jpo/software/wakeonlan/ + +In order to use this wrapper, create the ~/.wakeonlan directory, and place in +that directory one file for each device you would like to be able to wake. Give +the file a name that describes the device, such as its hostname. Each file +should contain a line with the mac address of the target device and the network +broadcast address. + +For instance, there might be a file ~/.wakeonlan/leto with the following +contents: + +00:11:22:33:44:55:66 192.168.0.255 + +To wake that device, use the following command: + +# wake leto + +The available device names will be autocompleted, so: + +# wake + +...will suggest "leto", along with any other configuration files that were +placed in the ~/.wakeonlan directory. + +For more information regarding the configuration file format, check the +wakeonlan man page. + diff --git a/plugins/wakeonlan/completions/_wake b/plugins/wakeonlan/completions/_wake new file mode 100644 index 000000000..85aee5a16 --- /dev/null +++ b/plugins/wakeonlan/completions/_wake @@ -0,0 +1,13 @@ +#compdef wake +#autoload + +# +# Completes wake. +# +# Authors: +# Paul Gideon Dann +# Sorin Ionescu +# + +_arguments "1:device to wake:_files -W '$HOME/.wakeonlan'" && return 0 + diff --git a/plugins/wakeonlan/functions/wake b/plugins/wakeonlan/functions/wake new file mode 100644 index 000000000..7e03efaaa --- /dev/null +++ b/plugins/wakeonlan/functions/wake @@ -0,0 +1,21 @@ +# +# Wakes devices via wakeonlan. +# +# Authors: +# Paul Gideon Dann +# Sorin Ionescu +# + +local config_file="$HOME/.wakeonlan/$1" +if [[ ! -f "$config_file" ]]; then + print "$0: no such device file: $1" >&2 + return 1 +fi + +if (( ! $+commands[wakeonlan] )); then + print "$0: command not found: wakeonlan" >&2 + return 1 +fi + +wakeonlan -f "$config_file" + diff --git a/plugins/yum/init.zsh b/plugins/yum/init.zsh new file mode 100644 index 000000000..a71f67a5b --- /dev/null +++ b/plugins/yum/init.zsh @@ -0,0 +1,19 @@ +# +# Defines yum aliases. +# +# Authors: +# Simon +# Sorin Ionescu +# + +# Aliases +alias ys="yum search" # Search package. +alias yp="yum info" # Show package info. +alias yl="yum list" # List packages. +alias yli="yum list installed" # Print all installed packages. +alias yu="sudo yum update" # Upgrate packages. +alias yi="sudo yum install" # Install package. +alias yr="sudo yum remove" # Remove package. +alias yrl="sudo yum remove --remove-leaves" # Remove package and leaves. +alias yc="sudo yum clean all" # Clean cache. + diff --git a/plugins/z/init.zsh b/plugins/z/init.zsh new file mode 100644 index 000000000..e08e16a36 --- /dev/null +++ b/plugins/z/init.zsh @@ -0,0 +1,25 @@ +# +# Maintains a frequently used directory list for fast directory changes. +# +# Authors: +# Sorin Ionescu +# + +if [[ -f /etc/profile.d/z.zsh ]]; then + source /etc/profile.d/z.zsh +elif [[ -f /opt/local/etc/profile.d/z.zsh ]]; then + source /opt/local/etc/profile.d/z.zsh +elif [[ -f "$(brew --prefix 2> /dev/null)/etc/profile.d/z.sh" ]]; then + source "$(brew --prefix 2> /dev/null)/etc/profile.d/z.sh" +fi + +if (( $+functions[_z] )); then + alias z='nocorrect _z 2>&1' + alias j='z' + function z-precmd () { + z --add "$(pwd -P)" + } + autoload -Uz add-zsh-hook + add-zsh-hook precmd z-precmd +fi + diff --git a/spectrum.zsh b/spectrum.zsh new file mode 100644 index 000000000..ed0a4835b --- /dev/null +++ b/spectrum.zsh @@ -0,0 +1,65 @@ +# +# Provides for easier formatting and use of 256 colors. +# +# Authors: +# P.C. Shyamshankar +# Sorin Ionescu +# + +typeset -Ag FX FG BG + +FX=( + none "\e[00m" + normal "\e[22m" + bold "\e[01m" no-bold "\e[22m" + faint "\e[02m" no-faint "\e[22m" + standout "\e[03m" no-standout "\e[23m" + underline "\e[04m" no-underline "\e[24m" + blink "\e[05m" no-blink "\e[25m" + fast-blink "\e[06m" no-fast-blink "\e[25m" + reverse "\e[07m" no-reverse "\e[27m" + conceal "\e[08m" no-conceal "\e[28m" + strikethrough "\e[09m" no-strikethrough "\e[29m" + gothic "\e[20m" no-gothic "\e[22m" + double-underline "\e[21m" no-double-underline "\e[22m" + proportional "\e[26m" no-proportional "\e[50m" + overline "\e[53m" no-overline "\e[55m" + + no-border "\e[54m" + border-rectangle "\e[51m" no-border-rectangle "\e[54m" + border-circle "\e[52m" no-border-circle "\e[54m" + + no-ideogram-marking "\e[65m" + underline-or-right "\e[60m" no-underline-or-right "\e[65m" + double-underline-or-right "\e[61m" no-double-underline-or-right "\e[65m" + overline-or-left "\e[62m" no-overline-or-left "\e[65m" + double-overline-or-left "\e[63m" no-double-overline-or-left "\e[65m" + stress "\e[64m" no-stress "\e[65m" + + font-default "\e[10m" + font-first "\e[11m" no-font-first "\e[10m" + font-second "\e[12m" no-font-second "\e[10m" + font-third "\e[13m" no-font-third "\e[10m" + font-fourth "\e[14m" no-font-fourth "\e[10m" + font-fifth "\e[15m" no-font-fifth "\e[10m" + font-sixth "\e[16m" no-font-sixth "\e[10m" + font-seventh "\e[17m" no-font-seventh "\e[10m" + font-eigth "\e[18m" no-font-eigth "\e[10m" + font-ninth "\e[19m" no-font-ninth "\e[10m" +) + +FG[none]="$FX[none]" +BG[none]="$FX[none]" +colors=(black red green yellow blue magenta cyan white) +for color in {0..255}; do + if (( $color >= 0 )) && (( $color < $#colors )); then + index=$(( $color + 1 )) + FG[$colors[$index]]="\e[38;5;${color}m" + BG[$colors[$index]]="\e[48;5;${color}m" + fi + + FG[$color]="\e[38;5;${color}m" + BG[$color]="\e[48;5;${color}m" +done +unset colors color index + diff --git a/templates/zshrc.zsh b/templates/zshrc.zsh new file mode 100644 index 000000000..deced37fe --- /dev/null +++ b/templates/zshrc.zsh @@ -0,0 +1,35 @@ +# +# Sets Oh My Zsh options. +# +# Authors: +# Sorin Ionescu +# + +# Set the key mapping style to 'emacs' or 'vi'. +zstyle ':omz:editor' keymap 'emacs' + +# Auto convert .... to ../.. +zstyle ':omz:editor' dot-expansion 'no' + +# Set case-sensitivity for completion, history lookup, etc. +zstyle ':omz:*:*' case-sensitive 'no' + +# Color output (auto set to 'no' on dumb terminals). +zstyle ':omz:*:*' color 'yes' + +# Auto set the tab and window titles. +zstyle ':omz:terminal' auto-title 'yes' + +# Set the plugins to load (see $OMZ/plugins/). +zstyle ':omz:load' plugin 'archive' 'git' + +# Set the prompt theme to load. +# Setting it to 'random' loads a random theme. +# Auto set to 'off' on dumb terminals. +zstyle ':omz:prompt' theme 'sorin' + +# This will make you shout: OH MY ZSHELL! +source "$HOME/.oh-my-zsh/init.zsh" + +# Customize to your needs... + diff --git a/terminal.zsh b/terminal.zsh new file mode 100644 index 000000000..e70957709 --- /dev/null +++ b/terminal.zsh @@ -0,0 +1,101 @@ +# +# Sets terminal window and tab titles. +# +# Authors: +# James Cox +# Sorin Ionescu +# + +# Dumb terminals lack support. +if [[ "$TERM" == 'dumb' ]]; then + return +fi + +# Set the GNU Screen window number. +if [[ -n "$WINDOW" ]]; then + export SCREEN_NO="%B${WINDOW}%b " +else + export SCREEN_NO="" +fi + +# Sets the GNU Screen title. +function set-screen-title() { + if [[ "$TERM" == screen* ]]; then + printf "\ek%s\e\\" ${(V)argv} + fi +} + +# Sets the terminal window title. +function set-window-title() { + if [[ "$TERM" == ((x|a|ml|dt|E)term*|(u|)rxvt*) ]]; then + printf "\e]2;%s\a" ${(V)argv} + fi +} + +# Sets the terminal tab title. +function set-tab-title() { + if [[ "$TERM" == ((x|a|ml|dt|E)term*|(u|)rxvt*) ]]; then + printf "\e]1;%s\a" ${(V)argv} + fi +} + +# Sets the tab and window titles with the command name. +function set-title-by-command() { + emulate -L zsh + setopt LOCAL_OPTIONS EXTENDED_GLOB + + # Get the command name that is under job control. + if [[ "${1[(w)1]}" == (fg|%*)(\;|) ]]; then + # Get the job name, and, if missing, set it to the default %+. + local job_name="${${1[(wr)%*(\;|)]}:-%+}" + + # Make a local copy for use in the subshell. + local -A jobtexts_from_parent_shell + jobtexts_from_parent_shell=(${(kv)jobtexts}) + + jobs $job_name 2>/dev/null > >( + read index discarded + # The index is already surrounded by brackets: [1]. + set-title-by-command "${(e):-\$jobtexts_from_parent_shell$index}" + ) + else + # Set the command name, or in the case of sudo or ssh, the next command. + local cmd=${1[(wr)^(*=*|sudo|ssh|-*)]} + + # Right-truncate the command name to 15 characters. + if (( $#cmd > 15 )); then + cmd="${cmd[1,15]}..." + fi + + for kind in window tab screen; do + set-${kind}-title "$cmd" + done + fi +} + +# Don't override precmd/preexec; append to hook array. +autoload -Uz add-zsh-hook + +# Sets the tab and window titles before the prompt is displayed. +function set-title-precmd() { + if [[ "$TERM_PROGRAM" != "Apple_Terminal" ]] && zstyle -t ':omz:terminal' auto-title; then + set-window-title "${(%):-%~}" + for kind in tab screen; do + # Left-truncate the current working directory to 15 characters. + set-${kind}-title "${(%):-%15<...<%~%<<}" + done + else + # Set Apple Terminal current working directory. + printf '\e]7;%s\a' "file://$HOST${PWD// /%20}" + fi +} +add-zsh-hook precmd set-title-precmd + +# Sets the tab and window titles before command execution. +function set-title-preexec() { + if zstyle -t ':omz:terminal' auto-title; then + set-title-by-command "$2" + fi +} +add-zsh-hook preexec set-title-preexec + diff --git a/themes/minimal/prompt_minimal_setup b/themes/minimal/prompt_minimal_setup new file mode 100644 index 000000000..fbd60f2f1 --- /dev/null +++ b/themes/minimal/prompt_minimal_setup @@ -0,0 +1,43 @@ +# +# A monochrome theme that displays basic information. +# +# Authors: +# Brian Tse +# Sorin Ionescu +# + +function +vi-git-status() { + # Untracked files. + if [[ -n $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then + hook_com[unstaged]='%F{red}●%f' + fi +} + +function prompt_minimal_precmd () { + vcs_info +} + +function prompt_minimal_setup() { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + prompt_opts=(cr percent subst) + + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + add-zsh-hook precmd prompt_minimal_precmd + + zstyle ':vcs_info:*' enable bzr git hg svn + zstyle ':vcs_info:*' check-for-changes true + zstyle ':vcs_info:*' stagedstr '%F{green}●%f' + zstyle ':vcs_info:*' unstagedstr '%F{yellow}●%f' + zstyle ':vcs_info:*' formats ' - [%b%c%u]' + zstyle ':vcs_info:*' actionformats " - [%b%c%u|%F{cyan}%a%f]" + zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b|%F{cyan}%r%f' + zstyle ':vcs_info:git*+set-message:*' hooks git-status + + PROMPT='%2~${vcs_info_msg_0_} » ' +} + +prompt_minimal_setup "$@" + diff --git a/themes/nicoulaj/prompt_nicoulaj_setup b/themes/nicoulaj/prompt_nicoulaj_setup new file mode 100644 index 000000000..2a6c5bd72 --- /dev/null +++ b/themes/nicoulaj/prompt_nicoulaj_setup @@ -0,0 +1,54 @@ +# +# A simple theme that displays only relevant information. +# +# Authors: +# Julien Nicoulaud +# Sorin Ionescu +# +# Features: +# - One line. +# - VCS information in the right prompt. +# - Only shows the path on the left prompt by default. +# - Crops the path to a defined length and only shows the path relative to +# the current VCS repository root. +# - Uses a different color depending on if the last command succeeded/failed. +# - Shows user@hostname if connected through SSH. +# - Shows if logged in as root or not. +# + +function prompt_nicoulaj_setup() { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + prompt_opts=(cr percent subst) + + # Load required modules. + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + # Add hook for calling vcs_info before each command. + add-zsh-hook precmd vcs_info + + # Customizable parameters. + local max_path_chars=30 + local user_char='❯' + local root_char='❯❯❯' + local success_color='%F{071}' + local failure_color='%F{124}' + local vcs_info_color='%F{242}' + + # Set vcs_info parameters. + zstyle ':vcs_info:*' enable bzr git hg svn + zstyle ':vcs_info:*:*' check-for-changes true # Can be slow on big repos. + zstyle ':vcs_info:*:*' unstagedstr '!' + zstyle ':vcs_info:*:*' stagedstr '+' + zstyle ':vcs_info:*:*' actionformats "%S" "%r/%s/%b %u%c (%a)" + zstyle ':vcs_info:*:*' formats "%S" "%r/%s/%b %u%c" + zstyle ':vcs_info:*:*' nvcsformats "%~" "" + + # Define prompts. + PROMPT="%(?.${success_color}.${failure_color})${SSH_TTY:+[%n@%m]}%B%${max_path_chars}<...<"'${vcs_info_msg_0_%%.}'"%<<%(!.${root_char}.${user_char})%b%f " + RPROMPT="${vcs_info_color}"'${vcs_info_msg_1_}'"%f" +} + +prompt_nicoulaj_setup "$@" + diff --git a/themes/sorin/prompt_sorin_setup b/themes/sorin/prompt_sorin_setup new file mode 100644 index 000000000..a1aafbfe1 --- /dev/null +++ b/themes/sorin/prompt_sorin_setup @@ -0,0 +1,51 @@ +# +# A simple theme that only shows relevant information. +# +# Authors: +# Sorin Ionescu +# +# Screenshots: +# http://i.imgur.com/aipDQ.png +# + +function prompt_sorin_precmd () { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + + if (( $+functions[git-info] )); then + git-info + fi +} + +function prompt_sorin_setup() { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + prompt_opts=(cr percent subst) + + autoload -Uz add-zsh-hook + add-zsh-hook precmd prompt_sorin_precmd + + zstyle ':omz:completion' indicator '%B%F{red}...%f%b' + zstyle ':omz:prompt' vicmd '%F{yellow}❮%f%B%F{red}❮%f%b%F{red}❮%f' + zstyle ':omz:plugin:git:prompt' action ':%%B%F{yellow}%s%f%%b' + zstyle ':omz:plugin:git:prompt' added ' %%B%F{green}✚%f%%b' + zstyle ':omz:plugin:git:prompt' ahead ' %%B%F{yellow}⬆%f%%b' + zstyle ':omz:plugin:git:prompt' behind ' %%B%F{yellow}⬇%f%%b' + zstyle ':omz:plugin:git:prompt' branch ':%F{red}%b%f' + zstyle ':omz:plugin:git:prompt' deleted ' %%B%F{red}✖%f%%b' + zstyle ':omz:plugin:git:prompt' modified ' %%B%F{blue}✱%f%%b' + zstyle ':omz:plugin:git:prompt' renamed ' %%B%F{magenta}➜%f%%b' + zstyle ':omz:plugin:git:prompt' commit '%c' + zstyle ':omz:plugin:git:prompt' stashed ' %%B%F{cyan}✭%f%%b' + zstyle ':omz:plugin:git:prompt' unmerged ' %%B%F{yellow}═%f%%b' + zstyle ':omz:plugin:git:prompt' untracked ' %%B%F{white}◼%f%%b' + zstyle ':omz:plugin:git:prompt' prompt ' %F{blue}git%f%b%s' + zstyle ':omz:plugin:git:prompt' rprompt '%A%B%S%a%d%m%r%U%u' + + PROMPT='%F{cyan}%1~%f${git_prompt_info} %(!.%B%F{red}#%f%b.%B%F{green}❯%f%b) ' + RPROMPT='%(?::%F{red}⏎%f)${VIM:+" %B%F{green}V%f%b"}${git_rprompt_info}' + SPROMPT='zsh: correct %F{red}%R%f to %F{green}%r%f [nyae]? ' +} + +prompt_sorin_setup "$@" + diff --git a/themes/steeef/prompt_steeef_setup b/themes/steeef/prompt_steeef_setup new file mode 100644 index 000000000..9d52842ea --- /dev/null +++ b/themes/steeef/prompt_steeef_setup @@ -0,0 +1,113 @@ +# +# A theme based on Steve Losh's prompt with VCS_INFO integration. +# +# Authors: +# Steve Losh +# Bart Trojanowski +# Brian Carper +# steeef +# Sorin Ionescu +# + +function virtualenv_info() { + if [[ -n "$VIRTUAL_ENV" ]]; then + print "(${VIRTUAL_ENV:t}) " + fi +} + +function prompt_steeef_precmd() { + if [[ -n "$__PROMPT_STEEEF_VCS_UPDATE" ]] ; then + # Check for untracked files or updated submodules since vcs_info doesn't. + if [[ ! -z $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then + __PROMPT_STEEEF_VCS_UPDATE=1 + fmt_branch="(${__PROMPT_STEEEF_COLORS[1]}%b%f%u%c${__PROMPT_STEEEF_COLORS[4]}●%f)" + else + fmt_branch="(${__PROMPT_STEEEF_COLORS[1]}%b%f%u%c)" + fi + zstyle ':vcs_info:*:prompt:*' formats "${fmt_branch}" + + vcs_info 'prompt' + __PROMPT_STEEEF_VCS_UPDATE='' + fi +} + +function prompt_steeef_preexec() { + case "$(history $HISTCMD)" in + (*git*) + __PROMPT_STEEEF_VCS_UPDATE=1 + ;; + (*svn*) + __PROMPT_STEEEF_VCS_UPDATE=1 + ;; + esac +} + +function prompt_steeef_chpwd() { + __PROMPT_STEEEF_VCS_UPDATE=1 +} + +function prompt_steeef_setup() { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + prompt_opts=(cr percent subst) + + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + add-zsh-hook precmd prompt_steeef_precmd + add-zsh-hook preexec prompt_steeef_preexec + add-zsh-hook chpwd prompt_steeef_chpwd + + __PROMPT_STEEEF_VCS_UPDATE=1 + + # Use extended color pallete if available. + if [[ $TERM = *256color* || $TERM = *rxvt* ]]; then + __PROMPT_STEEEF_COLORS=( + "%F{81}" # turquoise + "%F{166}" # orange + "%F{135}" # purple + "%F{161}" # hotpink + "%F{118}" # limegreen + ) + else + __PROMPT_STEEEF_COLORS=( + "%F{cyan}" + "%F{yellow}" + "%F{magenta}" + "%F{red}" + "%F{green}" + ) + fi + + # Enable VCS systems you use. + zstyle ':vcs_info:*' enable bzr git hg svn + + # check-for-changes can be really slow. + # You should disable it if you work with large repositories. + zstyle ':vcs_info:*:prompt:*' check-for-changes true + + # Formats: + # %b - branchname + # %u - unstagedstr (see below) + # %c - stagedstr (see below) + # %a - action (e.g. rebase-i) + # %R - repository path + # %S - path in the repository + local fmt_branch="(${__PROMPT_STEEEF_COLORS[1]}%b%f%u%c)" + local fmt_action="(${__PROMPT_STEEEF_COLORS[5]}%a%f)" + local fmt_unstaged="${__PROMPT_STEEEF_COLORS[2]}●%f" + local fmt_staged="${__PROMPT_STEEEF_COLORS[5]}●%f" + + zstyle ':vcs_info:*:prompt:*' unstagedstr "${fmt_unstaged}" + zstyle ':vcs_info:*:prompt:*' stagedstr "${fmt_staged}" + zstyle ':vcs_info:*:prompt:*' actionformats "${fmt_branch}${fmt_action}" + zstyle ':vcs_info:*:prompt:*' formats "${fmt_branch}" + zstyle ':vcs_info:*:prompt:*' nvcsformats "" + + PROMPT=" +${__PROMPT_STEEEF_COLORS[3]}%n%f at ${__PROMPT_STEEEF_COLORS[2]}%m%f in ${__PROMPT_STEEEF_COLORS[5]}%~%f "'${vcs_info_msg_0_}'" +"'$(virtualenv_info)'"$ " +} + +prompt_steeef_setup "$@" + diff --git a/utility.zsh b/utility.zsh new file mode 100644 index 000000000..50a7654c0 --- /dev/null +++ b/utility.zsh @@ -0,0 +1,55 @@ +# +# Defines utility functions. +# +# Authors: +# Robby Russell +# Suraj N. Kurapati +# Sorin Ionescu +# + +# Lists the ten most used commands. +alias history-stat="history | awk '{print \$2}' | sort | uniq -c | sort -n -r | head" + +# Serves a directory via HTTP. +alias http-serve='python -m SimpleHTTPServer' + +# Makes a directory and changes to it. +function mkdcd() { + [[ -n "$1" ]] && mkdir -p "$1" && cd "$1" +} +compdef _mkdir mkdcd + +# Changes to a directory and lists its contents. +function cdll() { + builtin cd "$1" && ll +} +compdef _cd cdll + +# Pushes an entry onto the directory stack and lists its contents. +function pushdll() { + builtin pushd "$1" && ll +} +compdef _cd pushdll + +# Pops an entry off the directory stack and lists its contents. +function popdll() { + builtin popd "$1" && ll +} +compdef _cd popdll + +# Prints columns 1 2 3 ... n. +function slit() { + awk "{ print $(for n; do print -n "\$$n,"; done | sed 's/,$//') }" +} + +# Displays user owned process status. +function pmine() { + ps "$@" -U "$USER" -o pid,%cpu,%mem,command +} +compdef _ps pmine + +# Finds files and executes a command on them. +function find-exec() { + find . -type f -iname "*${1:-}*" -exec "${2:-file}" '{}' \; +} +