mirror of
https://github.com/DazAh/dotfiles
synced 2026-05-21 18:25:46 +01:00
upgradeohmyzsh
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
FROM gitpod/workspace-full
|
||||
|
||||
RUN sudo apt-get update && \
|
||||
sudo apt-get install -y zsh && \
|
||||
sudo rm -rf /var/lib/apt/lists/*
|
||||
@@ -0,0 +1,9 @@
|
||||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
|
||||
tasks:
|
||||
- init: |
|
||||
export EDITOR="command gp open -w" VISUAL="command gp open -w"
|
||||
cp -f /workspace/ohmyzsh/templates/zshrc.zsh-template ~/.zshrc
|
||||
ln -sf /workspace/ohmyzsh ~/.oh-my-zsh
|
||||
command: exec zsh
|
||||
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
x+)JMU014`040031QH,®ÌKŽ/.HMÖ+Jbàú®¬iÞ¤ä¤ÂlÃ|T‚;XíÅ PÈÌ+IM/J,ÉÌÏ+f`ñv”ÏoŠm\\�¹üàò°·ÉõÝPó²3srâ‹2óÒáfú2Vü|xï§OÏYÑžÒeµEÅ=¡Šs2óRã3ó2KàŠ›’Êÿˆ)¤ì\Àše]ñÃàgºÿw¨âÜÒœ’Ìx°˜sÍÜ•E,d‘ÉÔü^æ²ñÒ�2ˆsó .5›·`æÎ˜¹Y/>NZš/äh~/jÈ�øŒÔœ‚Ô"�×ïHíæÒ]3{—±²å¦Âßsd¯q×ü†˜U\ôwjzfj1ÃÞˆ
|
||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
x+)JMU014`040031QH,®ÌKŽ/.HMÖ+Jbàú®¬iÞ¤ä¤ÂlÃ|T‚;XíÅ PÈÌ+IM/J,ÉÌÏ+f`ñv”ÏoŠm\\�¹üàò°·ÉõÝPó²3srâ‹2óÒáfú2Vü|xï§OÏYÑžÒeµEÅ=¡Šs2óRã3ó2KàŠ›’Êÿˆ)¤ì\Àše]ñÃàgºÿw¨âÜÒœ’Ìx°˜sÍÜ•E,d‘ÉÔü^æ²ñÒ�2ˆsó .5›·`æÎ˜¹Y/>NZš/äh~/jÈ�øŒÔœ‚Ô"�×ïHíæÒ]3{—±²å¦Âßsd¯q×ü†˜U\ôwjzfj1Ãbc·%‹/Û¤è™Û|ìI‹óÇÉPãJR‹r3ósâ‹S‹‹�¡2ó§Ü³³;̯«ývªô1:bÐ�{…iÄÌòÌ”ôÔ’b“Ez·tV¿pkU¤£ûûuþŒ�Ó]×£;
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
x•�KnÃ0D»Ö)x�²¥øE7í²é²Ö‡Š…êcÈtƒÜ¾r� Ë!æq†49FO þB¤Æ¶Ñ-ö�r¢Ujp|8I©„º“m/šQ¸†-ª`"•åb”R¸ÁŇ֎�n:-:Ór3¶NJ‰œ©�æ\à½x5iE8cÖ=ÄÛ5*Ž&ÇWhNÃÐ÷�'8ðŽsV§µ$á¿ðaìŸ8»àxB˜nžæ¯Ù¯”Ë}•`ưÔÅ”A#Ä\JÖÛJŒ}>˜˜Í7<‘Ý¥*p> ¨d!de¡~Ðú‚†Âö˜œ�Ãeb>„Õ�”-%Ÿ®€Ḛ̂_´Ó>Yÿãí¦B%÷›¶hÆ¿Ô#û�¸Š#
|
||||
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
xu‘K¯›0…»æWXê¥1ó�î.$ȃ„¼H²3Æ&4@À„¼~}Ó[UÝ´³é;š3šÑ¡ç²Ì/À„ðËE0LCI RÄ U5ŒRSÁÌDIš(Š™@̨•"¬©&‚U`‘"KÓ79%ÐTS1ž(z‚tªBj©\Ó4ÿÌCÌU•“ UG¯ýáT}O5
|
||||
›:RSŒu‹K¤»Ï¸"§`ôº¬eà�½ åŸð‘•$/¾Ñsù(ØR�U�Ô!”^êë©ÀË/~—€·ê,X]<>²ürì’ÿز:kóô~•ãzAÞ¬/´×›¥û©K@·Ö¡Žm;ÛŽœhÌTálKgbhó+ÁͶS?l/�oêÔ§zy.Iíþaˆª�@²›æì¶
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
x+)JMU030d040031QпKMи,и/JноKкLgX%ЯЮИы≈ЩАЪ╬
|
||||
OДd╨\9y²╝┴(Х╔g√d■&1┬и.ЧZ╞╚┘∙ЦLгZ ЁЩОа▄*иLок/Jexё╡pЖ√⌠┘WрёUн╦в÷░ь8У╨)▓╙┌Э=≈ЭДЛт╒╢л°T├м1
|
||||
Вw}⌠)X╬©}╥╓Д-УТч`4у∙╧9g▌9].╠'ыч8ВDе ▀·cBPeнЧ.╝ЯЧnЯнЧ~.║н!z╧)
|
||||
keн╫╧тП/K{ъ╘■ц[<.чy^WМДИБИГR╨/Щ╔5≈⌠с▀÷≥лвvZОИJйЗУ╙тгсыу/ьU╞╓╒└аuWКБ▓юc▌в~╛≤q&Чju≤ф╩уPeA╝▌.╬╝ Ёз≤К%╖Уд7╣%L]╢ЖGy╚╩$⌠K▀KРs╬> ╞_$пYЫaИ╤
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
x•ОAjГ0Р®u
|
||||
нf4ЦH3PJ
|
||||
Ѕ€,Ќв@Y^¤§Ї[rЃьЭя‹ЗПлІ\»Eў·ЮT-fЋЮqu¤ERИ™kђ¤*XУ4Љѓ"bо©йЫЙk–ВIE3ЉґЊ�&F?ъRёr‰%›ґчymц+э|Оц]@]8эЧуѕiЫ†ЫЪфюэ.Ч>пУђЧеГ:в€LСћА�c=юv}]
|
||||
Y‚wТу¤мўЫ–.j~�PQ
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
x¥�Mj1…»�Sh—E ‘�RJέφ²G‰:γΰqΙι;΄„ +ρτήϋ�r�穃ρψΤ›¨‘rΘ'―•µΙη�‘lƒΟ�1�δ%ΫαΒM–'N�$e3κ,ΦLc`™bΘΘ‘\�™ρ‘7IyΆγtΩΐΞPHDHlΒθ��Δh£ψΪKmπΑχχ/›ο΄ςϋωv]¥‡¥6Ή|έη©—k:δ:Ώ‚ςhlF[Ψ£B¶νφ_—�“†Oig�ΤxΙv3―uυ¥χΛϊ|<ώr¬eΎέΧς�0-½Βoeψ®Φpώ
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
x•‘KOÃ0ǹ®Ÿ¢÷‰<Ú¥MBLÚŽ\ö
|
||||
ÜÄm£%m•¤öé)ì!và€/~üü·-Y�ÞÛ”‹¢|H1çUÅÚ²aµÖ¼\·š+#¹h–Œ6•â”É&8¤¼lx¥T#”(jDÉ”(UÝ(Å”µ¢’
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
github: [robbyrussell, mcornella, larson-carter]
|
||||
open_collective: ohmyzsh
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Get help on Discord
|
||||
url: https://discord.gg/ohmyzsh
|
||||
about: Have a quick question? Join the Discord server and ask on the appropriate channel.
|
||||
@@ -0,0 +1,397 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
function omz {
|
||||
[[ $# -gt 0 ]] || {
|
||||
_omz::help
|
||||
return 1
|
||||
}
|
||||
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
# Subcommand functions start with _ so that they don't
|
||||
# appear as completion entries when looking for `omz`
|
||||
(( $+functions[_omz::$command] )) || {
|
||||
_omz::help
|
||||
return 1
|
||||
}
|
||||
|
||||
_omz::$command "$@"
|
||||
}
|
||||
|
||||
function _omz {
|
||||
local -a cmds subcmds
|
||||
cmds=(
|
||||
'changelog:Print the changelog'
|
||||
'help:Usage information'
|
||||
'plugin:Manage plugins'
|
||||
'pr:Manage Oh My Zsh Pull Requests'
|
||||
'theme:Manage themes'
|
||||
'update:Update Oh My Zsh'
|
||||
)
|
||||
|
||||
if (( CURRENT == 2 )); then
|
||||
_describe 'command' cmds
|
||||
elif (( CURRENT == 3 )); then
|
||||
case "$words[2]" in
|
||||
changelog) local -a refs
|
||||
refs=("${(@f)$(command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}")
|
||||
_describe 'command' refs ;;
|
||||
plugin) subcmds=('list:List plugins')
|
||||
_describe 'command' subcmds ;;
|
||||
pr) subcmds=('test:Test a Pull Request' 'clean:Delete all Pull Request branches')
|
||||
_describe 'command' subcmds ;;
|
||||
theme) subcmds=('use:Load a theme' 'list:List themes')
|
||||
_describe 'command' subcmds ;;
|
||||
esac
|
||||
elif (( CURRENT == 4 )); then
|
||||
case "$words[2]::$words[3]" in
|
||||
theme::use) compadd "$ZSH"/themes/*.zsh-theme(.N:t:r) \
|
||||
"$ZSH_CUSTOM"/**/*.zsh-theme(.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
compdef _omz omz
|
||||
|
||||
## Utility functions
|
||||
|
||||
function _omz::confirm {
|
||||
# If question supplied, ask it before reading the answer
|
||||
# NOTE: uses the logname of the caller function
|
||||
if [[ -n "$1" ]]; then
|
||||
_omz::log prompt "$1" "${${functrace[1]#_}%:*}"
|
||||
fi
|
||||
|
||||
# Read one character
|
||||
read -r -k 1
|
||||
|
||||
# If no newline entered, add a newline
|
||||
if [[ "$REPLY" != $'\n' ]]; then
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
function _omz::log {
|
||||
# if promptsubst is set, a message with `` or $()
|
||||
# will be run even if quoted due to `print -P`
|
||||
setopt localoptions nopromptsubst
|
||||
|
||||
# $1 = info|warn|error|debug
|
||||
# $2 = text
|
||||
# $3 = (optional) name of the logger
|
||||
|
||||
local logtype=$1
|
||||
local logname=${3:-${${functrace[1]#_}%:*}}
|
||||
|
||||
# Don't print anything if debug is not active
|
||||
if [[ $logtype = debug && -z $_OMZ_DEBUG ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Choose coloring based on log type
|
||||
case "$logtype" in
|
||||
prompt) print -Pn "%S%F{blue}$logname%f%s: $2" ;;
|
||||
debug) print -P "%F{white}$logname%f: $2" ;;
|
||||
info) print -P "%F{green}$logname%f: $2" ;;
|
||||
warn) print -P "%S%F{yellow}$logname%f%s: $2" ;;
|
||||
error) print -P "%S%F{red}$logname%f%s: $2" ;;
|
||||
esac >&2
|
||||
}
|
||||
|
||||
## User-facing commands
|
||||
|
||||
function _omz::help {
|
||||
cat <<EOF
|
||||
Usage: omz <command> [options]
|
||||
|
||||
Available commands:
|
||||
|
||||
help Print this help message
|
||||
changelog Print the changelog
|
||||
plugin <command> Manage plugins
|
||||
pr <command> Manage Oh My Zsh Pull Requests
|
||||
theme <command> Manage themes
|
||||
update Update Oh My Zsh
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
function _omz::changelog {
|
||||
local version=${1:-HEAD} format=${3:-"--text"}
|
||||
|
||||
if ! command git -C "$ZSH" show-ref --verify refs/heads/$version &>/dev/null && \
|
||||
! command git -C "$ZSH" show-ref --verify refs/tags/$version &>/dev/null && \
|
||||
! command git -C "$ZSH" rev-parse --verify "${version}^{commit}" &>/dev/null; then
|
||||
cat <<EOF
|
||||
Usage: omz changelog [version]
|
||||
|
||||
NOTE: <version> must be a valid branch, tag or commit.
|
||||
EOF
|
||||
return 1
|
||||
fi
|
||||
|
||||
"$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
|
||||
}
|
||||
|
||||
function _omz::plugin {
|
||||
(( $# > 0 && $+functions[_omz::plugin::$1] )) || {
|
||||
cat <<EOF
|
||||
Usage: omz plugin <command> [options]
|
||||
|
||||
Available commands:
|
||||
|
||||
list List all available Oh My Zsh plugins
|
||||
|
||||
EOF
|
||||
return 1
|
||||
}
|
||||
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
_omz::plugin::$command "$@"
|
||||
}
|
||||
|
||||
function _omz::plugin::list {
|
||||
local -a custom_plugins builtin_plugins
|
||||
custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t))
|
||||
builtin_plugins=("$ZSH"/plugins/*(-/N:t))
|
||||
|
||||
# If the command is being piped, print all found line by line
|
||||
if [[ ! -t 1 ]]; then
|
||||
print -l ${(q-)custom_plugins} ${(q-)builtin_plugins}
|
||||
return
|
||||
fi
|
||||
|
||||
if (( ${#custom_plugins} )); then
|
||||
print -P "%U%BCustom plugins%b%u:"
|
||||
print -l ${(q-)custom_plugins} | column
|
||||
fi
|
||||
|
||||
if (( ${#builtin_plugins} )); then
|
||||
(( ${#custom_plugins} )) && echo # add a line of separation
|
||||
|
||||
print -P "%U%BBuilt-in plugins%b%u:"
|
||||
print -l ${(q-)builtin_plugins} | column
|
||||
fi
|
||||
}
|
||||
|
||||
function _omz::pr {
|
||||
(( $# > 0 && $+functions[_omz::pr::$1] )) || {
|
||||
cat <<EOF
|
||||
Usage: omz pr <command> [options]
|
||||
|
||||
Available commands:
|
||||
|
||||
clean Delete all PR branches (ohmyzsh/pull-*)
|
||||
test <PR_number_or_URL> Fetch PR #NUMBER and rebase against master
|
||||
|
||||
EOF
|
||||
return 1
|
||||
}
|
||||
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
_omz::pr::$command "$@"
|
||||
}
|
||||
|
||||
function _omz::pr::clean {
|
||||
(
|
||||
set -e
|
||||
builtin cd -q "$ZSH"
|
||||
|
||||
# Check if there are PR branches
|
||||
local fmt branches
|
||||
fmt="%(color:bold blue)%(align:18,right)%(refname:short)%(end)%(color:reset) %(color:dim bold red)%(objectname:short)%(color:reset) %(color:yellow)%(contents:subject)"
|
||||
branches="$(command git for-each-ref --sort=-committerdate --color --format="$fmt" "refs/heads/ohmyzsh/pull-*")"
|
||||
|
||||
# Exit if there are no PR branches
|
||||
if [[ -z "$branches" ]]; then
|
||||
_omz::log info "there are no Pull Request branches to remove."
|
||||
return
|
||||
fi
|
||||
|
||||
# Print found PR branches
|
||||
echo "$branches\n"
|
||||
# Confirm before removing the branches
|
||||
_omz::confirm "do you want remove these Pull Request branches? [Y/n] "
|
||||
# Only proceed if the answer is a valid yes option
|
||||
[[ "$REPLY" != [yY$'\n'] ]] && return
|
||||
|
||||
_omz::log info "removing all Oh My Zsh Pull Request branches..."
|
||||
command git branch --list 'ohmyzsh/pull-*' | while read branch; do
|
||||
command git branch -D "$branch"
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
function _omz::pr::test {
|
||||
# Allow $1 to be a URL to the pull request
|
||||
if [[ "$1" = https://* ]]; then
|
||||
1="${1:t}"
|
||||
fi
|
||||
|
||||
# Check the input
|
||||
if ! [[ -n "$1" && "$1" =~ ^[[:digit:]]+$ ]]; then
|
||||
echo >&2 "Usage: omz pr test <PR_NUMBER_or_URL>"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save current git HEAD
|
||||
local branch
|
||||
branch=$(builtin cd -q "$ZSH"; git symbolic-ref --short HEAD) || {
|
||||
_omz::log error "error when getting the current git branch. Aborting..."
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# Fetch PR onto ohmyzsh/pull-<PR_NUMBER> branch and rebase against master
|
||||
# If any of these operations fail, undo the changes made
|
||||
(
|
||||
set -e
|
||||
builtin cd -q "$ZSH"
|
||||
|
||||
# Get the ohmyzsh git remote
|
||||
command git remote -v | while read remote url _; do
|
||||
case "$url" in
|
||||
https://github.com/ohmyzsh/ohmyzsh(|.git)) found=1; break ;;
|
||||
git@github.com:ohmyzsh/ohmyzsh(|.git)) found=1; break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
(( $found )) || {
|
||||
_omz::log error "could not found the ohmyzsh git remote. Aborting..."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Fetch pull request head
|
||||
_omz::log info "fetching PR #$1 to ohmyzsh/pull-$1..."
|
||||
command git fetch -f "$remote" refs/pull/$1/head:ohmyzsh/pull-$1 || {
|
||||
_omz::log error "error when trying to fetch PR #$1."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Rebase pull request branch against the current master
|
||||
_omz::log info "rebasing PR #$1..."
|
||||
command git rebase master ohmyzsh/pull-$1 || {
|
||||
command git rebase --abort &>/dev/null
|
||||
_omz::log warn "could not rebase PR #$1 on top of master."
|
||||
_omz::log warn "you might not see the latest stable changes."
|
||||
_omz::log info "run \`zsh\` to test the changes."
|
||||
return 1
|
||||
}
|
||||
|
||||
_omz::log info "fetch of PR #${1} successful."
|
||||
)
|
||||
|
||||
# If there was an error, abort running zsh to test the PR
|
||||
[[ $? -eq 0 ]] || return 1
|
||||
|
||||
# Run zsh to test the changes
|
||||
_omz::log info "running \`zsh\` to test the changes. Run \`exit\` to go back."
|
||||
command zsh -l
|
||||
|
||||
# After testing, go back to the previous HEAD if the user wants
|
||||
_omz::confirm "do you want to go back to the previous branch? [Y/n] "
|
||||
# Only proceed if the answer is a valid yes option
|
||||
[[ "$REPLY" != [yY$'\n'] ]] && return
|
||||
|
||||
(
|
||||
set -e
|
||||
builtin cd -q "$ZSH"
|
||||
|
||||
command git checkout "$branch" -- || {
|
||||
_omz::log error "could not go back to the previous branch ('$branch')."
|
||||
return 1
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function _omz::theme {
|
||||
(( $# > 0 && $+functions[_omz::theme::$1] )) || {
|
||||
cat <<EOF
|
||||
Usage: omz theme <command> [options]
|
||||
|
||||
Available commands:
|
||||
|
||||
list List all available Oh My Zsh themes
|
||||
use <theme> Load an Oh My Zsh theme
|
||||
|
||||
EOF
|
||||
return 1
|
||||
}
|
||||
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
_omz::theme::$command "$@"
|
||||
}
|
||||
|
||||
function _omz::theme::list {
|
||||
local -a custom_themes builtin_themes
|
||||
custom_themes=("$ZSH_CUSTOM"/**/*.zsh-theme(.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::))
|
||||
builtin_themes=("$ZSH"/themes/*.zsh-theme(.N:t:r))
|
||||
|
||||
# If the command is being piped, print all found line by line
|
||||
if [[ ! -t 1 ]]; then
|
||||
print -l ${(q-)custom_themes} ${(q-)builtin_themes}
|
||||
return
|
||||
fi
|
||||
|
||||
if (( ${#custom_themes} )); then
|
||||
print -P "%U%BCustom themes%b%u:"
|
||||
print -l ${(q-)custom_themes} | column
|
||||
fi
|
||||
|
||||
if (( ${#builtin_themes} )); then
|
||||
(( ${#custom_themes} )) && echo # add a line of separation
|
||||
|
||||
print -P "%U%BBuilt-in themes%b%u:"
|
||||
print -l ${(q-)builtin_themes} | column
|
||||
fi
|
||||
}
|
||||
|
||||
function _omz::theme::use {
|
||||
if [[ -z "$1" ]]; then
|
||||
echo >&2 "Usage: omz theme use <theme>"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Respect compatibility with old lookup order
|
||||
if [[ -f "$ZSH_CUSTOM/$1.zsh-theme" ]]; then
|
||||
source "$ZSH_CUSTOM/$1.zsh-theme"
|
||||
elif [[ -f "$ZSH_CUSTOM/themes/$1.zsh-theme" ]]; then
|
||||
source "$ZSH_CUSTOM/themes/$1.zsh-theme"
|
||||
elif [[ -f "$ZSH/themes/$1.zsh-theme" ]]; then
|
||||
source "$ZSH/themes/$1.zsh-theme"
|
||||
else
|
||||
_omz::log error "theme '$1' not found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function _omz::update {
|
||||
# Run update script
|
||||
if [[ "$1" != --unattended ]]; then
|
||||
ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" --interactive
|
||||
else
|
||||
ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh"
|
||||
fi
|
||||
local ret=$?
|
||||
|
||||
# Update last updated file
|
||||
zmodload zsh/datetime
|
||||
echo "LAST_EPOCH=$(( EPOCHSECONDS / 60 / 60 / 24 ))" >! "${ZSH_CACHE_DIR}/.zsh-update"
|
||||
# Remove update lock if it exists
|
||||
command rm -rf "$ZSH/log/update.lock"
|
||||
|
||||
# Restart the zsh session
|
||||
if [[ $ret -eq 0 && "$1" != --unattended ]]; then
|
||||
# Check whether to run a login shell
|
||||
[[ "$ZSH_ARGZERO" = -* ]] && exec -l "${ZSH_ARGZERO#-}" || exec "$ZSH_ARGZERO"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
## Bazel autocomplete plugin
|
||||
|
||||
A copy of the completion script from the
|
||||
[bazelbuild/bazel](https://github.com/bazelbuild/bazel/master/scripts/zsh_completion/_bazel)
|
||||
git repo.
|
||||
@@ -0,0 +1,341 @@
|
||||
#compdef bazel
|
||||
|
||||
# Copyright 2015 The Bazel Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Installation
|
||||
# ------------
|
||||
#
|
||||
# 1. Add this script to a directory on your $fpath:
|
||||
# fpath[1,0]=~/.zsh/completion/
|
||||
# mkdir -p ~/.zsh/completion/
|
||||
# cp scripts/zsh_completion/_bazel ~/.zsh/completion
|
||||
#
|
||||
# 2. Optionally, add the following to your .zshrc.
|
||||
# zstyle ':completion:*' use-cache on
|
||||
# zstyle ':completion:*' cache-path ~/.zsh/cache
|
||||
#
|
||||
# This way, the completion script does not have to parse Bazel's options
|
||||
# repeatedly. The directory in cache-path must be created manually.
|
||||
#
|
||||
# 3. Restart the shell
|
||||
#
|
||||
# Options
|
||||
# -------
|
||||
# completion:init:bazel:* cache-lifetime
|
||||
# Lifetime for the completion cache (if turned on, default: 1 week)
|
||||
|
||||
local curcontext="$curcontext" state line
|
||||
|
||||
: ${BAZEL_COMPLETION_PACKAGE_PATH:=%workspace%}
|
||||
: ${BAZEL:=bazel}
|
||||
_bazel_b() { ${BAZEL} --noblock_for_lock "$@" 2>/dev/null; }
|
||||
|
||||
# Default cache lifetime is 1 week
|
||||
zstyle -s ":completion:${curcontext}:" cache-lifetime lifetime
|
||||
if [[ -z "${lifetime}" ]]; then
|
||||
lifetime=$((60*60*24*7))
|
||||
fi
|
||||
|
||||
_bazel_cache_policy() {
|
||||
local -a oldp
|
||||
oldp=( "$1"(Nms+${lifetime}) )
|
||||
(( $#oldp ))
|
||||
}
|
||||
|
||||
_set_cache_policy() {
|
||||
zstyle -s ":completion:*:$curcontext*" cache-policy update_policy
|
||||
|
||||
if [[ -z "$update_policy" ]]; then
|
||||
zstyle ":completion:$curcontext*" cache-policy _bazel_cache_policy
|
||||
fi
|
||||
}
|
||||
|
||||
# Skips over all global arguments. After invocation, OFFSET contains the
|
||||
# position of the bazel command in $words.
|
||||
_adapt_subcommand_offset() {
|
||||
OFFSET=2
|
||||
for w in ${words[2,-1]}; do
|
||||
if [[ $w == (#b)-* ]]; then
|
||||
(( OFFSET++ ))
|
||||
else
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Retrieve the cache but also check that the value is not empty.
|
||||
_bazel_safe_retrieve_cache() {
|
||||
_retrieve_cache $1 && [[ ${(P)#2} -gt 0 ]]
|
||||
}
|
||||
|
||||
# Puts the name of the variable that contains the options for the bazel
|
||||
# subcommand handed in as the first argument into the global variable
|
||||
# _bazel_cmd_options.
|
||||
_bazel_get_options() {
|
||||
local lcmd=$1
|
||||
_bazel_cmd_options=_bazel_${lcmd}_options
|
||||
_bazel_cmd_args=_bazel_${lcmd}_args
|
||||
if [[ ${(P)#_bazel_cmd_options} != 0 ]]; then
|
||||
return
|
||||
fi
|
||||
if _cache_invalid BAZEL_${lcmd}_options || _cache_invalid BAZEL_${lcmd}_args \
|
||||
|| ! _bazel_safe_retrieve_cache BAZEL_${lcmd}_options ${_bazel_cmd_options} \
|
||||
|| ! _retrieve_cache BAZEL_${lcmd}_args ${_bazel_cmd_args}; then
|
||||
if ! eval "$(_bazel_b help completion)"; then
|
||||
return
|
||||
fi
|
||||
local opts_var
|
||||
if [[ $lcmd == "startup_options" ]]; then
|
||||
opts_var="BAZEL_STARTUP_OPTIONS"
|
||||
else
|
||||
opts_var="BAZEL_COMMAND_${lcmd:u}_FLAGS"
|
||||
fi
|
||||
local -a raw_options
|
||||
if ! eval "raw_options=(\${(@f)$opts_var})"; then
|
||||
return
|
||||
fi
|
||||
|
||||
local -a option_list
|
||||
for opt in $raw_options; do
|
||||
case $opt in
|
||||
--*"={"*)
|
||||
local lst="${${opt##*"={"}%"}"}"
|
||||
local opt="${opt%%=*}="
|
||||
option_list+=("${opt}:string:_values '' ${lst//,/ }") ;;
|
||||
--*=path)
|
||||
option_list+=("${opt%path}:path:_files") ;;
|
||||
--*=label)
|
||||
option_list+=("${opt%label}:target:_bazel_complete_target") ;;
|
||||
--*=*)
|
||||
option_list+=("${opt}:string:") ;;
|
||||
*)
|
||||
option_list+=("$opt") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
local -a cmd_args
|
||||
local cmd_type
|
||||
if eval "cmd_type=\${BAZEL_COMMAND_${lcmd:u}_ARGUMENT}" && [[ -n $cmd_type ]]; then
|
||||
case $cmd_type in
|
||||
label|label-*)
|
||||
cmd_args+=("*::${cmd_type}:_bazel_complete_target_${cmd_type//-/_}") ;;
|
||||
info-key)
|
||||
cmd_args+=('1::key:_bazel_info_key') ;;
|
||||
path)
|
||||
cmd_args+=('1::profile:_path_files') ;;
|
||||
"command|{"*"}")
|
||||
local lst=${${cmd_type#"command|{"}%"}"}
|
||||
cmd_args+=("1::topic:_bazel_help_topic -- ${lst//,/ }") ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
typeset -g "${_bazel_cmd_options}"="${(pj:|:)option_list[*]}"
|
||||
_store_cache BAZEL_${lcmd}_options ${_bazel_cmd_options}
|
||||
typeset -g "${_bazel_cmd_args}"="${(pj:|:)cmd_args[*]}"
|
||||
_store_cache BAZEL_${lcmd}_args ${_bazel_cmd_args}
|
||||
fi
|
||||
}
|
||||
|
||||
_get_build_targets() {
|
||||
local pkg=$1
|
||||
local rule_re
|
||||
typeset -a completions
|
||||
case $target_type in
|
||||
test)
|
||||
rule_re=".*_test"
|
||||
;;
|
||||
build)
|
||||
rule_re=".*"
|
||||
;;
|
||||
bin)
|
||||
rule_re=".*_test|.*_binary"
|
||||
;;
|
||||
esac
|
||||
completions=(${$(_bazel_b query "kind(\"${rule_re}\", ${pkg}:all)" 2>/dev/null)##*:})
|
||||
if ( (( ${#completions} > 0 )) && [[ $target_type != run ]] ); then
|
||||
completions+=(all)
|
||||
fi
|
||||
echo ${completions[*]}
|
||||
}
|
||||
|
||||
# Returns all packages that match $PREFIX. PREFIX may start with //, in which
|
||||
# case the workspace roots are searched. Otherwise, they are completed based on
|
||||
# PWD.
|
||||
_get_build_packages() {
|
||||
local workspace pfx
|
||||
typeset -a package_roots paths final_paths
|
||||
workspace=$PWD
|
||||
package_roots=(${(ps.:.)BAZEL_COMPLETION_PACKAGE_PATH})
|
||||
package_roots=(${^package_roots//\%workspace\%/$workspace})
|
||||
if [[ "${(e)PREFIX}" == //* ]]; then
|
||||
pfx=${(e)PREFIX[2,-1]}
|
||||
else
|
||||
pfx=${(e)PREFIX}
|
||||
fi
|
||||
paths=(${^package_roots}/${pfx}*(/))
|
||||
for p in ${paths[*]}; do
|
||||
if [[ -f ${p}/BUILD || -f ${p}/BUILD.bazel ]]; then
|
||||
final_paths+=(${p##*/}:)
|
||||
fi
|
||||
final_paths+=(${p##*/}/)
|
||||
done
|
||||
echo ${final_paths[*]}
|
||||
}
|
||||
|
||||
_package_remove_slash() {
|
||||
if [[ $KEYS == ':' && $LBUFFER == */ ]]; then
|
||||
LBUFFER=${LBUFFER[1,-2]}
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion function for BUILD targets, called by the completion system.
|
||||
_bazel_complete_target() {
|
||||
local expl
|
||||
typeset -a packages targets
|
||||
if [[ "${(e)PREFIX}" != *:* ]]; then
|
||||
# There is no : in the prefix, completion can be either
|
||||
# a package or a target, if the cwd is a package itself.
|
||||
if [[ -f $PWD/BUILD || -f $PWD/BUILD.bazel ]]; then
|
||||
targets=($(_get_build_targets ""))
|
||||
_description build_target expl "BUILD target"
|
||||
compadd "${expl[@]}" -a targets
|
||||
fi
|
||||
packages=($(_get_build_packages))
|
||||
_description build_package expl "BUILD package"
|
||||
# Chop of the leading path segments from the prefix for display.
|
||||
compset -P '*/'
|
||||
compadd -R _package_remove_slash -S '' "${expl[@]}" -a packages
|
||||
else
|
||||
targets=($(_get_build_targets "${${(e)PREFIX}%:*}"))
|
||||
_description build_target expl "BUILD target"
|
||||
# Ignore the current prefix for the upcoming completion, since we only list
|
||||
# the names of the targets, not the full path.
|
||||
compset -P '*:'
|
||||
compadd "${expl[@]}" -a targets
|
||||
fi
|
||||
}
|
||||
|
||||
_bazel_complete_target_label() {
|
||||
typeset -g target_type=build
|
||||
_bazel_complete_target
|
||||
}
|
||||
|
||||
_bazel_complete_target_label_test() {
|
||||
typeset -g target_type=test
|
||||
_bazel_complete_target
|
||||
}
|
||||
|
||||
_bazel_complete_target_label_bin() {
|
||||
typeset -g target_type=bin
|
||||
_bazel_complete_target
|
||||
}
|
||||
|
||||
### Actual completion commands
|
||||
|
||||
_bazel() {
|
||||
_adapt_subcommand_offset
|
||||
if (( CURRENT - OFFSET > 0 )); then
|
||||
# Remember the subcommand name, stored globally so we can access it
|
||||
# from any subsequent function
|
||||
cmd=${words[OFFSET]//-/_}
|
||||
|
||||
# Set the context for the subcommand.
|
||||
curcontext="${curcontext%:*:*}:bazel-$cmd:"
|
||||
_set_cache_policy
|
||||
|
||||
# Narrow the range of words we are looking at to exclude cmd
|
||||
# name and any leading options
|
||||
(( CURRENT = CURRENT - OFFSET + 1 ))
|
||||
shift $((OFFSET - 1)) words
|
||||
# Run the completion for the subcommand
|
||||
_bazel_get_options $cmd
|
||||
_arguments : \
|
||||
${(Pps:|:)_bazel_cmd_options} \
|
||||
${(Pps:|:)_bazel_cmd_args}
|
||||
else
|
||||
_set_cache_policy
|
||||
# Start special handling for global options,
|
||||
# which can be retrieved by calling
|
||||
# $ bazel help startup_options
|
||||
_bazel_get_options startup_options
|
||||
_arguments : \
|
||||
${(Pps:|:)_bazel_cmd_options} \
|
||||
"*:commands:_bazel_commands"
|
||||
fi
|
||||
return
|
||||
}
|
||||
|
||||
_get_commands() {
|
||||
# bazel_cmd_list is a global (g) array (a)
|
||||
typeset -ga _bazel_cmd_list
|
||||
# Use `bazel help` instead of `bazel help completion` to get command
|
||||
# descriptions.
|
||||
if _bazel_cmd_list=("${(@f)$(_bazel_b help | awk '
|
||||
/Available commands/ { command=1; }
|
||||
/ [-a-z]+[ \t]+.+/ { if (command) { printf "%s:", $1; for (i=2; i<=NF; i++) printf "%s ", $i; print "" } }
|
||||
/^$/ { command=0; }')}"); then
|
||||
_store_cache BAZEL_commands _bazel_cmd_list
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion function for bazel subcommands, called by the completion system.
|
||||
_bazel_commands() {
|
||||
if [[ ${#_bazel_cmd_list} == 0 ]]; then
|
||||
if _cache_invalid BAZEL_commands \
|
||||
|| ! _bazel_safe_retrieve_cache BAZEL_commands _bazel_cmd_list; then
|
||||
_get_commands
|
||||
fi
|
||||
fi
|
||||
|
||||
_describe -t bazel-commands 'Bazel command' _bazel_cmd_list
|
||||
}
|
||||
|
||||
# Completion function for bazel help options, called by the completion system.
|
||||
_bazel_help_topic() {
|
||||
if [[ ${#_bazel_cmd_list} == 0 ]]; then
|
||||
if _cache_invalid BAZEL_commands \
|
||||
|| ! _bazel_safe_retrieve_cache BAZEL_commands _bazel_cmd_list; then
|
||||
_get_commands
|
||||
fi
|
||||
fi
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
if [[ $1 == -- ]]; then
|
||||
shift
|
||||
break
|
||||
fi
|
||||
shift
|
||||
done
|
||||
_bazel_help_list=($@)
|
||||
_bazel_help_list+=($_bazel_cmd_list)
|
||||
_describe -t bazel-help 'Help topic' _bazel_help_list
|
||||
}
|
||||
|
||||
# Completion function for bazel info keys, called by the completion system.
|
||||
_bazel_info_key() {
|
||||
if [[ ${#_bazel_info_keys_list} == 0 ]]; then
|
||||
if _cache_invalid BAZEL_info_keys \
|
||||
|| ! _bazel_safe_retrieve_cache BAZEL_info_keys _bazel_info_keys_list; then
|
||||
typeset -ga _bazel_info_keys_list
|
||||
# Use `bazel help` instead of `bazel help completion` to get info-key
|
||||
# descriptions.
|
||||
if _bazel_info_keys_list=("${(@f)$(_bazel_b help info-keys | awk '
|
||||
{ printf "%s:", $1; for (i=2; i<=NF; i++) printf "%s ", $i; print "" }')}"); then
|
||||
_store_cache BAZEL_info_keys _bazel_info_keys_list
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
_describe -t bazel-info 'Key' _bazel_info_keys_list
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# The whole point of this wrapper is to replace emboldening factor -u0 with
|
||||
# -u1 under certain circumstances on Solaris.
|
||||
|
||||
if [ "$1,$2,$3" = "-u0,-Tlp,-man" ]; then
|
||||
shift
|
||||
exec /usr/bin/nroff -u1 "$@"
|
||||
else
|
||||
# Some other invocation of nroff
|
||||
exec /usr/bin/nroff "$@"
|
||||
fi
|
||||
@@ -0,0 +1,3 @@
|
||||
print -P "%F{yellow}The 'fedora' plugin is deprecated. Use the '%Udnf%u' plugin instead.%f"
|
||||
|
||||
source "$ZSH/plugins/dnf/dnf.plugin.zsh"
|
||||
@@ -0,0 +1,65 @@
|
||||
# genpass
|
||||
|
||||
This plugin provides three unique password generators for ZSH. Each generator
|
||||
has at least a 128-bit security margin and generates passwords from the
|
||||
cryptographically secure `/dev/urandom`. Each generator can also take an
|
||||
optional numeric argument to generate multiple passwords.
|
||||
|
||||
Requirements:
|
||||
|
||||
* `grep(1)`
|
||||
* GNU coreutils (or appropriate for your system)
|
||||
* Word list providing `/usr/share/dict/words`
|
||||
|
||||
To use it, add `genpass` to the plugins array in your zshrc file:
|
||||
|
||||
plugins=(... genpass)
|
||||
|
||||
## genpass-apple
|
||||
|
||||
Generates a pronounceable pseudoword passphrase of the "cvccvc" consonant/vowel
|
||||
syntax, inspired by [Apple's iCloud Keychain password generator][1]. Each
|
||||
pseudoword has exactly 1 digit placed at the edge of a "word" and exactly 1
|
||||
capital letter to satisfy most password security requirements.
|
||||
|
||||
% genpass-apple
|
||||
gelcyv-foqtam-fotqoh-viMleb-lexduv-6ixfuk
|
||||
|
||||
% genpass-apple 3
|
||||
japvyz-qyjti4-kajrod-nubxaW-hukkan-dijcaf
|
||||
vydpig-fucnul-3ukpog-voggom-zygNad-jepgad
|
||||
zocmez-byznis-hegTaj-jecdyq-qiqmiq-5enwom
|
||||
|
||||
[1]: https://developer.apple.com/password-rules/
|
||||
|
||||
## genpass-monkey
|
||||
|
||||
Generates visually unambiguous random meaningless strings using [Crockford's
|
||||
base32][2].
|
||||
|
||||
% genpass-monkey
|
||||
xt7gn976e7jj3fstgpy27330x3
|
||||
|
||||
% genpass-monkey 3
|
||||
n1qqwtzgejwgqve9yzf2gxvx4m
|
||||
r2n3f5s6vbqs2yx7xjnmahqewy
|
||||
296w9y9rts3p5r9yay0raek8e5
|
||||
|
||||
[2]: https://www.crockford.com/base32.html
|
||||
|
||||
## genpass-xkcd
|
||||
|
||||
Generates passphrases from `/usr/share/dict/words` inspired by the [famous (and
|
||||
slightly misleading) XKCD comic][3]. Each passphrase is prepended with a digit
|
||||
showing the number of words in the passphrase to adhere to password security
|
||||
requirements that require digits. Each word is 6 characters or less.
|
||||
|
||||
% genpass-xkcd
|
||||
9-eaten-Slav-rife-aired-hill-cordon-splits-welsh-napes
|
||||
|
||||
% genpass-xkcd 3
|
||||
9-worker-Vlad-horde-shrubs-smite-thwart-paw-alters-prawns
|
||||
9-tutors-stink-rhythm-junk-snappy-hooray-barbs-mewl-clomp
|
||||
9-vital-escape-Angkor-Huff-wet-Mayra-abbés-putts-guzzle
|
||||
|
||||
[3]: https://xkcd.com/936/
|
||||
@@ -0,0 +1,95 @@
|
||||
autoload -U regexp-replace
|
||||
zmodload zsh/mathfunc
|
||||
|
||||
genpass-apple() {
|
||||
# Generates a 128-bit password of 6 pseudowords of 6 characters each
|
||||
# EG, xudmec-4ambyj-tavric-mumpub-mydVop-bypjyp
|
||||
# Can take a numerical argument for generating extra passwords
|
||||
local -i i j num
|
||||
|
||||
[[ $1 =~ '^[0-9]+$' ]] && num=$1 || num=1
|
||||
|
||||
local consonants="$(LC_ALL=C tr -cd b-df-hj-np-tv-xz < /dev/urandom \
|
||||
| head -c $((24*$num)))"
|
||||
local vowels="$(LC_ALL=C tr -cd aeiouy < /dev/urandom | head -c $((12*$num)))"
|
||||
local digits="$(LC_ALL=C tr -cd 0-9 < /dev/urandom | head -c $num)"
|
||||
|
||||
# The digit is placed on a pseudoword edge using $base36. IE, Dvccvc or cvccvD
|
||||
local position="$(LC_ALL=C tr -cd 056bchinotuz < /dev/urandom | head -c $num)"
|
||||
local -A base36=(0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 \
|
||||
e 14 f 15 g 16 h 17 i 18 j 19 k 20 l 21 m 22 n 23 o 24 p 25 q 26 r 27 s 28 \
|
||||
t 29 u 30 v 31 w 32 x 33 y 34 z 35)
|
||||
|
||||
for i in {1..$num}; do
|
||||
local pseudo=""
|
||||
|
||||
for j in {1..12}; do
|
||||
# Uniformly iterate through $consonants and $vowels for each $i and $j
|
||||
# Creates cvccvccvccvccvccvccvccvccvccvccvccvc for each $num
|
||||
pseudo="${pseudo}${consonants:$((24*$i+2*${j}-26)):1}"
|
||||
pseudo="${pseudo}${vowels:$((12*$i+${j}-13)):1}"
|
||||
pseudo="${pseudo}${consonants:$((24*$i+2*${j}-25)):1}"
|
||||
done
|
||||
|
||||
local -i digit_pos=${base36[${position[$i]}]}
|
||||
local -i char_pos=$digit_pos
|
||||
|
||||
# The digit and uppercase character must be in different locations
|
||||
while [[ $digit_pos == $char_pos ]]; do
|
||||
char_pos=$base36[$(LC_ALL=C tr -cd 0-9a-z < /dev/urandom | head -c 1)]
|
||||
done
|
||||
|
||||
# Places the digit on a pseudoword edge
|
||||
regexp-replace pseudo "^(.{$digit_pos}).(.*)$" \
|
||||
'${match[1]}${digits[$i]}${match[2]}'
|
||||
|
||||
# Uppercase a random character (that is not a digit)
|
||||
regexp-replace pseudo "^(.{$char_pos})(.)(.*)$" \
|
||||
'${match[1]}${(U)match[2]}${match[3]}'
|
||||
|
||||
# Hyphenate each 6-character pseudoword
|
||||
regexp-replace pseudo '^(.{6})(.{6})(.{6})(.{6})(.{6})(.{6})$' \
|
||||
'${match[1]}-${match[2]}-${match[3]}-${match[4]}-${match[5]}-${match[6]}'
|
||||
|
||||
printf "${pseudo}\n"
|
||||
done
|
||||
}
|
||||
|
||||
genpass-monkey() {
|
||||
# Generates a 128-bit base32 password as if monkeys banged the keyboard
|
||||
# EG, nz5ej2kypkvcw0rn5cvhs6qxtm
|
||||
# Can take a numerical argument for generating extra passwords
|
||||
local -i i num
|
||||
|
||||
[[ $1 =~ '^[0-9]+$' ]] && num=$1 || num=1
|
||||
|
||||
local pass=$(LC_ALL=C tr -cd '0-9a-hjkmnp-tv-z' < /dev/urandom \
|
||||
| head -c $((26*$num)))
|
||||
|
||||
for i in {1..$num}; do
|
||||
printf "${pass:$((26*($i-1))):26}\n"
|
||||
done
|
||||
}
|
||||
|
||||
genpass-xkcd() {
|
||||
# Generates a 128-bit XKCD-style passphrase
|
||||
# EG, 9-mien-flood-Patti-buxom-dozes-ickier-pay-ailed-Foster
|
||||
# Can take a numerical argument for generating extra passwords
|
||||
local -i i num
|
||||
|
||||
[[ $1 =~ '^[0-9]+$' ]] && num=$1 || num=1
|
||||
|
||||
# Get all alphabetic words of at most 6 characters in length
|
||||
local dict=$(LC_ALL=C grep -E '^[a-zA-Z]{1,6}$' /usr/share/dict/words)
|
||||
|
||||
# Calculate the base-2 entropy of each word in $dict
|
||||
# Entropy is e = L * log2(C), where L is the length of the password (here,
|
||||
# in words) and C the size of the character set (here, words in $dict).
|
||||
# Solve for e = 128 bits of entropy. Recall: log2(n) = log(n)/log(2).
|
||||
local -i n=$((int(ceil(128*log(2)/log(${(w)#dict})))))
|
||||
|
||||
for i in {1..$num}; do
|
||||
printf "$n-"
|
||||
printf "$dict" | shuf -n "$n" | paste -sd '-'
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
# git lfs plugin
|
||||
|
||||
The git lfs plugin provides [aliases](#aliases) and [functions](#functions) for [git-lfs](https://github.com/git-lfs/git-lfs).
|
||||
|
||||
To use it, add `git-lfs` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... git-lfs)
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Command |
|
||||
| :------- | :---------------------------------- |
|
||||
| `glfsi` | `git lfs install` |
|
||||
| `glfst` | `git lfs track` |
|
||||
| `glfsls` | `git lfs ls-files` |
|
||||
| `glfsmi` | `git lfs migrate import --include=` |
|
||||
|
||||
## Functions
|
||||
|
||||
| Function | Command |
|
||||
| :------- | :---------------------------------------------- |
|
||||
| `gplfs` | `git lfs push origin "$(current_branch)" --all` |
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Aliases
|
||||
#
|
||||
|
||||
alias glfsi='git lfs install'
|
||||
alias glfst='git lfs track'
|
||||
alias glfsls='git lfs ls-files'
|
||||
alias glfsmi='git lfs migrate import --include='
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
|
||||
function gplfs() {
|
||||
local b="$(git_current_branch)"
|
||||
git lfs push origin "$b" --all
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
print -P "%F{yellow}The 'go' plugin is deprecated. Use the '%Ugolang%u' plugin instead.%f"
|
||||
|
||||
source "$ZSH/plugins/golang/golang.plugin.zsh"
|
||||
@@ -0,0 +1,37 @@
|
||||
# Generic Colouriser plugin
|
||||
|
||||
This plugin adds wrappers for commands supported by [Generic Colouriser](https://github.com/garabik/grc):
|
||||
|
||||
To use it, add `grc` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... grc)
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
The following commands are wrapped by `grc` so that their output is automatically colored:
|
||||
|
||||
- `cc`
|
||||
- `configure`
|
||||
- `cvs`
|
||||
- `df`
|
||||
- `diff`
|
||||
- `dig`
|
||||
- `gcc`
|
||||
- `gmake`
|
||||
- `ifconfig`
|
||||
- `iwconfig`
|
||||
- `last`
|
||||
- `ldap`
|
||||
- `make`
|
||||
- `mount`
|
||||
- `mtr`
|
||||
- `netstat`
|
||||
- `ping`
|
||||
- `ping6`
|
||||
- `ps`
|
||||
- `traceroute`
|
||||
- `traceroute6`
|
||||
- `wdiff`
|
||||
- `whois`
|
||||
@@ -0,0 +1,44 @@
|
||||
# Adapted from: https://github.com/garabik/grc/blob/master/grc.zsh
|
||||
|
||||
if [[ "$TERM" = dumb ]] || (( ! $+commands[grc] )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# Supported commands
|
||||
cmds=(
|
||||
cc
|
||||
configure
|
||||
cvs
|
||||
df
|
||||
diff
|
||||
dig
|
||||
gcc
|
||||
gmake
|
||||
ifconfig
|
||||
iwconfig
|
||||
last
|
||||
ldap
|
||||
make
|
||||
mount
|
||||
mtr
|
||||
netstat
|
||||
ping
|
||||
ping6
|
||||
ps
|
||||
traceroute
|
||||
traceroute6
|
||||
wdiff
|
||||
whois
|
||||
)
|
||||
|
||||
# Set alias for supported commands
|
||||
for cmd in $cmds; do
|
||||
if (( $+commands[$cmd] )); then
|
||||
eval "function $cmd {
|
||||
grc --colour=auto \"${commands[$cmd]}\" \"\$@\"
|
||||
}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Clean up variables
|
||||
unset cmds cmd
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Aliases
|
||||
# (sorted alphabetically)
|
||||
#
|
||||
|
||||
alias https='http --default-scheme=https'
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Angel Ramboi
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# zsh-ipfs
|
||||
|
||||
zsh completion plugin for [The InterPlanetary File System (IPFS)][1]
|
||||
|
||||
Please submit issues and pull requests to the [main zsh-ipfs repo][2].
|
||||
|
||||
### About
|
||||
|
||||
[IPFS (InterPlanetary File System)][1] is a peer-to-peer hypermedia protocol
|
||||
designed to make the web faster, safer, and more open.
|
||||
|
||||
### License
|
||||
|
||||
See: https://github.com/hellounicorn/zsh-ipfs/blob/master/LICENSE
|
||||
|
||||
[1]: http://ipfs.io/
|
||||
[2]: https://github.com/hellounicorn/zsh-ipfs
|
||||
@@ -0,0 +1,717 @@
|
||||
#compdef ipfs
|
||||
#autoload
|
||||
|
||||
local -a _1st_arguments
|
||||
_1st_arguments=(
|
||||
'add:Add a file or directory to ipfs.'
|
||||
'bitswap:Interact with the bitswap agent.'
|
||||
'block:Interact with raw IPFS blocks.'
|
||||
'bootstrap:Show or edit the list of bootstrap peers.'
|
||||
'cat:Show IPFS object data.'
|
||||
'cid:Convert and discover properties of CIDs'
|
||||
'commands:List all available commands.'
|
||||
'config:Get and set ipfs config values.'
|
||||
'daemon:Run a network-connected IPFS node.'
|
||||
'dag:Interact with ipld dag objects. (experimental)'
|
||||
'dht:Issue commands directly through the DHT.'
|
||||
'diag:Generate diagnostic reports.'
|
||||
'dns:Resolve DNS links.'
|
||||
'files:Interact with unixfs files.'
|
||||
'filestore:Interact with filestore objects. (experimental)'
|
||||
'get:Download IPFS objects.'
|
||||
'id:Show ipfs node id info.'
|
||||
'init:Initializes ipfs config file.'
|
||||
'key:Create and list IPNS name keypairs.'
|
||||
'log:Interact with the daemon log output.'
|
||||
'ls:List directory contents for Unix filesystem objects.'
|
||||
'mount:Mounts IPFS to the filesystem (read-only).'
|
||||
'name:Publish and resolve IPNS names.'
|
||||
'object:Interact with IPFS objects.'
|
||||
'p2p:Libp2p stream mounting.'
|
||||
'pin:Pin (and unpin) objects to local storage.'
|
||||
'ping:Send echo request packets to IPFS hosts.'
|
||||
'refs:List links (references) from an object.'
|
||||
'repo:Manipulate the IPFS repo.'
|
||||
'resolve:Resolve the value of names to IPFS.'
|
||||
'stats:Query IPFS statistics.'
|
||||
'swarm:Interact with the swarm.'
|
||||
'tar:Utility functions for tar files in ipfs.'
|
||||
'update:Download and apply go-ipfs updates'
|
||||
'version:Show ipfs version information.'
|
||||
)
|
||||
|
||||
_ipfs_subcommand(){
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
_arguments -C ':command:->command' '*::options:->options'
|
||||
case $state in
|
||||
(command)
|
||||
_describe -t commands "ipfs subcommand" $1
|
||||
return
|
||||
;;
|
||||
(options)
|
||||
case $line[1] in
|
||||
(wantlist)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(bitswap)
|
||||
_arguments '(-p --peer)'{-p,--peer}'[Specify which peer to show wantlist for. Default: self.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(add)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(pin)
|
||||
_arguments \
|
||||
'(-r --recursive)'{-r,--recursive}'[Recursively pin the object linked to by the specified object(s). Default: true.]' \
|
||||
'--progress[Show progress.]'
|
||||
;;
|
||||
(bootstrap)
|
||||
local -a _bootstrap_rm_arguments
|
||||
_bootstrap_rm_arguments=(
|
||||
'default:Add default peers to the bootstrap list.'
|
||||
)
|
||||
_ipfs_subcommand _bootstrap_rm_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(rm)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(pin)
|
||||
_arguments '(-r --recursive)'{-r,--recursive}'[Recursively unpin the object linked to by the specified object(s). Default: true.]'
|
||||
;;
|
||||
(bootstrap)
|
||||
local -a _bootstrap_rm_arguments
|
||||
_bootstrap_rm_arguments=(
|
||||
'all:Remove all peers from the bootstrap list.'
|
||||
)
|
||||
_ipfs_subcommand _bootstrap_rm_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(ls)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(pin)
|
||||
_arguments \
|
||||
'(-t --type)'{-t,--type}'[The type of pinned keys to list. Can be "direct", "indirect", "recursive", or "all". Default: all.]' \
|
||||
'(-q --quiet)'{-q,--quiet}'[Write just hashes of objects.]'
|
||||
;;
|
||||
(p2p)
|
||||
_arguments '(-v --headers)'{-v,--headers}'[Print table headers (Protocol, Listen, Target).]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(update)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(pin)
|
||||
_arguments '--unpin[Remove the old pin. Default: true.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(verify)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(pin)
|
||||
_arguments \
|
||||
'--verbose[Also write the hashes of non-broken pins.]' \
|
||||
'(-q --quiet)'{-q,--quiet}'[Write just hashes of broken pins.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(get|query|findpeer)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(dht)
|
||||
_arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
|
||||
;;
|
||||
(object)
|
||||
_arguments '--data-encoding[Encoding type of the data field, either "text" or "base64". Default: text.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(put)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(dht)
|
||||
_arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
|
||||
;;
|
||||
(object)
|
||||
_arguments \
|
||||
'--inputenc[Encoding type of input data. One of: {"protobuf", "json"}. Default: json.]' \
|
||||
'--datafieldenc[Encoding type of the data field, either "text" or "base64". Default: text.]' \
|
||||
'--pin[Pin this object when adding.]' \
|
||||
'(-q --quiet)'{-q,--quiet}'[Write minimal output]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(findprovs)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(dht)
|
||||
_arguments \
|
||||
'(-v --verbose)'{-v,--verbose}'[Print extra information.]' \
|
||||
'(-n --num-providers)'{-n,--num-providers}'[The number of providers to find. Default: 20.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(provide)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(dht)
|
||||
_arguments \
|
||||
'(-v --verbose)'{-v,--verbose}'[Print extra information.]' \
|
||||
'(-r --recursive)'{-r,--recursive}'[Recursively provide entire graph.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(cmds|diff)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(diag|object)
|
||||
_arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(stat)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(object)
|
||||
_arguments '--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
|
||||
;;
|
||||
(repo)
|
||||
_arguments \
|
||||
'--size-only[Only report RepoSize and StorageMax.]' \
|
||||
'--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(publish)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(name)
|
||||
_arguments \
|
||||
'--resolve[Check if the given path can be resolved before publishing. Default: true.]' \
|
||||
'(-t --lifetime)'{-t,--lifetime}'[Time duration that the record will be valid for. Default: 24h.]' \
|
||||
'--allow-offline[When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing.]' \
|
||||
'--ttl[Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental).]' \
|
||||
'(-k --key)'{-k,--key}"[Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'. Default: self.]" \
|
||||
'(-Q --quieter)'{-Q,--quieter}'[Write only final hash.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(pubsub)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(name)
|
||||
local -a _name_pubsub_arguments
|
||||
_name_pubsub_arguments=(
|
||||
'cancel:Cancel a name subscription'
|
||||
'state:Query the state of IPNS pubsub'
|
||||
'subs:Show current name subscriptions'
|
||||
)
|
||||
_ipfs_subcommand _name_pubsub_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(resolve)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(name)
|
||||
_arguments \
|
||||
'(-r --recursive)'{-r,--recursive}'[Resolve until the result is not an IPNS name. Default: true.]' \
|
||||
'(-n --nocache)'{-n,--nocache}'[Do not use cached entries.]' \
|
||||
'(--dhtrc --dht-record-count)'{--dhtrc,--dht-record-count}'[Number of records to request for DHT resolution.]' \
|
||||
'(--dhtt --dht-timeout)'{--dhtt,--dht-timeout}'[Max time to collect values during DHT resolution eg "30s". Pass 0 for no timeout.]' \
|
||||
'(-s --stream)'{-s,--stream}'[Stream entries as they are found.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(patch)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(object)
|
||||
local -a _object_patch_arguments
|
||||
_object_patch_arguments=(
|
||||
'add-link:Add a link to a given object.'
|
||||
'append-data:Append data to the data segment of a dag node.'
|
||||
'rm-link:Remove a link from a given object.'
|
||||
'set-data:Set the data field of an IPFS object.'
|
||||
)
|
||||
_ipfs_subcommand _object_patch_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(gc)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(repo)
|
||||
_arguments \
|
||||
'--stream-errors[Stream errors.]' \
|
||||
'(-q --quiet)'{-q,--quiet}'[Write minimal output.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(bitswap)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(stats)
|
||||
_arguments \
|
||||
'(-v --verbose)'{-v,--verbose}'[Print extra information.]' \
|
||||
'--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(bw)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(stats)
|
||||
_arguments \
|
||||
'(-p --peer)'{-p,--peer}'[Specify a peer to print bandwidth for.]' \
|
||||
'(-t --proto)'{-t,--proto}'[Specify a protocol to print bandwidth for.]' \
|
||||
'--poll[Print bandwidth at an interval.]' \
|
||||
'(-i --interval)'{-i,--interval}'[Time interval to wait between updating output, if 'poll' is true.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(repo)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(stats)
|
||||
_arguments \
|
||||
'--size-only[Only report RepoSize and StorageMax.]' \
|
||||
'--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(bases)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(cid)
|
||||
_arguments \
|
||||
'--prefix[also include the single leter prefixes in addition to the code.]' \
|
||||
'--numeric[also include numeric codes.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(codecs|hashes)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(cid)
|
||||
_arguments '--numeric[also include numeric codes.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(format)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(cid)
|
||||
_arguments \
|
||||
'-f[Printf style format string. Default: %s.]' \
|
||||
'-v[CID version to convert to.]' \
|
||||
'-b[Multibase to display CID in.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(close)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(p2p)
|
||||
_arguments \
|
||||
'(-a --all)'{-a,--all}'[Close all listeners.]' \
|
||||
'(-p --protocol)'{-p,--protocol}'[Match protocol name.]' \
|
||||
'(-l --listen-address)'{-l,--listen-address}'[Match listen address.]' \
|
||||
'(-t --target-address)'{-t,--target-address}'[Match target address.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(forward)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(p2p)
|
||||
_arguments "--allow-custom-protocol[Don't require /x/ prefix.]"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(listen)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(p2p)
|
||||
_arguments \
|
||||
"--allow-custom-protocol[Don't require /x/ prefix.]" \
|
||||
'(-r --report-peer-id)'{-r,--report-peer-id}'[Send remote base58 peerid to target when a new connection is established.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(stream)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(p2p)
|
||||
local -a _p2p_stream_arguments
|
||||
_p2p_stream_arguments=(
|
||||
'close:Close active p2p stream.'
|
||||
'ls:List active p2p streams.'
|
||||
)
|
||||
_ipfs_subcommand _p2p_stream_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(addrs)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(swarm)
|
||||
local -a _swarm_addrs_arguments
|
||||
_swarm_addrs_arguments=(
|
||||
'listen:List interface listening addresses.'
|
||||
'local:List local addresses.'
|
||||
)
|
||||
_ipfs_subcommand _swarm_addrs_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(filters)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(swarm)
|
||||
local -a _swarm_filters_arguments
|
||||
_swarm_filters_arguments=(
|
||||
'add:Add an address filter.'
|
||||
'rm:Remove an address filter.'
|
||||
)
|
||||
_ipfs_subcommand _swarm_filters_arguments
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(peers)
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(swarm)
|
||||
_arguments \
|
||||
'(-v --verbose)'{-v,--verbose}'[display all extra information.]' \
|
||||
'--streams[Also list information about open streams for each peer.]' \
|
||||
'--latency[Also list information about latency to each peer.]' \
|
||||
'--direction[Also list information about the direction of connection.]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
local expl
|
||||
|
||||
_arguments \
|
||||
'(-c --config)'{-c,--config}'[Path to the configuration file to use.]' \
|
||||
'(-D --debug)'{-D,--debug}'[Operate in debug mode.]' \
|
||||
'(--help)--help[Show the full command help text.]' \
|
||||
'(--h)-h[Show a short version of the command help text.]' \
|
||||
'(-L --local)'{-L,--local}'[Run the command locally, instead of using the daemon. DEPRECATED: use --offline.]' \
|
||||
'(--offline)--offline[Run the command offline.]' \
|
||||
'(--api)--api[Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001).]' \
|
||||
'(--cid-base)--cid-base[Multibase encoding used for version 1 CIDs in output.]' \
|
||||
'(--upgrade-cidv0-in-output)--upgrade-cidv0-in-output[Upgrade version 0 to version 1 CIDs in output.]' \
|
||||
'(--enc --encoding)'{--enc,--encoding}'[The encoding type the output should be encoded with (json, xml, or text). Default: text.]' \
|
||||
'(--stream-channels)--stream-channels[Stream channel output.]' \
|
||||
'(--timeout)--timeout[Set a global timeout on the command.]' \
|
||||
'*:: :->subcmds' && return 0
|
||||
|
||||
if (( CURRENT == 1 )); then
|
||||
_describe -t commands "ipfs subcommand" _1st_arguments
|
||||
return
|
||||
fi
|
||||
|
||||
MAIN_SUBCOMMAND="$words[1]"
|
||||
case $MAIN_SUBCOMMAND in
|
||||
(add)
|
||||
_arguments \
|
||||
'(-r --recursive)'{-r,--recursive}'[Add directory paths recursively.]' \
|
||||
'(--dereference-args)--dereference-args[Symlinks supplied in arguments are dereferenced.]' \
|
||||
'(--stdin-name)--stdin-name[Assign a name if the file source is stdin.]' \
|
||||
'(-H --hidden)'{-H,--hidden}'[Include files that are hidden. Only takes effect on recursive add.]' \
|
||||
'(-q --quiet)'{-q,--quiet}'[Write minimal output.]' \
|
||||
'(-Q --quieter)'{-Q,--quieter}'[Write only final hash.]' \
|
||||
'(--silent)--silent[Write no output.]' \
|
||||
'(-p --progress)'{-p,--progress}'[Stream progress data.]' \
|
||||
'(-t --trickle)'{-t,--trickle}'[Use trickle-dag format for dag generation.]' \
|
||||
'(-n --only-hash)'{-n,--only-hash}'[Only chunk and hash - do not write to disk.]' \
|
||||
'(-w --wrap-with-directory)'{-w,--wrap-with-directory}'[Wrap files with a directory object.]' \
|
||||
'(-s --chunker)'{-s,--chunker}'[Chunking algorithm, size-(bytes) or rabin-(min)-(avg)-(max). Default: size-262144.]' \
|
||||
'(--pin)--pin[Pin this object when adding. Default: true.]' \
|
||||
'(--raw-leaves)--raw-leaves[Use raw blocks for leaf nodes. (experimental).]' \
|
||||
'(--nocopy)--nocopy[Add the file using filestore. Implies raw-leaves. (experimental).]' \
|
||||
'(--fscache)--fscache[Check the filestore for pre-existing blocks. (experimental).]' \
|
||||
'(--cid-version)--cid-version[CID version. Defaults to 0 unless an option that depends on CIDv1 is passed. (experimental).]' \
|
||||
'(--hash)--hash[Hash function to use. Implies CIDv1 if not sha2-256. (experimental). Default: sha2-256.]' \
|
||||
'(--inline)--inline[Inline small blocks into CIDs. (experimental).]' \
|
||||
'(--inline-limit)--inline-limit[Maximum block size to inline. (experimental). Default: 32.]'
|
||||
;;
|
||||
(bitswap)
|
||||
local -a _bitswap_arguments
|
||||
_bitswap_arguments=(
|
||||
'ledger:Show the current ledger for a peer.'
|
||||
'reprovide:Trigger reprovider.'
|
||||
'stat:Show some diagnostic information on the bitswap agent.'
|
||||
'wantlist:Show blocks currently on the wantlist.'
|
||||
)
|
||||
_ipfs_subcommand _bitswap_arguments
|
||||
;;
|
||||
(block)
|
||||
local -a _block_arguments
|
||||
_block_arguments=(
|
||||
'get:Get a raw IPFS block.'
|
||||
'put:Store input as an IPFS block.'
|
||||
'rm:Remove IPFS block(s).'
|
||||
'stat:Print information of a raw IPFS block.'
|
||||
)
|
||||
_ipfs_subcommand _block_arguments
|
||||
;;
|
||||
(bootstrap)
|
||||
local -a _bootstrap_arguments
|
||||
_bootstrap_arguments=(
|
||||
'add:Add peers to the bootstrap list.'
|
||||
'list:Show peers in the bootstrap list.'
|
||||
'rm:Remove peers from the bootstrap list.'
|
||||
)
|
||||
_ipfs_subcommand _bootstrap_arguments
|
||||
;;
|
||||
(cat)
|
||||
_arguments \
|
||||
'(-o --offset)'{-o,--offset}'[Byte offset to begin reading from.]' \
|
||||
'(-l --length)'{-l,--length}'[Maximum number of bytes to read.]'
|
||||
;;
|
||||
(cid)
|
||||
local -a _cid_arguments
|
||||
_cid_arguments=(
|
||||
'base32:Convert CIDs to Base32 CID version 1.'
|
||||
'bases:List available multibase encodings.'
|
||||
'codecs:List available CID codecs.'
|
||||
'format:Format and convert a CID in various useful ways.'
|
||||
'hashes:List available multihashes.'
|
||||
)
|
||||
_ipfs_subcommand _cid_arguments
|
||||
;;
|
||||
(commands)
|
||||
_arguments '(-f --flags)'{-f,--flags}'[Show command flags.]'
|
||||
;;
|
||||
(config)
|
||||
_arguments \
|
||||
'--bool[Set a boolean value.]' \
|
||||
'--json[Parse stringified JSON.]'
|
||||
local -a _config_arguments
|
||||
_config_arguments=(
|
||||
'edit:Open the config file for editing in $EDITOR.'
|
||||
'profile:Apply profiles to config.'
|
||||
'replace:Replace the config with <file>.'
|
||||
'show:Output config file contents.'
|
||||
)
|
||||
_ipfs_subcommand _config_arguments
|
||||
;;
|
||||
(daemon)
|
||||
_arguments \
|
||||
'--init[Initialize ipfs with default settings if not already initialized.]' \
|
||||
'--init-profile[Configuration profiles to apply for --init. See ipfs init --help for more.]' \
|
||||
'--routing[Overrides the routing option. Default: default.]' \
|
||||
'--mount[Mounts IPFS to the filesystem.]' \
|
||||
'--writable[Enable writing objects (with POST, PUT and DELETE).]' \
|
||||
'--mount-ipfs[Path to the mountpoint for IPFS (if using --mount). Defaults to config setting.]' \
|
||||
'--mount-ipns[Path to the mountpoint for IPNS (if using --mount). Defaults to config setting.]' \
|
||||
'--unrestricted-api[Allow API access to unlisted hashes.]' \
|
||||
'--disable-transport-encryption[Disable transport encryption (for debugging protocols).]' \
|
||||
'--enable-gc[Enable automatic periodic repo garbage collection.]' \
|
||||
'--manage-fdlimit[Check and raise file descriptor limits if needed. Default: true.]' \
|
||||
'--migrate[If true, assume yes at the migrate prompt. If false, assume no.]' \
|
||||
'--enable-pubsub-experiment[Instantiate the ipfs daemon with the experimental pubsub feature enabled.]' \
|
||||
'--enable-namesys-pubsub[Enable IPNS record distribution through pubsub; enables pubsub.]' \
|
||||
'--enable-mplex-experiment[Add the experimental 'go-multiplex' stream muxer to libp2p on construction. Default: true.]'
|
||||
;;
|
||||
(dag)
|
||||
local -a _dag_arguments
|
||||
_dag_arguments=(
|
||||
'get:Get a dag node from ipfs.'
|
||||
'put:Add a dag node to ipfs.'
|
||||
'resolve:Resolve ipld block.'
|
||||
)
|
||||
_ipfs_subcommand _dag_arguments
|
||||
;;
|
||||
(dht)
|
||||
local -a _dht_arguments
|
||||
_dht_arguments=(
|
||||
'findpeer:Find the multiaddresses associated with a Peer ID.'
|
||||
'findprovs:Find peers that can provide a specific value, given a key.'
|
||||
'get:Given a key, query the routing system for its best value.'
|
||||
'provide:Announce to the network that you are providing given values.'
|
||||
'put:Write a key/value pair to the routing system.'
|
||||
'query:Find the closest Peer IDs to a given Peer ID by querying the DHT.'
|
||||
)
|
||||
_ipfs_subcommand _dht_arguments
|
||||
;;
|
||||
(diag)
|
||||
local -a _diag_arguments
|
||||
_diag_arguments=(
|
||||
'cmds:List commands run on this IPFS node.'
|
||||
'sys:Print system diagnostic information.'
|
||||
)
|
||||
_ipfs_subcommand _diag_arguments
|
||||
;;
|
||||
(dns)
|
||||
_arguments '(-r --recursive)'{-r,--recursive}'[Resolve until the result is not a DNS link. Default: true.]'
|
||||
;;
|
||||
(files)
|
||||
_arguments '(-f --flush)'{-f,--flush}'[Flush target and ancestors after write. Default: true.]'
|
||||
local -a _files_arguments
|
||||
_files_arguments=(
|
||||
'chcid:Change the cid version or hash function of the root node of a given path.'
|
||||
'cp:Copy files into mfs.'
|
||||
"flush:Flush a given path's data to disk."
|
||||
'ls:List directories in the local mutable namespace.'
|
||||
'mkdir:Make directories.'
|
||||
'mv:Move files.'
|
||||
'read:Read a file in a given mfs.'
|
||||
'rm:Remove a file.'
|
||||
'stat:Display file status.'
|
||||
'write:Write to a mutable file in a given filesystem.'
|
||||
)
|
||||
_ipfs_subcommand _files_arguments
|
||||
;;
|
||||
(filestore)
|
||||
local -a _filestore_arguments
|
||||
_filestore_arguments=(
|
||||
'dups:List blocks that are both in the filestore and standard block storage.'
|
||||
'ls:List objects in filestore.'
|
||||
'verify:Verify objects in filestore.'
|
||||
)
|
||||
_ipfs_subcommand _filestore_arguments
|
||||
;;
|
||||
(get)
|
||||
_arguments \
|
||||
'(-o --output)'{-o,--output}'[The path where the output should be stored.]'\
|
||||
'(-a --archive)'{-a,--archive}'[Output a TAR archive.]' \
|
||||
'(-C --compress)'{-C,--compress}'[Compress the output with GZIP compression.]' \
|
||||
'(-l --compression-level)'{-l,--compression-level}'[The level of compression (1-9).]'
|
||||
;;
|
||||
(id)
|
||||
_arguments '(-f --format)'{-f,--format}'[Optional output format.]'
|
||||
;;
|
||||
(init)
|
||||
_arguments \
|
||||
'(-b --bits)'{-b,--bits}'[Number of bits to use in the generated RSA private key. Default: 2048.]' \
|
||||
'(-e --empty-repo)'{-e,--empty-repo}"[Don't add and pin help files to the local storage.]" \
|
||||
'(-p --profile)'{-p,--profile}"[Apply profile settings to config. Multiple profiles can be separated by ','.]"
|
||||
;;
|
||||
(key)
|
||||
local -a _key_arguments
|
||||
_key_arguments=(
|
||||
'gen:Create a new keypair'
|
||||
'list:List all local keypairs'
|
||||
'rename:Rename a keypair'
|
||||
'rm:Remove a keypair'
|
||||
)
|
||||
_ipfs_subcommand _key_arguments
|
||||
;;
|
||||
(log)
|
||||
local -a _log_arguments
|
||||
_log_arguments=(
|
||||
'level:Change the logging level.'
|
||||
'ls:List the logging subsystems.'
|
||||
'tail:Read the event log.'
|
||||
)
|
||||
_ipfs_subcommand _log_arguments
|
||||
;;
|
||||
(ls)
|
||||
_arguments \
|
||||
'(-v --headers)'{-v,--headers}'[Print table headers (Hash, Size, Name).]' \
|
||||
'--resolve-type[Resolve linked objects to find out their types. Default: true.]' \
|
||||
'--size[Resolve linked objects to find out their file size. Default: true.]' \
|
||||
'(-s --stream)'{-s,--stream}'[Enable exprimental streaming of directory entries as they are traversed.]' \
|
||||
;;
|
||||
(mount)
|
||||
_arguments \
|
||||
'(-f --ipfs-path)'{-f,--ipfs-path}'[The path where IPFS should be mounted.]' \
|
||||
'(-n --ipns-path)'{-n,--ipns-path}'[The path where IPNS should be mounted.]'
|
||||
;;
|
||||
(name)
|
||||
local -a _name_arguments
|
||||
_name_arguments=(
|
||||
'publish:Publish IPNS names.'
|
||||
'pubsub:IPNS pubsub management.'
|
||||
'resolve:Resolve IPNS names.'
|
||||
)
|
||||
_ipfs_subcommand _name_arguments
|
||||
;;
|
||||
(object)
|
||||
local -a _object_arguments
|
||||
_object_arguments=(
|
||||
'data:Output the raw bytes of an IPFS object.'
|
||||
'diff:Display the diff between two ipfs objects.'
|
||||
'get:Get and serialize the DAG node named by <key>.'
|
||||
'links:Output the links pointed to by the specified object.'
|
||||
'new:Create a new object from an ipfs template.'
|
||||
'patch:Create a new merkledag object based on an existing one.'
|
||||
'put:Store input as a DAG object, print its key.'
|
||||
'stat:Get stats for the DAG node named by <key>.'
|
||||
)
|
||||
_ipfs_subcommand _object_arguments
|
||||
;;
|
||||
(p2p)
|
||||
local -a _p2p_arguments
|
||||
_p2p_arguments=(
|
||||
'close:Stop listening for new connections to forward.'
|
||||
'forward:Forward connections to libp2p service'
|
||||
'listen:Create libp2p service'
|
||||
'ls:List active p2p listeners.'
|
||||
'stream:P2P stream management.'
|
||||
)
|
||||
_ipfs_subcommand _p2p_arguments
|
||||
;;
|
||||
(pin)
|
||||
local -a _pin_arguments
|
||||
_pin_arguments=(
|
||||
'add:Pin objects to local storage.'
|
||||
'ls:List objects pinned to local storage.'
|
||||
'rm:Remove pinned objects from local storage.'
|
||||
'update:Update a recursive pin'
|
||||
'verify:Verify that recursive pins are complete.'
|
||||
)
|
||||
_ipfs_subcommand _pin_arguments
|
||||
;;
|
||||
(ping)
|
||||
_arguments '(-n --count)'{-n,--count}'[Number of ping messages to send. Default: 10.]'
|
||||
;;
|
||||
(refs)
|
||||
_arguments \
|
||||
'--format[Emit edges with given format. Available tokens: <src> <dst> <linkname>. Default: <dst>.]' \
|
||||
'(-e --edges)'{-e,--edges}'[Emit edge format: `<from> -> <to>`.]' \
|
||||
'(-u --unique)'{-u,--unique}'[Omit duplicate refs from output.]' \
|
||||
'(-r --recursive)'{-r,--recursive}'[Recursively list links of child nodes.]' \
|
||||
'--max-depth[Only for recursive refs, limits fetch and listing to the given depth. Default: -1.]'
|
||||
local -a _refs_arguments
|
||||
_refs_arguments='local:List all local references.'
|
||||
_ipfs_subcommand _refs_arguments
|
||||
;;
|
||||
(repo)
|
||||
local -a _repo_arguments
|
||||
_repo_arguments=(
|
||||
'fsck:Remove repo lockfiles.'
|
||||
'gc:Perform a garbage collection sweep on the repo.'
|
||||
'stat:Get stats for the currently used repo.'
|
||||
'verify:Verify all blocks in repo are not corrupted.'
|
||||
'version:Show the repo version.'
|
||||
)
|
||||
_ipfs_subcommand _repo_arguments
|
||||
;;
|
||||
(resolve)
|
||||
_arguments \
|
||||
'(-r --recursive)'{-r,--recursive}'[Resolve until the result is an IPFS name. Default: true.]' \
|
||||
'(--dhtrc --dht-record-count)'{--dhtrc,--dht-record-count}'[Number of records to request for DHT resolution.]' \
|
||||
'(--dhtt --dht-timeout)'{--dhtt,--dht-timeout}'[Max time to collect values during DHT resolution eg "30s". Pass 0 for no timeout.]'
|
||||
;;
|
||||
(stats)
|
||||
local -a _stats_arguments
|
||||
_stats_arguments=(
|
||||
'bitswap:Show some diagnostic information on the bitswap agent.'
|
||||
'bw:Print ipfs bandwidth information.'
|
||||
'repo:Get stats for the currently used repo.'
|
||||
)
|
||||
_ipfs_subcommand _stats_arguments
|
||||
;;
|
||||
(swarm)
|
||||
local -a _swarm_arguments
|
||||
_swarm_arguments=(
|
||||
'addrs:List known addresses. Useful for debugging.'
|
||||
'connect:Open connection to a given address.'
|
||||
'disconnect:Close connection to a given address.'
|
||||
'filters:Manipulate address filters.'
|
||||
'peers:List peers with open connections.'
|
||||
)
|
||||
_ipfs_subcommand _swarm_arguments
|
||||
;;
|
||||
(tar)
|
||||
local -a _tar_arguments
|
||||
_tar_arguments=(
|
||||
'add:Import a tar file into ipfs.'
|
||||
'cat:Export a tar file from IPFS.'
|
||||
)
|
||||
_ipfs_subcommand _tar_arguments
|
||||
;;
|
||||
(version)
|
||||
_arguments \
|
||||
'(-n --number)'{-n,--number}'[Only show the version number.]' \
|
||||
'--commit[Show the commit hash.]' \
|
||||
'--repo[Show repo version.]' \
|
||||
'--all[Show all version information.]'
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Joshua Bedford
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Lando ZSH (lando-zsh)
|
||||
|
||||
This plugin adds aliases for using various languages and frameworks with [Lando](https://docs.lando.dev/basics/) for Docker. It will only run within lando-driven project directories.
|
||||
|
||||
To use it, add `lando` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... lando)
|
||||
```
|
||||
|
||||
## ALIASES:
|
||||
|
||||
| Alias | Description |
|
||||
|:----------:|:----------------:|
|
||||
| `artisan` | `lando artisan` |
|
||||
| `composer` | `lando composer` |
|
||||
| `drush` | `lando drush` |
|
||||
| `gulp` | `lando gulp` |
|
||||
| `npm` | `lando npm` |
|
||||
| `wp` | `lando wp` |
|
||||
| `yarn` | `lando yarn` |
|
||||
|
||||
## How It Works:
|
||||
|
||||
This plugin removes the requirement to type `lando` before a command. It utilizes the lando version of supported commands run within directories with the following criteria:
|
||||
- The `.lando.yml` file is found in the current directory or any parent directory within `$LANDO_ZSH_SITES_DIRECTORY`.
|
||||
- The current directory is within `$LANDO_ZSH_SITES_DIRECTORY` but is not `$LANDO_ZSH_SITES_DIRECTORY` itself.
|
||||
|
||||
## Settings:
|
||||
|
||||
- `LANDO_ZSH_SITES_DIRECTORY`: The plugin will stop searching through parents for `CONFIG_FILE` once it hits this directory.
|
||||
- `LANDO_ZSH_CONFIG_FILE`: The plugin will check to see if this provided file exists to check for presence of Lando.
|
||||
|
||||
## Author:
|
||||
|
||||
- Author: Joshua Bedford
|
||||
- URL: [https://github.com/joshuabedford/lando-zsh](https://github.com/joshuabedford/lando-zsh)
|
||||
@@ -0,0 +1,40 @@
|
||||
# Settings
|
||||
: ${LANDO_ZSH_SITES_DIRECTORY:="$HOME/Sites"}
|
||||
: ${LANDO_ZSH_CONFIG_FILE:=.lando.yml}
|
||||
|
||||
# Enable multiple commands with lando.
|
||||
function artisan \
|
||||
composer \
|
||||
drush \
|
||||
gulp \
|
||||
npm \
|
||||
wp \
|
||||
yarn {
|
||||
if checkForLandoFile; then
|
||||
lando "$0" "$@"
|
||||
else
|
||||
command "$0" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for the file in the current and parent directories.
|
||||
checkForLandoFile() {
|
||||
# Only bother checking for lando within the Sites directory.
|
||||
if [[ "$PWD/" != "$LANDO_ZSH_SITES_DIRECTORY"/* ]]; then
|
||||
# Not within $LANDO_ZSH_SITES_DIRECTORY
|
||||
return 1
|
||||
fi
|
||||
|
||||
local curr_dir="$PWD"
|
||||
# Checking for file: $LANDO_ZSH_CONFIG_FILE within $LANDO_ZSH_SITES_DIRECTORY...
|
||||
while [[ "$curr_dir" != "$LANDO_ZSH_SITES_DIRECTORY" ]]; do
|
||||
if [[ -f "$curr_dir/$LANDO_ZSH_CONFIG_FILE" ]]; then
|
||||
return 0
|
||||
fi
|
||||
curr_dir="${curr_dir:h}"
|
||||
done
|
||||
|
||||
# Could not find $LANDO_ZSH_CONFIG_FILE in the current directory
|
||||
# or in any of its parents up to $LANDO_ZSH_SITES_DIRECTORY.
|
||||
return 1
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# lxd
|
||||
|
||||
This plugin provides completion for [lxd](https://linuxcontainers.org/lxd/), as well as aliases
|
||||
for frequent lxc commands.
|
||||
|
||||
To use it add `lxd` to the plugins array in your zshrc file.
|
||||
|
||||
```zsh
|
||||
plugins=(... lxd)
|
||||
@@ -0,0 +1,26 @@
|
||||
_lxc_get_command_list () {
|
||||
$_comp_command1 | sed "1,/Available Commands/d" | awk '/^[ \t]*[a-z]+/ { print $1 }'
|
||||
}
|
||||
|
||||
_lxc_get_subcommand_list () {
|
||||
$_comp_command1 ${words[2]} | sed "1,/Available Commands/d" | awk '/^[ \t]*[a-z]+/ { print $1 }'
|
||||
}
|
||||
|
||||
_lxc () {
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
_arguments \
|
||||
'1: :->command'\
|
||||
'*: :->args'
|
||||
|
||||
case $state in
|
||||
command)
|
||||
compadd $(_lxc_get_command_list)
|
||||
;;
|
||||
*)
|
||||
compadd $(_lxc_get_subcommand_list)
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
compdef _lxc lxc
|
||||
@@ -0,0 +1,90 @@
|
||||
#compdef security
|
||||
|
||||
local -a _1st_arguments
|
||||
_1st_arguments=(
|
||||
'help:Show all commands, or show usage for a command'
|
||||
'list-keychains:Display or manipulate the keychain search list'
|
||||
'default-keychain:Display or set the default keychain'
|
||||
'login-keychain:Display or set the login keychain'
|
||||
'create-keychain:Create keychains and add them to the search list'
|
||||
'delete-keychain:Delete keychains and remove them from the search list'
|
||||
'lock-keychain:Lock the specified keychain'
|
||||
'lock-keychain:Unlock the specified keychain'
|
||||
'set-keychain-settings:Set settings for a keychain'
|
||||
'set-keychain-password:Set password for a keychain'
|
||||
'show-keychain-info:Show the settings for keychain'
|
||||
'dump-keychain:Dump the contents of one or more keychains'
|
||||
'create-keypair:Create an asymmetric key pair'
|
||||
'add-generic-password:Add a generic password item'
|
||||
'add-internet-password:Add an internet password item'
|
||||
'add-certificates:Add certificates to a keychain'
|
||||
'find-generic-password:Find a generic password item'
|
||||
'delete-generic-password:Delete a generic password item'
|
||||
'find-internet-password:Find an internet password item'
|
||||
'delete-internet-password:Delete an internet password item'
|
||||
'find-certificate:Find a certificate item'
|
||||
'find-identity:Find an identity certificate + private key'
|
||||
'delete-certificate:Delete a certificate from a keychain'
|
||||
'set-identity-preference:Set the preferred identity to use for a service'
|
||||
'get-identity-preference:Get the preferred identity to use for a service'
|
||||
'create-db:Create a db using the DL'
|
||||
'export:Export items from a keychain'
|
||||
'import:Import items into a keychain'
|
||||
'cms:Encode or decode CMS messages'
|
||||
'install-mds:MDS database'
|
||||
'add-trusted-cert:Add trusted certificates:'
|
||||
'remove-trusted-cert:Remove trusted certificates:'
|
||||
'dump-trust-settings:Display contents of trust settings'
|
||||
'user-trust-settings-enable:Display or manipulate user-level trust settings'
|
||||
'trust-settings-export:Export trust settings'
|
||||
'trust-settings-import:Import trust settings'
|
||||
'verify-cert:Verify certificates:'
|
||||
'authorize:Perform authorization operations'
|
||||
'authorizationdb:Make changes to the authorization policy database'
|
||||
'execute-with-privileges:Execute tool with privileges'
|
||||
'leaks:Run /usr/bin/leaks on this process'
|
||||
'error:Display a descriptive message for the given error codes:'
|
||||
'create-filevaultmaster-keychain:"Create a keychain containing a key pair for FileVault recovery use'
|
||||
)
|
||||
_arguments '*:: :->command'
|
||||
|
||||
if (( CURRENT == 1 )); then
|
||||
_describe -t commands "security command" _1st_arguments
|
||||
return
|
||||
fi
|
||||
|
||||
case "$words[1]" in
|
||||
find-(generic|internet)-password)
|
||||
_values \
|
||||
'Usage: find-[internet/generic]-password [-a account] [-s server] [options...] [-g] [keychain...]' \
|
||||
'-a[Match "account" string]' \
|
||||
'-c[Match "creator" (four-character code)]' \
|
||||
'-C[Match "type" (four-character code)]' \
|
||||
'-D[Match "kind" string]' \
|
||||
'-G[Match "value" string (generic attribute)]' \
|
||||
'-j[Match "comment" string]' \
|
||||
'-l[Match "label" string]' \
|
||||
'-s[Match "service" string]' \
|
||||
'-g[Display the password for the item found]' \
|
||||
'-w[Display only the password on stdout]' ;;
|
||||
add-(generic|internet)-password)
|
||||
_values \
|
||||
'Usage: add-[internet/generic]-password [-a account] [-s server] [-w password] [options...] [-A|-T appPath] [keychain]]' \
|
||||
'-a[Specify account name (required)]' \
|
||||
'-c[Specify item creator (optional four-character code)]' \
|
||||
'-C[Specify item type (optional four-character code)]' \
|
||||
'-d[Specify security domain string (optional)]' \
|
||||
'-D[Specify kind (default is "Internet password")]' \
|
||||
'-j[Specify comment string (optional)]' \
|
||||
'-l[Specify label (if omitted, server name is used as default label)]' \
|
||||
'-p[Specify path string (optional)]' \
|
||||
'-P[Specify port number (optional)]' \
|
||||
'-r[Specify protocol (optional four-character SecProtocolType, e.g. "http", "ftp ")]' \
|
||||
'-s[Specify server name (required)]' \
|
||||
'-t[Specify authentication type (as a four-character SecAuthenticationType, default is "dflt")]' \
|
||||
'-w[Specify password to be added]' \
|
||||
'-A[Allow any application to access this item without warning (insecure, not recommended!)]' \
|
||||
'-T[Specify an application which may access this item (multiple -T options are allowed)]' \
|
||||
'-U[Update item if it already exists (if omitted, the item cannot already exist) ]' \
|
||||
'utils)]' ;;
|
||||
esac
|
||||
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
function music itunes() {
|
||||
local APP_NAME=Music sw_vers=$(sw_vers -productVersion 2>/dev/null)
|
||||
|
||||
autoload is-at-least
|
||||
if [[ -z "$sw_vers" ]] || is-at-least 10.15 $sw_vers; then
|
||||
if [[ $0 = itunes ]]; then
|
||||
echo >&2 The itunes function name is deprecated. Use \'music\' instead.
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
APP_NAME=iTunes
|
||||
fi
|
||||
|
||||
local opt=$1 playlist=$2
|
||||
(( $# > 0 )) && shift
|
||||
case "$opt" in
|
||||
launch|play|pause|stop|rewind|resume|quit)
|
||||
;;
|
||||
mute)
|
||||
opt="set mute to true"
|
||||
;;
|
||||
unmute)
|
||||
opt="set mute to false"
|
||||
;;
|
||||
next|previous)
|
||||
opt="$opt track"
|
||||
;;
|
||||
vol)
|
||||
local new_volume volume=$(osascript -e "tell application \"$APP_NAME\" to get sound volume")
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "Current volume is ${volume}."
|
||||
return 0
|
||||
fi
|
||||
case $1 in
|
||||
up) new_volume=$((volume + 10 < 100 ? volume + 10 : 100)) ;;
|
||||
down) new_volume=$((volume - 10 > 0 ? volume - 10 : 0)) ;;
|
||||
<0-100>) new_volume=$1 ;;
|
||||
*) echo "'$1' is not valid. Expected <0-100>, up or down."
|
||||
return 1 ;;
|
||||
esac
|
||||
opt="set sound volume to ${new_volume}"
|
||||
;;
|
||||
playlist)
|
||||
# Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f
|
||||
if [[ -n "$playlist" ]]; then
|
||||
osascript 2>/dev/null <<EOF
|
||||
tell application "$APP_NAME"
|
||||
set new_playlist to "$playlist" as string
|
||||
play playlist new_playlist
|
||||
end tell
|
||||
EOF
|
||||
if [[ $? -eq 0 ]]; then
|
||||
opt="play"
|
||||
else
|
||||
opt="stop"
|
||||
fi
|
||||
else
|
||||
opt="set allPlaylists to (get name of every playlist)"
|
||||
fi
|
||||
;;
|
||||
playing|status)
|
||||
local currenttrack currentartist state=$(osascript -e "tell application \"$APP_NAME\" to player state as string")
|
||||
if [[ "$state" = "playing" ]]; then
|
||||
currenttrack=$(osascript -e "tell application \"$APP_NAME\" to name of current track as string")
|
||||
currentartist=$(osascript -e "tell application \"$APP_NAME\" to artist of current track as string")
|
||||
echo -E "Listening to ${fg[yellow]}${currenttrack}${reset_color} by ${fg[yellow]}${currentartist}${reset_color}"
|
||||
else
|
||||
echo "$APP_NAME is $state"
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
shuf|shuff|shuffle)
|
||||
# The shuffle property of current playlist can't be changed in iTunes 12,
|
||||
# so this workaround uses AppleScript to simulate user input instead.
|
||||
# Defaults to toggling when no options are given.
|
||||
# The toggle option depends on the shuffle button being visible in the Now playing area.
|
||||
# On and off use the menu bar items.
|
||||
local state=$1
|
||||
|
||||
if [[ -n "$state" && "$state" != (on|off|toggle) ]]; then
|
||||
print "Usage: $0 shuffle [on|off|toggle]. Invalid option."
|
||||
return 1
|
||||
fi
|
||||
|
||||
case "$state" in
|
||||
on|off)
|
||||
# Inspired by: https://stackoverflow.com/a/14675583
|
||||
osascript >/dev/null 2>&1 <<EOF
|
||||
tell application "System Events" to perform action "AXPress" of (menu item "${state}" of menu "Shuffle" of menu item "Shuffle" of menu "Controls" of menu bar item "Controls" of menu bar 1 of application process "iTunes" )
|
||||
EOF
|
||||
return 0
|
||||
;;
|
||||
toggle|*)
|
||||
osascript >/dev/null 2>&1 <<EOF
|
||||
tell application "System Events" to perform action "AXPress" of (button 2 of process "iTunes"'s window "iTunes"'s scroll area 1)
|
||||
EOF
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
""|-h|--help)
|
||||
echo "Usage: $0 <option>"
|
||||
echo "option:"
|
||||
echo "\t-h|--help\tShow this message and exit"
|
||||
echo "\tlaunch|play|pause|stop|rewind|resume|quit"
|
||||
echo "\tmute|unmute\tMute or unmute $APP_NAME"
|
||||
echo "\tnext|previous\tPlay next or previous track"
|
||||
echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer."
|
||||
echo "\tvol [0-100|up|down]\tGet or set the volume. 0 to 100 sets the volume. 'up' / 'down' increases / decreases by 10 points. No argument displays current volume."
|
||||
echo "\tplaying|status\tShow what song is currently playing in Music."
|
||||
echo "\tplaylist [playlist name]\t Play specific playlist"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
print "Unknown option: $opt"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
osascript -e "tell application \"$APP_NAME\" to $opt"
|
||||
}
|
||||
|
||||
function _music() {
|
||||
local app_name
|
||||
case "$words[1]" in
|
||||
itunes) app_name="iTunes" ;;
|
||||
music|*) app_name="Music" ;;
|
||||
esac
|
||||
|
||||
local -a cmds subcmds
|
||||
cmds=(
|
||||
"launch:Launch the ${app_name} app"
|
||||
"play:Play ${app_name}"
|
||||
"pause:Pause ${app_name}"
|
||||
"stop:Stop ${app_name}"
|
||||
"rewind:Rewind ${app_name}"
|
||||
"resume:Resume ${app_name}"
|
||||
"quit:Quit ${app_name}"
|
||||
"mute:Mute the ${app_name} app"
|
||||
"unmute:Unmute the ${app_name} app"
|
||||
"next:Skip to the next song"
|
||||
"previous:Skip to the previous song"
|
||||
"vol:Change the volume"
|
||||
"playlist:Play a specific playlist"
|
||||
{playing,status}":Show what song is currently playing"
|
||||
{shuf,shuff,shuffle}":Set shuffle mode"
|
||||
{-h,--help}":Show usage"
|
||||
)
|
||||
|
||||
if (( CURRENT == 2 )); then
|
||||
_describe 'command' cmds
|
||||
elif (( CURRENT == 3 )); then
|
||||
case "$words[2]" in
|
||||
vol) subcmds=( 'up:Raise the volume' 'down:Lower the volume' )
|
||||
_describe 'command' subcmds ;;
|
||||
shuf|shuff|shuffle) subcmds=('on:Switch on shuffle mode' 'off:Switch off shuffle mode' 'toggle:Toggle shuffle mode (default)')
|
||||
_describe 'command' subcmds ;;
|
||||
esac
|
||||
elif (( CURRENT == 4 )); then
|
||||
case "$words[2]" in
|
||||
playlist) subcmds=('play:Play the playlist (default)' 'stop:Stop the playlist')
|
||||
_describe 'command' subcmds ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
compdef _music music itunes
|
||||
@@ -0,0 +1,9 @@
|
||||
# rustup
|
||||
|
||||
This plugin adds completion for [`rustup`](https://rustup.rs/), the toolchain installer for the Rust programming language.
|
||||
|
||||
To use it, add `rustup` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... rustup)
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
||||
#compdef scd
|
||||
#description smart change directory
|
||||
|
||||
local curcontext="$curcontext" state line expl ret=1
|
||||
typeset -A opt_args
|
||||
|
||||
local -a indexopts myargs
|
||||
indexopts=( --add -a --unindex )
|
||||
|
||||
myargs=(
|
||||
# common options
|
||||
"(--help -h)"{--help,-h}"[print help and exit]"
|
||||
|
||||
# options for manipulating directory index
|
||||
- index
|
||||
"(--recursive -r)"{--recursive,-r}"[use recursive --add or --unindex]"
|
||||
"($indexopts)"{--add,-a}"[add specified directories to the index]"
|
||||
"($indexopts)--unindex[remove specified directories from the index]"
|
||||
"*:directory:{ (( ${words[(I)-a|--add|--unindex]} )) && _path_files -/ }"
|
||||
|
||||
# define new directory alias
|
||||
- alias
|
||||
"--alias=[create alias for this or given directory]:directory-alias:()"
|
||||
'1:directory:{ (( words[(I)--alias*] )) && _path_files -/ }'
|
||||
|
||||
# remove definition of directory alias
|
||||
- unalias
|
||||
"--unalias[remove definition of directory alias]"
|
||||
"*::directory alias:->scd-alias-target"
|
||||
|
||||
# act on the directory change
|
||||
- scd
|
||||
"(--all -A)"{--all,-A}"[include less likely and ignored paths]"
|
||||
"--list[print matching directories and exit]"
|
||||
"(--verbose -v)"{--verbose,-v}"[show directory ranking and full paths]"
|
||||
"(--push -p)"{--push,-p}"[change directory with 'pushd']"
|
||||
"1::directory alias:->scd-alias-target"
|
||||
"*:patterns:()"
|
||||
)
|
||||
|
||||
_arguments -S -C $myargs && ret=0
|
||||
|
||||
|
||||
if [[ "$state" == scd-alias-target && -s ~/.scdalias.zsh ]]; then
|
||||
local -a scdaliases
|
||||
scdaliases=( )
|
||||
eval "$(setopt extendedglob
|
||||
phome="(#b)(#s)${HOME}(/*)#(#e)"
|
||||
builtin hash -dr
|
||||
source ~/.scdalias.zsh &&
|
||||
for k v in ${(kv)nameddirs}; do
|
||||
scdaliases+=( $k:${v/${~phome}/"~"${match[1]}} )
|
||||
done
|
||||
complete_unalias=${+opt_args[unalias---unalias]}
|
||||
if (( complete_unalias && ! ${+nameddirs[OLD]} )); then
|
||||
scdaliases+=( 'OLD:all aliases to non-existent paths' )
|
||||
fi
|
||||
typeset -p scdaliases )"
|
||||
_describe -t scdaliases scdalias scdaliases
|
||||
fi
|
||||
@@ -0,0 +1,533 @@
|
||||
#!/bin/zsh -f
|
||||
|
||||
emulate -L zsh
|
||||
|
||||
local RUNNING_AS_COMMAND=
|
||||
local EXIT=return
|
||||
if [[ $(whence -w $0) == *:' 'command ]]; then
|
||||
RUNNING_AS_COMMAND=1
|
||||
EXIT=exit
|
||||
fi
|
||||
|
||||
local DOC='scd -- smart change to a recently used directory
|
||||
usage: scd [options] [pattern1 pattern2 ...]
|
||||
Go to a directory path that matches all patterns. Prefer recent or
|
||||
frequently visited directories as found in the directory index.
|
||||
Display a selection menu in case of multiple matches.
|
||||
|
||||
Special patterns:
|
||||
^PAT match at the path root, "^/home"
|
||||
PAT$ match paths ending with PAT, "man$"
|
||||
./ match paths under the current directory
|
||||
:PAT require PAT to span the tail, ":doc", ":re/doc"
|
||||
|
||||
Options:
|
||||
-a, --add add current or specified directories to the index.
|
||||
--unindex remove current or specified directories from the index.
|
||||
-r, --recursive apply options --add or --unindex recursively.
|
||||
--alias=ALIAS create alias for the current or specified directory and
|
||||
store it in ~/.scdalias.zsh.
|
||||
--unalias remove ALIAS definition for the current or specified
|
||||
directory from ~/.scdalias.zsh.
|
||||
Use "OLD" to purge aliases to non-existent directories.
|
||||
-A, --all display all directories even those excluded by patterns
|
||||
in ~/.scdignore. Disregard unique match for a directory
|
||||
alias and filtering of less likely paths.
|
||||
-p, --push use "pushd" to change to the target directory.
|
||||
--list show matching directories and exit.
|
||||
-v, --verbose display directory rank in the selection menu.
|
||||
-h, --help display this message and exit.
|
||||
'
|
||||
|
||||
local SCD_HISTFILE=${SCD_HISTFILE:-${HOME}/.scdhistory}
|
||||
local SCD_HISTSIZE=${SCD_HISTSIZE:-5000}
|
||||
local SCD_MENUSIZE=${SCD_MENUSIZE:-20}
|
||||
local SCD_MEANLIFE=${SCD_MEANLIFE:-86400}
|
||||
local SCD_THRESHOLD=${SCD_THRESHOLD:-0.005}
|
||||
local SCD_SCRIPT=${RUNNING_AS_COMMAND:+$SCD_SCRIPT}
|
||||
local SCD_ALIAS=~/.scdalias.zsh
|
||||
local SCD_IGNORE=~/.scdignore
|
||||
|
||||
# Minimum logarithm of probability. Avoids out of range warning in exp().
|
||||
local -r MINLOGPROB=-15
|
||||
|
||||
# When false, use case-insensitive globbing to fix PWD capitalization.
|
||||
local PWDCASECORRECT=true
|
||||
if [[ ${OSTYPE} == darwin* ]]; then
|
||||
PWDCASECORRECT=false
|
||||
fi
|
||||
|
||||
local a d m p i maxrank threshold
|
||||
local opt_help opt_add opt_unindex opt_recursive opt_verbose
|
||||
local opt_alias opt_unalias opt_all opt_push opt_list
|
||||
local -A drank dalias scdignore
|
||||
local dmatching
|
||||
local last_directory
|
||||
|
||||
setopt extendedglob noautonamedirs brace_ccl
|
||||
|
||||
# If SCD_SCRIPT is defined make sure that that file exists and is empty.
|
||||
# This removes any old previous commands from the SCD_SCRIPT file.
|
||||
[[ -n "$SCD_SCRIPT" ]] && [[ -s $SCD_SCRIPT || ! -f $SCD_SCRIPT ]] && (
|
||||
umask 077
|
||||
: >| $SCD_SCRIPT
|
||||
)
|
||||
|
||||
# process command line options
|
||||
zmodload -i zsh/zutil
|
||||
zmodload -i zsh/datetime
|
||||
zmodload -i zsh/parameter
|
||||
zparseopts -D -E -- a=opt_add -add=opt_add -unindex=opt_unindex \
|
||||
r=opt_recursive -recursive=opt_recursive \
|
||||
-alias:=opt_alias -unalias=opt_unalias \
|
||||
A=opt_all -all=opt_all p=opt_push -push=opt_push -list=opt_list \
|
||||
v=opt_verbose -verbose=opt_verbose h=opt_help -help=opt_help \
|
||||
|| $EXIT $?
|
||||
|
||||
# remove the first instance of "--" from positional arguments
|
||||
argv[(i)--]=( )
|
||||
|
||||
if [[ -n $opt_help ]]; then
|
||||
print $DOC
|
||||
$EXIT
|
||||
fi
|
||||
|
||||
# load directory aliases if they exist
|
||||
[[ -r $SCD_ALIAS ]] && source $SCD_ALIAS
|
||||
|
||||
# load scd-ignore patterns if available
|
||||
if [[ -s $SCD_IGNORE ]]; then
|
||||
setopt noglob
|
||||
<$SCD_IGNORE \
|
||||
while read p; do
|
||||
[[ $p != [\#]* ]] || continue
|
||||
[[ -n $p ]] || continue
|
||||
# expand leading tilde if it has valid expansion
|
||||
if [[ $p == [~]* ]] && ( : ${~p} ) 2>/dev/null; then
|
||||
p=${~p}
|
||||
fi
|
||||
scdignore[$p]=1
|
||||
done
|
||||
setopt glob
|
||||
fi
|
||||
|
||||
# Private internal functions are prefixed with _scd_Y19oug_.
|
||||
# Clean them up when the scd function returns.
|
||||
setopt localtraps
|
||||
trap 'unfunction -m "_scd_Y19oug_*"' EXIT
|
||||
|
||||
# works faster than the (:a) modifier and is compatible with zsh 4.2.6
|
||||
_scd_Y19oug_abspath() {
|
||||
set -A $1 ${(ps:\0:)"$(
|
||||
setopt pushdsilent
|
||||
unfunction -m "*"
|
||||
unalias -m "*"
|
||||
unset CDPATH
|
||||
shift
|
||||
for d; do
|
||||
pushd $d || continue
|
||||
$PWDCASECORRECT &&
|
||||
print -Nr -- $PWD ||
|
||||
print -Nr -- (#i)$PWD
|
||||
popd 2>/dev/null
|
||||
done
|
||||
)"}
|
||||
}
|
||||
|
||||
# define directory alias
|
||||
if [[ -n $opt_alias ]]; then
|
||||
if [[ -n $1 && ! -d $1 ]]; then
|
||||
print -u2 "'$1' is not a directory."
|
||||
$EXIT 1
|
||||
fi
|
||||
a=${opt_alias[-1]#=}
|
||||
_scd_Y19oug_abspath d ${1:-$PWD}
|
||||
# alias in the current shell, update alias file if successful
|
||||
hash -d -- $a=$d &&
|
||||
(
|
||||
umask 077
|
||||
hash -dr
|
||||
[[ -r $SCD_ALIAS ]] && source $SCD_ALIAS
|
||||
hash -d -- $a=$d
|
||||
hash -dL >| $SCD_ALIAS
|
||||
)
|
||||
$EXIT $?
|
||||
fi
|
||||
|
||||
# undefine one or more directory aliases
|
||||
if [[ -n $opt_unalias ]]; then
|
||||
local -U uu
|
||||
local ec=0
|
||||
uu=( ${*:-${PWD}} )
|
||||
if (( ${uu[(I)OLD]} && ${+nameddirs[OLD]} == 0 )); then
|
||||
uu=( ${uu:#OLD} ${(ps:\0:)"$(
|
||||
hash -dr
|
||||
if [[ -r $SCD_ALIAS ]]; then
|
||||
source $SCD_ALIAS
|
||||
fi
|
||||
for a d in ${(kv)nameddirs}; do
|
||||
[[ -d $d ]] || print -Nr -- $a
|
||||
done
|
||||
)"}
|
||||
)
|
||||
fi
|
||||
m=( )
|
||||
for p in $uu; do
|
||||
d=$p
|
||||
if [[ ${+nameddirs[$d]} == 0 && -d $d ]]; then
|
||||
_scd_Y19oug_abspath d $d
|
||||
fi
|
||||
a=${(k)nameddirs[$d]:-${(k)nameddirs[(r)$d]}}
|
||||
if [[ -z $a ]]; then
|
||||
ec=1
|
||||
print -u2 "'$p' is neither a directory alias nor an aliased path."
|
||||
continue
|
||||
fi
|
||||
# unalias in the current shell and remember to update the alias file
|
||||
if unhash -d -- $a 2>/dev/null; then
|
||||
m+=( $a )
|
||||
fi
|
||||
done
|
||||
if [[ $#m != 0 && -r $SCD_ALIAS ]]; then
|
||||
(
|
||||
umask 077
|
||||
hash -dr
|
||||
source $SCD_ALIAS
|
||||
for a in $m; do
|
||||
unhash -d -- $a 2>/dev/null
|
||||
done
|
||||
hash -dL >| $SCD_ALIAS
|
||||
) || ec=$?
|
||||
fi
|
||||
$EXIT $ec
|
||||
fi
|
||||
|
||||
# The "compress" function collapses repeated directories into
|
||||
# a single entry with a time-stamp yielding an equivalent probability.
|
||||
_scd_Y19oug_compress() {
|
||||
awk -v epochseconds=$EPOCHSECONDS \
|
||||
-v meanlife=$SCD_MEANLIFE \
|
||||
-v minlogprob=$MINLOGPROB \
|
||||
'
|
||||
BEGIN {
|
||||
FS = "[:;]";
|
||||
pmin = exp(minlogprob);
|
||||
}
|
||||
/^: deleted:0;/ { next; }
|
||||
length($0) < 4096 && $2 > 1000 {
|
||||
df = $0;
|
||||
sub("^[^;]*;", "", df);
|
||||
if (!df) next;
|
||||
tau = 1.0 * ($2 - epochseconds) / meanlife;
|
||||
prob = (tau < minlogprob) ? pmin : exp(tau);
|
||||
dlist[last[df]] = "";
|
||||
dlist[NR] = df;
|
||||
last[df] = NR;
|
||||
ptot[df] += prob;
|
||||
}
|
||||
END {
|
||||
for (i = 1; i <= NR; ++i) {
|
||||
d = dlist[i];
|
||||
if (d) {
|
||||
ts = log(ptot[d]) * meanlife + epochseconds;
|
||||
printf(": %.0f:0;%s\n", ts, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
' $*
|
||||
}
|
||||
|
||||
# Rewrite directory index if it is at least 20% oversized.
|
||||
local curhistsize
|
||||
if [[ -z $opt_unindex && -s $SCD_HISTFILE ]] && \
|
||||
curhistsize=$(wc -l <$SCD_HISTFILE) && \
|
||||
(( $curhistsize > 1.2 * $SCD_HISTSIZE )); then
|
||||
# Compress repeated entries in a background process.
|
||||
(
|
||||
m=( ${(f)"$(_scd_Y19oug_compress $SCD_HISTFILE)"} )
|
||||
# purge non-existent and ignored directories
|
||||
m=( ${(f)"$(
|
||||
for a in $m; do
|
||||
d=${a#*;}
|
||||
[[ -z ${scdignore[(k)$d]} ]] || continue
|
||||
[[ -d $d ]] || continue
|
||||
$PWDCASECORRECT || d=( (#i)${d} )
|
||||
t=${a%%;*}
|
||||
print -r -- "${t};${d}"
|
||||
done
|
||||
)"}
|
||||
)
|
||||
# cut old entries if still oversized
|
||||
if [[ $#m -gt $SCD_HISTSIZE ]]; then
|
||||
m=( ${m[-$SCD_HISTSIZE,-1]} )
|
||||
fi
|
||||
# Checking existence of many directories could have taken a while.
|
||||
# Append any index entries added in meantime.
|
||||
m+=( ${(f)"$(sed "1,${curhistsize}d" $SCD_HISTFILE)"} )
|
||||
print -lr -- $m >| ${SCD_HISTFILE}
|
||||
) &|
|
||||
fi
|
||||
|
||||
# Determine the last recorded directory
|
||||
if [[ -s ${SCD_HISTFILE} ]]; then
|
||||
last_directory=${"$(tail -1 ${SCD_HISTFILE})"#*;}
|
||||
fi
|
||||
|
||||
# The "record" function adds its arguments to the directory index.
|
||||
_scd_Y19oug_record() {
|
||||
while [[ -n $last_directory && $1 == $last_directory ]]; do
|
||||
shift
|
||||
done
|
||||
if [[ $# -gt 0 ]]; then
|
||||
( umask 077
|
||||
p=": ${EPOCHSECONDS}:0;"
|
||||
print -lr -- ${p}${^*} >>| $SCD_HISTFILE )
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ -n $opt_add ]]; then
|
||||
m=( ${^${argv:-$PWD}}(N-/) )
|
||||
_scd_Y19oug_abspath m ${m}
|
||||
_scd_Y19oug_record $m
|
||||
if [[ -n $opt_recursive ]]; then
|
||||
for d in $m; do
|
||||
print -n "scanning ${d} ... "
|
||||
_scd_Y19oug_record ${d}/**/*(-/N)
|
||||
print "[done]"
|
||||
done
|
||||
fi
|
||||
$EXIT
|
||||
fi
|
||||
|
||||
# take care of removing entries from the directory index
|
||||
if [[ -n $opt_unindex ]]; then
|
||||
if [[ ! -s $SCD_HISTFILE ]]; then
|
||||
$EXIT
|
||||
fi
|
||||
argv=( ${argv:-$PWD} )
|
||||
# expand existing directories in the argument list
|
||||
for i in {1..$#}; do
|
||||
if [[ -d ${argv[i]} ]]; then
|
||||
_scd_Y19oug_abspath d ${argv[i]}
|
||||
argv[i]=${d}
|
||||
fi
|
||||
done
|
||||
# strip trailing slashes, but preserve the root path
|
||||
argv=( ${argv/(#m)?\/##(#e)/${MATCH[1]}} )
|
||||
m="$(awk -v recursive=${opt_recursive} '
|
||||
BEGIN {
|
||||
for (i = 2; i < ARGC; ++i) {
|
||||
argset[ARGV[i]] = 1;
|
||||
delete ARGV[i];
|
||||
}
|
||||
unindex_root = ("/" in argset);
|
||||
}
|
||||
1 {
|
||||
d = $0; sub(/^[^;]*;/, "", d);
|
||||
if (d in argset) next;
|
||||
}
|
||||
recursive {
|
||||
if (unindex_root) exit;
|
||||
for (a in argset) {
|
||||
if (substr(d, 1, length(a) + 1) == a"/") next;
|
||||
}
|
||||
}
|
||||
{ print $0 }
|
||||
' $SCD_HISTFILE $* )" || $EXIT $?
|
||||
: >| ${SCD_HISTFILE}
|
||||
[[ ${#m} == 0 ]] || print -r -- $m >> ${SCD_HISTFILE}
|
||||
$EXIT
|
||||
fi
|
||||
|
||||
# The "action" function is called when there is just one target directory.
|
||||
_scd_Y19oug_action() {
|
||||
local cdcmd=cd
|
||||
[[ -z ${opt_push} ]] || cdcmd=pushd
|
||||
builtin $cdcmd $1 || return $?
|
||||
if [[ -z $SCD_SCRIPT && -n $RUNNING_AS_COMMAND ]]; then
|
||||
print -u2 "Warning: running as command with SCD_SCRIPT undefined."
|
||||
fi
|
||||
if [[ -n $SCD_SCRIPT ]]; then
|
||||
local d=$1
|
||||
if [[ $OSTYPE == cygwin && ${(L)SCD_SCRIPT} == *.bat ]]; then
|
||||
d=$(cygpath -aw .)
|
||||
fi
|
||||
print -r "${cdcmd} ${(qqq)d}" >| $SCD_SCRIPT
|
||||
fi
|
||||
}
|
||||
|
||||
# Select and order indexed directories by matching command-line patterns.
|
||||
# Set global arrays dmatching and drank.
|
||||
_scd_Y19oug_match() {
|
||||
## single argument that is an existing directory or directory alias
|
||||
if [[ -z $opt_all && $# == 1 ]] && \
|
||||
[[ -d ${d::=${nameddirs[$1]}} || -d ${d::=$1} ]] && [[ -x $d ]];
|
||||
then
|
||||
_scd_Y19oug_abspath dmatching $d
|
||||
drank[${dmatching[1]}]=1
|
||||
return
|
||||
fi
|
||||
|
||||
# quote brackets when PWD is /Volumes/[C]/
|
||||
local qpwd=${PWD//(#m)[][]/\\${MATCH}}
|
||||
|
||||
# support "./" as an alias for $PWD to match only subdirectories.
|
||||
argv=( ${argv/(#s).\/(#e)/(#s)${qpwd}(|/*)(#e)} )
|
||||
|
||||
# support "./pat" as an alias for $PWD/pat.
|
||||
argv=( ${argv/(#m)(#s).\/?*/(#s)${qpwd}${MATCH#.}} )
|
||||
|
||||
# support "^" as an anchor for the root directory, e.g., "^$HOME".
|
||||
argv=( ${argv/(#m)(#s)\^?*/(#s)${${~MATCH[2,-1]}}} )
|
||||
|
||||
# support "$" as an anchor at the end of directory name.
|
||||
argv=( ${argv/(#m)?[$](#e)/${MATCH[1]}(#e)} )
|
||||
|
||||
# support prefix ":" to match over the tail component.
|
||||
argv=( ${argv/(#m)(#s):?*/${MATCH[2,-1]}[^/]#(#e)} )
|
||||
|
||||
# calculate rank of all directories in SCD_HISTFILE and store it in drank.
|
||||
# include a dummy entry to avoid issues with splitting an empty string.
|
||||
[[ -s $SCD_HISTFILE ]] && drank=( ${(f)"$(
|
||||
print -l /dev/null -10
|
||||
<$SCD_HISTFILE \
|
||||
awk -v epochseconds=$EPOCHSECONDS \
|
||||
-v meanlife=$SCD_MEANLIFE \
|
||||
-v minlogprob=$MINLOGPROB \
|
||||
'
|
||||
BEGIN {
|
||||
FS = "[:;]";
|
||||
pmin = exp(minlogprob);
|
||||
}
|
||||
/^: deleted:0;/ {
|
||||
df = $0;
|
||||
sub("^[^;]*;", "", df);
|
||||
delete ptot[df];
|
||||
next;
|
||||
}
|
||||
length($0) < 4096 && $2 > 0 {
|
||||
df = $0;
|
||||
sub("^[^;]*;", "", df);
|
||||
if (!df) next;
|
||||
dp = df;
|
||||
while (!(dp in ptot)) {
|
||||
ptot[dp] = pmin;
|
||||
sub("//*[^/]*$", "", dp);
|
||||
if (!dp) break;
|
||||
}
|
||||
if ($2 <= 1000) next;
|
||||
tau = 1.0 * ($2 - epochseconds) / meanlife;
|
||||
prob = (tau < minlogprob) ? pmin : exp(tau);
|
||||
ptot[df] += prob;
|
||||
}
|
||||
END { for (di in ptot) { print di; print ptot[di]; } }
|
||||
'
|
||||
)"}
|
||||
)
|
||||
unset "drank[/dev/null]"
|
||||
|
||||
# filter drank to the entries that match all arguments
|
||||
for a; do
|
||||
p="(#l)*(${a})*"
|
||||
drank=( ${(kv)drank[(I)${~p}]} )
|
||||
done
|
||||
# require that at least one argument matches in directory tail name.
|
||||
p="(#l)*(${(j:|:)argv})[^/]#"
|
||||
drank=( ${(kv)drank[(I)${~p}]} )
|
||||
|
||||
# discard ignored directories
|
||||
if [[ -z ${opt_all} ]]; then
|
||||
for d in ${(k)drank}; do
|
||||
[[ -z ${scdignore[(k)$d]} ]] || unset "drank[$d]"
|
||||
done
|
||||
fi
|
||||
|
||||
# build a list of matching directories reverse-sorted by their probabilities
|
||||
dmatching=( ${(f)"$(
|
||||
builtin printf "%s %s\n" ${(Oakv)drank} |
|
||||
/usr/bin/sort -grk1 )"}
|
||||
)
|
||||
dmatching=( ${dmatching#*[[:blank:]]} )
|
||||
|
||||
# do not match $HOME or $PWD when run without arguments
|
||||
if [[ $# == 0 ]]; then
|
||||
dmatching=( ${dmatching:#(${HOME}|${PWD})} )
|
||||
fi
|
||||
|
||||
# keep at most SCD_MENUSIZE of matching and valid directories
|
||||
# mark up any deleted entries in the index
|
||||
local -A isdeleted
|
||||
m=( )
|
||||
isdeleted=( )
|
||||
for d in $dmatching; do
|
||||
[[ ${#m} == $SCD_MENUSIZE ]] && break
|
||||
(( ${+isdeleted[$d]} == 0 )) || continue
|
||||
[[ -d $d ]] || { isdeleted[$d]=1; continue }
|
||||
[[ -x $d ]] && m+=$d
|
||||
done
|
||||
dmatching=( $m )
|
||||
if [[ -n ${isdeleted} ]]; then
|
||||
print -lr -- ": deleted:0;"${^${(k)isdeleted}} >> $SCD_HISTFILE
|
||||
fi
|
||||
|
||||
# find the maximum rank
|
||||
maxrank=0.0
|
||||
for d in $dmatching; do
|
||||
[[ ${drank[$d]} -lt maxrank ]] || maxrank=${drank[$d]}
|
||||
done
|
||||
|
||||
# discard all directories below the rank threshold
|
||||
threshold=$(( maxrank * SCD_THRESHOLD ))
|
||||
if [[ -n ${opt_all} ]]; then
|
||||
threshold=0
|
||||
fi
|
||||
dmatching=( ${^dmatching}(Ne:'(( ${drank[$REPLY]} >= threshold ))':) )
|
||||
}
|
||||
|
||||
_scd_Y19oug_match $*
|
||||
|
||||
## process matching directories.
|
||||
if [[ ${#dmatching} == 0 ]]; then
|
||||
print -u2 "No matching directory."
|
||||
$EXIT 1
|
||||
fi
|
||||
|
||||
## build formatted directory aliases for selection menu or list display
|
||||
for d in $dmatching; do
|
||||
if [[ -n ${opt_verbose} ]]; then
|
||||
dalias[$d]=$(printf "%.3g %s" ${drank[$d]} $d)
|
||||
else
|
||||
dalias[$d]=$(print -Dr -- $d)
|
||||
fi
|
||||
done
|
||||
|
||||
## process the --list option
|
||||
if [[ -n $opt_list ]]; then
|
||||
for d in $dmatching; do
|
||||
print -r -- "# ${dalias[$d]}"
|
||||
print -r -- $d
|
||||
done
|
||||
$EXIT
|
||||
fi
|
||||
|
||||
## handle a single matching directory here.
|
||||
if [[ ${#dmatching} == 1 ]]; then
|
||||
_scd_Y19oug_action $dmatching
|
||||
$EXIT $?
|
||||
fi
|
||||
|
||||
## Here we have multiple matches. Let's use the selection menu.
|
||||
a=( {a-z} {A-Z} )
|
||||
a=( ${a[1,${#dmatching}]} )
|
||||
p=( )
|
||||
for i in {1..${#dmatching}}; do
|
||||
[[ -n ${a[i]} ]] || break
|
||||
p+="${a[i]}) ${dalias[${dmatching[i]}]}"
|
||||
done
|
||||
|
||||
print -c -r -- $p
|
||||
|
||||
if read -s -k 1 d && [[ ${i::=${a[(I)$d]}} -gt 0 ]]; then
|
||||
_scd_Y19oug_action ${dmatching[i]}
|
||||
$EXIT $?
|
||||
fi
|
||||
@@ -0,0 +1,52 @@
|
||||
# Shell Proxy oh-my-zsh plugin
|
||||
|
||||
This a pure user-space program, shell-proxy setter, written Python3 and Bash.
|
||||
|
||||
100% only no side-effects, only effect **environment variables** and **aliases**
|
||||
|
||||
## Key feature
|
||||
|
||||
- Support Ubuntu, Archlinux, etc (Linux)
|
||||
- Support macOS
|
||||
- Support git via based-`$GIT_SSH`
|
||||
- Support ssh, sftp, scp, slogin and ssh-copy-id via based-`alias`
|
||||
- Built-in Auto-complete
|
||||
|
||||
## Usage
|
||||
|
||||
Method 1:
|
||||
|
||||
`$DEFAULT_PROXY` is the proxy URL you will set
|
||||
|
||||
Method 2:
|
||||
|
||||
Write a program to `$HOME/.config/proxy` in the file.
|
||||
|
||||
Example program:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# The file path: $HOME/.config/proxy
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo "http://127.0.0.1:6152" # Surge Mac
|
||||
else
|
||||
echo "http://127.0.0.1:8123" # polipo
|
||||
fi
|
||||
```
|
||||
|
||||
Method 3:
|
||||
|
||||
The working path of **Method 2** can be changed via `$CONFIG_PROXY`
|
||||
|
||||
## Reference
|
||||
|
||||
- `$GIT_SSH`: <https://www.git-scm.com/docs/git#Documentation/git.txt-codeGITSSHcode>
|
||||
- OpenSSH manual: <https://man.openbsd.org/ssh>
|
||||
|
||||
## Maintainer
|
||||
|
||||
- <https://github.com/septs>
|
||||
|
||||
## The oh-my-zsh plugin (shell-proxy)
|
||||
|
||||
Public Domain
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
from subprocess import check_output, list2cmdline
|
||||
|
||||
cwd = os.path.dirname(__file__)
|
||||
ssh_agent = os.path.join(cwd, "ssh-agent.py")
|
||||
user_proxy = os.environ.get("CONFIG_PROXY", os.path.expandvars("$HOME/.config/proxy"))
|
||||
|
||||
|
||||
def get_http_proxy():
|
||||
if "DEFAULT_PROXY" in os.environ:
|
||||
return os.environ["DEFAULT_PROXY"]
|
||||
if os.path.isfile(user_proxy):
|
||||
return check_output(user_proxy).decode("utf-8").strip()
|
||||
raise Exception("Not found, Proxy configuration")
|
||||
|
||||
|
||||
def make_proxies(url: str):
|
||||
proxies = {"%s_PROXY" % _: url for _ in ("HTTP", "HTTPS", "FTP", "RSYNC", "ALL")}
|
||||
proxies.update({name.lower(): value for (name, value) in proxies.items()})
|
||||
proxies["GIT_SSH"] = ssh_agent
|
||||
return proxies
|
||||
|
||||
|
||||
def merge(mapping: dict):
|
||||
return ("%s=%s" % _ for _ in mapping.items())
|
||||
|
||||
|
||||
class CommandSet:
|
||||
proxies = make_proxies(get_http_proxy())
|
||||
aliases = {
|
||||
_: "env __SSH_PROGRAM_NAME__=%s %s" % (_, ssh_agent)
|
||||
for _ in ("ssh", "sftp", "scp", "slogin", "ssh-copy-id")
|
||||
}
|
||||
|
||||
def enable(self):
|
||||
cmdline("export", *merge(self.proxies))
|
||||
cmdline("alias", *merge(self.aliases))
|
||||
|
||||
def disable(self):
|
||||
cmdline("unset", *self.proxies.keys())
|
||||
cmdline("unalias", *self.aliases.keys())
|
||||
|
||||
def status(self):
|
||||
proxies = (
|
||||
"%11s = %s" % (name, os.environ[name])
|
||||
for name in self.proxies.keys()
|
||||
if name in os.environ
|
||||
)
|
||||
for _ in proxies:
|
||||
cmdline("echo", _)
|
||||
|
||||
def usage(self):
|
||||
cmdline("echo", "usage: proxy {enable,disable,status}")
|
||||
self.status()
|
||||
|
||||
|
||||
def cmdline(*items):
|
||||
print(list2cmdline(items))
|
||||
|
||||
|
||||
def main():
|
||||
command = CommandSet()
|
||||
if len(sys.argv) == 1:
|
||||
command.usage()
|
||||
sys.exit(-1)
|
||||
getattr(command, sys.argv[1], command.usage)()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
ssh_proxy = os.path.join(os.path.dirname(__file__), "ssh-proxy.py")
|
||||
|
||||
argv = [
|
||||
os.environ.get("__SSH_PROGRAM_NAME__", "ssh"),
|
||||
"-o",
|
||||
"ProxyCommand={} %h %p".format(ssh_proxy),
|
||||
"-o",
|
||||
"Compression=yes",
|
||||
]
|
||||
|
||||
subprocess.call(argv + sys.argv[1:], env=os.environ)
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.parse
|
||||
|
||||
proxy = next(os.environ[_] for _ in ("HTTP_PROXY", "HTTPS_PROXY") if _ in os.environ)
|
||||
argv = [
|
||||
"nc",
|
||||
"-X",
|
||||
"connect",
|
||||
"-x",
|
||||
urllib.parse.urlparse(proxy).netloc, # proxy-host:proxy-port
|
||||
sys.argv[1], # host
|
||||
sys.argv[2], # port
|
||||
]
|
||||
|
||||
subprocess.call(argv)
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/bash
|
||||
# shellcheck disable=SC1090
|
||||
|
||||
__PROXY__="${0:A:h}/proxy.py"
|
||||
|
||||
proxy() {
|
||||
source <("$__PROXY__" "$1")
|
||||
}
|
||||
|
||||
_proxy() {
|
||||
local -r commands=('enable' 'disable' 'status')
|
||||
compset -P '*,'
|
||||
compadd -S '' "${commands[@]}"
|
||||
}
|
||||
|
||||
compdef '_proxy' 'proxy'
|
||||
@@ -0,0 +1,17 @@
|
||||
## sublime-merge
|
||||
|
||||
Plugin for Sublime Merge, a cross platform text and code editor, available for Linux, Mac OS X, and Windows.
|
||||
|
||||
### Requirements
|
||||
|
||||
* [Sublime Merge](https://www.sublimemerge.com)
|
||||
|
||||
### Usage
|
||||
|
||||
* If `sm` command is called without an argument, launch Sublime Merge
|
||||
|
||||
* If `sm` is passed a directory, `cd` to it and open the existing git repository in Sublime Merge
|
||||
|
||||
* If `smt` command is called, it is equivalent to `sm .`, opening the existing git repository in the current folder in Sublime Merge
|
||||
|
||||
* If `ssm` command is called, it is like `sudo sm`, opening the git repository in Sublime Merge. Useful for editing system protected repositories.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Sublime Merge Aliases
|
||||
|
||||
() {
|
||||
|
||||
if [[ "$OSTYPE" == linux* ]]; then
|
||||
local _sublime_linux_paths
|
||||
_sublime_linux_paths=(
|
||||
"$HOME/bin/sublime_merge"
|
||||
"/opt/sublime_merge/sublime_merge"
|
||||
"/usr/bin/sublime_merge"
|
||||
"/usr/local/bin/sublime_merge"
|
||||
"/usr/bin/sublime_merge"
|
||||
"/usr/local/bin/smerge"
|
||||
"/usr/bin/smerge"
|
||||
)
|
||||
for _sublime_merge_path in $_sublime_linux_paths; do
|
||||
if [[ -a $_sublime_merge_path ]]; then
|
||||
sm_run() { $_sublime_merge_path "$@" >/dev/null 2>&1 &| }
|
||||
ssm_run_sudo() {sudo $_sublime_merge_path "$@" >/dev/null 2>&1}
|
||||
alias ssm=ssm_run_sudo
|
||||
alias sm=sm_run
|
||||
break
|
||||
fi
|
||||
done
|
||||
elif [[ "$OSTYPE" = darwin* ]]; then
|
||||
local _sublime_darwin_paths
|
||||
_sublime_darwin_paths=(
|
||||
"/usr/local/bin/smerge"
|
||||
"/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge"
|
||||
"$HOME/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge"
|
||||
)
|
||||
for _sublime_merge_path in $_sublime_darwin_paths; do
|
||||
if [[ -a $_sublime_merge_path ]]; then
|
||||
subm () { "$_sublime_merge_path" "$@" }
|
||||
alias sm=subm
|
||||
break
|
||||
fi
|
||||
done
|
||||
elif [[ "$OSTYPE" = 'cygwin' ]]; then
|
||||
local sublime_merge_cygwin_paths
|
||||
sublime_merge_cygwin_paths=(
|
||||
"$(cygpath $ProgramW6432/Sublime\ Merge)/sublime_merge.exe"
|
||||
)
|
||||
for _sublime_merge_path in $_sublime_merge_cygwin_paths; do
|
||||
if [[ -a $_sublime_merge_path ]]; then
|
||||
subm () { "$_sublime_merge_path" "$@" }
|
||||
alias sm=subm
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
alias smt='sm .'
|
||||
@@ -0,0 +1,35 @@
|
||||
NAME=zsh-navigation-tools
|
||||
|
||||
INSTALL?=install -c
|
||||
PREFIX?=/usr/local
|
||||
SHARE_DIR?=$(DESTDIR)$(PREFIX)/share/$(NAME)
|
||||
DOC_DIR?=$(DESTDIR)$(PREFIX)/share/doc/$(NAME)
|
||||
|
||||
all:
|
||||
|
||||
install:
|
||||
$(INSTALL) -d $(SHARE_DIR)
|
||||
$(INSTALL) -d $(SHARE_DIR)/.config
|
||||
$(INSTALL) -d $(SHARE_DIR)/.config/znt
|
||||
$(INSTALL) -d $(DOC_DIR)
|
||||
cp zsh-navigation-tools.plugin.zsh _n-kill doc/znt-tmux.zsh $(SHARE_DIR)
|
||||
cp README.md NEWS LICENSE doc/img/n-history2.png $(DOC_DIR)
|
||||
if [ x"true" = x"`git rev-parse --is-inside-work-tree 2>/dev/null`" ]; then \
|
||||
git rev-parse HEAD; \
|
||||
else \
|
||||
cat .revision-hash; \
|
||||
fi > $(SHARE_DIR)/.revision-hash
|
||||
:
|
||||
for fname in n-*; do cp "$$fname" $(SHARE_DIR); done; \
|
||||
for fname in znt-*; do cp "$$fname" $(SHARE_DIR); done; \
|
||||
for fname in .config/znt/n-*; do cp "$$fname" $(SHARE_DIR)/.config/znt; done;
|
||||
|
||||
uninstall:
|
||||
rm -f $(SHARE_DIR)/.revision-hash $(SHARE_DIR)/_* $(SHARE_DIR)/zsh-* $(SHARE_DIR)/n-* $(SHARE_DIR)/znt-* $(SHARE_DIR)/.config/znt/n-*
|
||||
[ -d $(SHARE_DIR)/.config/znt ] && rmdir $(SHARE_DIR)/.config/znt || true
|
||||
[ -d $(SHARE_DIR)/.config ] && rmdir $(SHARE_DIR)/.config || true
|
||||
[ -d $(SHARE_DIR) ] && rmdir $(SHARE_DIR) || true
|
||||
rm -f $(DOC_DIR)/README.md $(DOC_DIR)/LICENSE $(DOC_DIR)/n-history2.png
|
||||
[ -d $(DOC_DIR) ] && rmdir $(DOC_DIR) || true
|
||||
|
||||
.PHONY: all install uninstall
|
||||
@@ -0,0 +1,59 @@
|
||||
# The Official Theme of
|
||||
## ## ## ## ##
|
||||
### ### ## ## ##
|
||||
#### #### ## ## ##
|
||||
## ### ## ## #########
|
||||
## ## ## ## ##
|
||||
## ## ## ## ##
|
||||
## ## ######## ## ##
|
||||
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# # # Feel free to customize! # # #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
|
||||
# To easily discover colors and their codes, type `spectrum_ls` in the terminal
|
||||
|
||||
AT_SYMBOL=" @ "
|
||||
IN_SYMBOL=" in "
|
||||
ON_SYMBOL=" on "
|
||||
SYMBOL="$"
|
||||
|
||||
USER_COLOR="%F{001}"
|
||||
DEVICE_COLOR="%F{033}"
|
||||
DIR_COLOR="%F{220}"
|
||||
BRANCH_COLOR="%F{001}"
|
||||
TIME_COLOR="%F{033}"
|
||||
|
||||
username() {
|
||||
echo "$USER_COLOR%n%f"
|
||||
}
|
||||
|
||||
# Returns device name
|
||||
device() {
|
||||
echo "$DEVICE_COLOR%m%f"
|
||||
}
|
||||
|
||||
# The current directory
|
||||
directory() {
|
||||
echo "$DIR_COLOR%1~%f"
|
||||
}
|
||||
|
||||
# Current time with milliseconds
|
||||
current_time() {
|
||||
echo "$TIME_COLOR%*%f"
|
||||
}
|
||||
|
||||
# Return status of the last command
|
||||
return_status() {
|
||||
echo "%(?..%F{001}out %?)%f"
|
||||
}
|
||||
|
||||
# Set the git_prompt_info text
|
||||
ZSH_THEME_GIT_PROMPT_PREFIX="${ON_SYMBOL}${BRANCH_COLOR}"
|
||||
ZSH_THEME_GIT_PROMPT_SUFFIX="%f"
|
||||
ZSH_THEME_GIT_PROMPT_DIRTY=""
|
||||
ZSH_THEME_GIT_PROMPT_CLEAN=""
|
||||
|
||||
# %B and %b make the text bold
|
||||
PROMPT='%b$(username)$AT_SYMBOL$(device)$IN_SYMBOL$(directory)$(git_prompt_info)%b $SYMBOL '
|
||||
RPROMPT="$(return_status) $(current_time)"
|
||||
@@ -0,0 +1,429 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
##############################
|
||||
# CHANGELOG SCRIPT CONSTANTS #
|
||||
##############################
|
||||
|
||||
#* Holds the list of valid types recognized in a commit subject
|
||||
#* and the display string of such type
|
||||
local -A TYPES
|
||||
TYPES=(
|
||||
build "Build system"
|
||||
chore "Chore"
|
||||
ci "CI"
|
||||
docs "Documentation"
|
||||
feat "Features"
|
||||
fix "Bug fixes"
|
||||
perf "Performance"
|
||||
refactor "Refactor"
|
||||
style "Style"
|
||||
test "Testing"
|
||||
)
|
||||
|
||||
#* Types that will be displayed in their own section,
|
||||
#* in the order specified here.
|
||||
local -a MAIN_TYPES
|
||||
MAIN_TYPES=(feat fix perf docs)
|
||||
|
||||
#* Types that will be displayed under the category of other changes
|
||||
local -a OTHER_TYPES
|
||||
OTHER_TYPES=(refactor style other)
|
||||
|
||||
#* Commit types that don't appear in $MAIN_TYPES nor $OTHER_TYPES
|
||||
#* will not be displayed and will simply be ignored.
|
||||
|
||||
|
||||
############################
|
||||
# COMMIT PARSING UTILITIES #
|
||||
############################
|
||||
|
||||
function parse-commit {
|
||||
|
||||
# This function uses the following globals as output: commits (A),
|
||||
# subjects (A), scopes (A) and breaking (A). All associative arrays (A)
|
||||
# have $hash as the key.
|
||||
# - commits holds the commit type
|
||||
# - subjects holds the commit subject
|
||||
# - scopes holds the scope of a commit
|
||||
# - breaking holds the breaking change warning if a commit does
|
||||
# make a breaking change
|
||||
|
||||
function commit:type {
|
||||
local type="$(sed -E 's/^([a-zA-Z_\-]+)(\(.+\))?!?: .+$/\1/' <<< "$1")"
|
||||
|
||||
# If $type doesn't appear in $TYPES array mark it as 'other'
|
||||
if [[ -n "${(k)TYPES[(i)$type]}" ]]; then
|
||||
echo $type
|
||||
else
|
||||
echo other
|
||||
fi
|
||||
}
|
||||
|
||||
function commit:scope {
|
||||
local scope
|
||||
|
||||
# Try to find scope in "type(<scope>):" format
|
||||
scope=$(sed -nE 's/^[a-zA-Z_\-]+\((.+)\)!?: .+$/\1/p' <<< "$1")
|
||||
if [[ -n "$scope" ]]; then
|
||||
echo "$scope"
|
||||
return
|
||||
fi
|
||||
|
||||
# If no scope found, try to find it in "<scope>:" format
|
||||
# Make sure it's not a type before printing it
|
||||
scope=$(sed -nE 's/^([a-zA-Z_\-]+): .+$/\1/p' <<< "$1")
|
||||
if [[ -z "${(k)TYPES[(i)$scope]}" ]]; then
|
||||
echo "$scope"
|
||||
fi
|
||||
}
|
||||
|
||||
function commit:subject {
|
||||
# Only display the relevant part of the commit, i.e. if it has the format
|
||||
# type[(scope)!]: subject, where the part between [] is optional, only
|
||||
# displays subject. If it doesn't match the format, returns the whole string.
|
||||
sed -E 's/^[a-zA-Z_\-]+(\(.+\))?!?: (.+)$/\2/' <<< "$1"
|
||||
}
|
||||
|
||||
# Return subject if the body or subject match the breaking change format
|
||||
function commit:is-breaking {
|
||||
local subject="$1" body="$2" message
|
||||
|
||||
if [[ "$body" =~ "BREAKING CHANGE: (.*)" || \
|
||||
"$subject" =~ '^[^ :\)]+\)?!: (.*)$' ]]; then
|
||||
message="${match[1]}"
|
||||
# skip next paragraphs (separated by two newlines or more)
|
||||
message="${message%%$'\n\n'*}"
|
||||
# ... and replace newlines with spaces
|
||||
echo "${message//$'\n'/ }"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Return truncated hash of the reverted commit
|
||||
function commit:is-revert {
|
||||
local subject="$1" body="$2"
|
||||
|
||||
if [[ "$subject" = Revert* && \
|
||||
"$body" =~ "This reverts commit ([^.]+)\." ]]; then
|
||||
echo "${match[1]:0:7}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse commit with hash $1
|
||||
local hash="$1" subject body warning rhash
|
||||
subject="$(command git show -s --format=%s $hash)"
|
||||
body="$(command git show -s --format=%b $hash)"
|
||||
|
||||
# Commits following Conventional Commits (https://www.conventionalcommits.org/)
|
||||
# have the following format, where parts between [] are optional:
|
||||
#
|
||||
# type[(scope)][!]: subject
|
||||
#
|
||||
# commit body
|
||||
# [BREAKING CHANGE: warning]
|
||||
|
||||
# commits holds the commit type
|
||||
commits[$hash]="$(commit:type "$subject")"
|
||||
# scopes holds the commit scope
|
||||
scopes[$hash]="$(commit:scope "$subject")"
|
||||
# subjects holds the commit subject
|
||||
subjects[$hash]="$(commit:subject "$subject")"
|
||||
|
||||
# breaking holds whether a commit has breaking changes
|
||||
# and its warning message if it does
|
||||
if warning=$(commit:is-breaking "$subject" "$body"); then
|
||||
breaking[$hash]="$warning"
|
||||
fi
|
||||
|
||||
# reverts holds commits reverted in the same release
|
||||
if rhash=$(commit:is-revert "$subject" "$body"); then
|
||||
reverts[$hash]=$rhash
|
||||
fi
|
||||
}
|
||||
|
||||
#############################
|
||||
# RELEASE CHANGELOG DISPLAY #
|
||||
#############################
|
||||
|
||||
function display-release {
|
||||
|
||||
# This function uses the following globals: output, version,
|
||||
# commits (A), subjects (A), scopes (A), breaking (A) and reverts (A).
|
||||
#
|
||||
# - output is the output format to use when formatting (raw|text|md)
|
||||
# - version is the version in which the commits are made
|
||||
# - commits, subjects, scopes, breaking, and reverts are associative arrays
|
||||
# with commit hashes as keys
|
||||
|
||||
# Remove commits that were reverted
|
||||
local hash rhash
|
||||
for hash rhash in ${(kv)reverts}; do
|
||||
if (( ${+commits[$rhash]} )); then
|
||||
# Remove revert commit
|
||||
unset "commits[$hash]" "subjects[$hash]" "scopes[$hash]" "breaking[$hash]"
|
||||
# Remove reverted commit
|
||||
unset "commits[$rhash]" "subjects[$rhash]" "scopes[$rhash]" "breaking[$rhash]"
|
||||
fi
|
||||
done
|
||||
|
||||
# If no commits left skip displaying the release
|
||||
if (( $#commits == 0 )); then
|
||||
return
|
||||
fi
|
||||
|
||||
##* Formatting functions
|
||||
|
||||
# Format the hash according to output format
|
||||
# If no parameter is passed, assume it comes from `$hash`
|
||||
function fmt:hash {
|
||||
#* Uses $hash from outer scope
|
||||
local hash="${1:-$hash}"
|
||||
case "$output" in
|
||||
raw) printf "$hash" ;;
|
||||
text) printf "\e[33m$hash\e[0m" ;; # red
|
||||
md) printf "[\`$hash\`](https://github.com/ohmyzsh/ohmyzsh/commit/$hash)" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Format headers according to output format
|
||||
# Levels 1 to 2 are considered special, the rest are formatted
|
||||
# the same, except in md output format.
|
||||
function fmt:header {
|
||||
local header="$1" level="$2"
|
||||
case "$output" in
|
||||
raw)
|
||||
case "$level" in
|
||||
1) printf "$header\n$(printf '%.0s=' {1..${#header}})\n\n" ;;
|
||||
2) printf "$header\n$(printf '%.0s-' {1..${#header}})\n\n" ;;
|
||||
*) printf "$header:\n\n" ;;
|
||||
esac ;;
|
||||
text)
|
||||
case "$level" in
|
||||
1|2) printf "\e[1;4m$header\e[0m\n\n" ;; # bold, underlined
|
||||
*) printf "\e[1m$header:\e[0m\n\n" ;; # bold
|
||||
esac ;;
|
||||
md) printf "$(printf '%.0s#' {1..${level}}) $header\n\n" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
function fmt:scope {
|
||||
#* Uses $scopes (A) and $hash from outer scope
|
||||
local scope="${1:-${scopes[$hash]}}"
|
||||
|
||||
# Get length of longest scope for padding
|
||||
local max_scope=0 padding=0
|
||||
for hash in ${(k)scopes}; do
|
||||
max_scope=$(( max_scope < ${#scopes[$hash]} ? ${#scopes[$hash]} : max_scope ))
|
||||
done
|
||||
|
||||
# If no scopes, exit the function
|
||||
if [[ $max_scope -eq 0 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Get how much padding is required for this scope
|
||||
padding=$(( max_scope < ${#scope} ? 0 : max_scope - ${#scope} ))
|
||||
padding="${(r:$padding:: :):-}"
|
||||
|
||||
# If no scope, print padding and 3 spaces (equivalent to "[] ")
|
||||
if [[ -z "$scope" ]]; then
|
||||
printf "${padding} "
|
||||
return
|
||||
fi
|
||||
|
||||
# Print [scope]
|
||||
case "$output" in
|
||||
raw|md) printf "[$scope]${padding} " ;;
|
||||
text) printf "[\e[38;5;9m$scope\e[0m]${padding} " ;; # red 9
|
||||
esac
|
||||
}
|
||||
|
||||
# If no parameter is passed, assume it comes from `$subjects[$hash]`
|
||||
function fmt:subject {
|
||||
#* Uses $subjects (A) and $hash from outer scope
|
||||
local subject="${1:-${subjects[$hash]}}"
|
||||
|
||||
# Capitalize first letter of the subject
|
||||
subject="${(U)subject:0:1}${subject:1}"
|
||||
|
||||
case "$output" in
|
||||
raw) printf "$subject" ;;
|
||||
# In text mode, highlight (#<issue>) and dim text between `backticks`
|
||||
text) sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" ;;
|
||||
# In markdown mode, link to (#<issue>) issues
|
||||
md) sed -E 's|#([0-9]+)|[#\1](https://github.com/ohmyzsh/ohmyzsh/issues/\1)|g' <<< "$subject" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
function fmt:type {
|
||||
#* Uses $type from outer scope
|
||||
local type="${1:-${TYPES[$type]:-${(C)type}}}"
|
||||
[[ -z "$type" ]] && return 0
|
||||
case "$output" in
|
||||
raw|md) printf "$type: " ;;
|
||||
text) printf "\e[4m$type\e[24m: " ;; # underlined
|
||||
esac
|
||||
}
|
||||
|
||||
##* Section functions
|
||||
|
||||
function display:version {
|
||||
fmt:header "$version" 2
|
||||
}
|
||||
|
||||
function display:breaking {
|
||||
(( $#breaking != 0 )) || return 0
|
||||
|
||||
case "$output" in
|
||||
raw) fmt:header "BREAKING CHANGES" 3 ;;
|
||||
text|md) fmt:header "⚠ BREAKING CHANGES" 3 ;;
|
||||
esac
|
||||
|
||||
local hash subject
|
||||
for hash message in ${(kv)breaking}; do
|
||||
echo " - $(fmt:hash) $(fmt:subject "${message}")"
|
||||
done | sort
|
||||
echo
|
||||
}
|
||||
|
||||
function display:type {
|
||||
local hash type="$1"
|
||||
|
||||
local -a hashes
|
||||
hashes=(${(k)commits[(R)$type]})
|
||||
|
||||
# If no commits found of type $type, go to next type
|
||||
(( $#hashes != 0 )) || return 0
|
||||
|
||||
fmt:header "${TYPES[$type]}" 3
|
||||
for hash in $hashes; do
|
||||
echo " - $(fmt:hash) $(fmt:scope)$(fmt:subject)"
|
||||
done | sort -k3 # sort by scope
|
||||
echo
|
||||
}
|
||||
|
||||
function display:others {
|
||||
local hash type
|
||||
|
||||
# Commits made under types considered other changes
|
||||
local -A changes
|
||||
changes=(${(kv)commits[(R)${(j:|:)OTHER_TYPES}]})
|
||||
|
||||
# If no commits found under "other" types, don't display anything
|
||||
(( $#changes != 0 )) || return 0
|
||||
|
||||
fmt:header "Other changes" 3
|
||||
for hash type in ${(kv)changes}; do
|
||||
case "$type" in
|
||||
other) echo " - $(fmt:hash) $(fmt:scope)$(fmt:subject)" ;;
|
||||
*) echo " - $(fmt:hash) $(fmt:scope)$(fmt:type)$(fmt:subject)" ;;
|
||||
esac
|
||||
done | sort -k3 # sort by scope
|
||||
echo
|
||||
}
|
||||
|
||||
##* Release sections order
|
||||
|
||||
# Display version header
|
||||
display:version
|
||||
|
||||
# Display breaking changes first
|
||||
display:breaking
|
||||
|
||||
# Display changes for commit types in the order specified
|
||||
for type in $MAIN_TYPES; do
|
||||
display:type "$type"
|
||||
done
|
||||
|
||||
# Display other changes
|
||||
display:others
|
||||
}
|
||||
|
||||
function main {
|
||||
# $1 = until commit, $2 = since commit
|
||||
local until="$1" since="$2"
|
||||
|
||||
# $3 = output format (--text|--raw|--md)
|
||||
# --md: uses markdown formatting
|
||||
# --raw: outputs without style
|
||||
# --text: uses ANSI escape codes to style the output
|
||||
local output=${${3:-"--text"}#--*}
|
||||
|
||||
if [[ -z "$until" ]]; then
|
||||
until=HEAD
|
||||
fi
|
||||
|
||||
if [[ -z "$since" ]]; then
|
||||
# If $since is not specified:
|
||||
# 1) try to find the version used before updating
|
||||
# 2) try to find the first version tag before $until
|
||||
since=$(command git config --get oh-my-zsh.lastVersion 2>/dev/null) || \
|
||||
since=$(command git describe --abbrev=0 --tags "$until^" 2>/dev/null) || \
|
||||
unset since
|
||||
elif [[ "$since" = --all ]]; then
|
||||
unset since
|
||||
fi
|
||||
|
||||
# Commit classification arrays
|
||||
local -A commits subjects scopes breaking reverts
|
||||
local truncate=0 read_commits=0
|
||||
local hash version tag
|
||||
|
||||
# Get the first version name:
|
||||
# 1) try tag-like version, or
|
||||
# 2) try name-rev, or
|
||||
# 3) try branch name, or
|
||||
# 4) try short hash
|
||||
version=$(command git describe --tags $until 2>/dev/null) \
|
||||
|| version=$(command git name-rev --no-undefined --name-only --exclude="remotes/*" $until 2>/dev/null) \
|
||||
|| version=$(command git symbolic-ref --quiet --short $until 2>/dev/null) \
|
||||
|| version=$(command git rev-parse --short $until 2>/dev/null)
|
||||
|
||||
# Get commit list from $until commit until $since commit, or until root
|
||||
# commit if $since is unset, in short hash form.
|
||||
# --first-parent is used when dealing with merges: it only prints the
|
||||
# merge commit, not the commits of the merged branch.
|
||||
command git rev-list --first-parent --abbrev-commit --abbrev=7 ${since:+$since..}$until | while read hash; do
|
||||
# Truncate list on versions with a lot of commits
|
||||
if [[ -z "$since" ]] && (( ++read_commits > 35 )); then
|
||||
truncate=1
|
||||
break
|
||||
fi
|
||||
|
||||
# If we find a new release (exact tag)
|
||||
if tag=$(command git describe --exact-match --tags $hash 2>/dev/null); then
|
||||
# Output previous release
|
||||
display-release
|
||||
# Reinitialize commit storage
|
||||
commits=()
|
||||
subjects=()
|
||||
scopes=()
|
||||
breaking=()
|
||||
reverts=()
|
||||
# Start work on next release
|
||||
version="$tag"
|
||||
read_commits=1
|
||||
fi
|
||||
|
||||
parse-commit "$hash"
|
||||
done
|
||||
|
||||
display-release
|
||||
|
||||
if (( truncate )); then
|
||||
echo " ...more commits omitted"
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
cd "$ZSH"
|
||||
|
||||
# Use raw output if stdout is not a tty
|
||||
if [[ ! -t 1 && -z "$3" ]]; then
|
||||
main "$1" "$2" --raw
|
||||
else
|
||||
main "$@"
|
||||
fi
|
||||
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
if [ -z "$ZSH_VERSION" ]; then
|
||||
exec zsh "$0"
|
||||
fi
|
||||
|
||||
cd "$ZSH"
|
||||
|
||||
# Use colors, but only if connected to a terminal
|
||||
# and that terminal supports them.
|
||||
|
||||
local -a RAINBOW
|
||||
local RED GREEN YELLOW BLUE BOLD DIM UNDER RESET
|
||||
|
||||
if [ -t 1 ]; then
|
||||
RAINBOW=(
|
||||
"$(printf '\033[38;5;196m')"
|
||||
"$(printf '\033[38;5;202m')"
|
||||
"$(printf '\033[38;5;226m')"
|
||||
"$(printf '\033[38;5;082m')"
|
||||
"$(printf '\033[38;5;021m')"
|
||||
"$(printf '\033[38;5;093m')"
|
||||
"$(printf '\033[38;5;163m')"
|
||||
)
|
||||
|
||||
RED=$(printf '\033[31m')
|
||||
GREEN=$(printf '\033[32m')
|
||||
YELLOW=$(printf '\033[33m')
|
||||
BLUE=$(printf '\033[34m')
|
||||
BOLD=$(printf '\033[1m')
|
||||
DIM=$(printf '\033[2m')
|
||||
UNDER=$(printf '\033[4m')
|
||||
RESET=$(printf '\033[m')
|
||||
fi
|
||||
|
||||
# Update upstream remote to ohmyzsh org
|
||||
git remote -v | while read remote url extra; do
|
||||
case "$url" in
|
||||
https://github.com/robbyrussell/oh-my-zsh(|.git))
|
||||
git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git"
|
||||
break ;;
|
||||
git@github.com:robbyrussell/oh-my-zsh(|.git))
|
||||
git remote set-url "$remote" "git@github.com:ohmyzsh/ohmyzsh.git"
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Set git-config values known to fix git errors
|
||||
# Line endings (#4069)
|
||||
git config core.eol lf
|
||||
git config core.autocrlf false
|
||||
# zeroPaddedFilemode fsck errors (#4963)
|
||||
git config fsck.zeroPaddedFilemode ignore
|
||||
git config fetch.fsck.zeroPaddedFilemode ignore
|
||||
git config receive.fsck.zeroPaddedFilemode ignore
|
||||
# autostash on rebase (#7172)
|
||||
resetAutoStash=$(git config --bool rebase.autoStash 2>/dev/null)
|
||||
git config rebase.autoStash true
|
||||
|
||||
local ret=0
|
||||
|
||||
# Update Oh My Zsh
|
||||
printf "${BLUE}%s${RESET}\n" "Updating Oh My Zsh"
|
||||
last_commit=$(git rev-parse HEAD)
|
||||
if git pull --rebase --stat origin master; then
|
||||
# Check if it was really updated or not
|
||||
if [[ "$(git rev-parse HEAD)" = "$last_commit" ]]; then
|
||||
message="Oh My Zsh is already at the latest version."
|
||||
ret=80 # non-zero exit code to indicate no changes pulled
|
||||
else
|
||||
message="Hooray! Oh My Zsh has been updated!"
|
||||
|
||||
# Save the commit prior to updating
|
||||
git config oh-my-zsh.lastVersion "$last_commit"
|
||||
|
||||
# Display changelog with less if available, otherwise just print it to the terminal
|
||||
if [[ "$1" = --interactive ]]; then
|
||||
if (( $+commands[less] )); then
|
||||
"$ZSH/tools/changelog.sh" HEAD "$last_commit" --text | LESS= command less -R
|
||||
else
|
||||
"$ZSH/tools/changelog.sh" HEAD "$last_commit"
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "${BLUE}%s \`${BOLD}%s${RESET}${BLUE}\`${RESET}\n" "You can see the changelog again with" "omz changelog"
|
||||
fi
|
||||
|
||||
printf '%s %s__ %s %s %s %s %s__ %s\n' $RAINBOW $RESET
|
||||
printf '%s ____ %s/ /_ %s ____ ___ %s__ __ %s ____ %s_____%s/ /_ %s\n' $RAINBOW $RESET
|
||||
printf '%s / __ \%s/ __ \ %s / __ `__ \%s/ / / / %s /_ / %s/ ___/%s __ \ %s\n' $RAINBOW $RESET
|
||||
printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s / /_%s(__ )%s / / / %s\n' $RAINBOW $RESET
|
||||
printf '%s\____/%s_/ /_/ %s /_/ /_/ /_/%s\__, / %s /___/%s____/%s_/ /_/ %s\n' $RAINBOW $RESET
|
||||
printf '%s %s %s %s /____/ %s %s %s %s\n' $RAINBOW $RESET
|
||||
printf '\n'
|
||||
printf "${BLUE}%s${RESET}\n" "$message"
|
||||
printf "${BLUE}${BOLD}%s ${UNDER}%s${RESET}\n" "To keep up with the latest news and updates, follow us on Twitter:" "https://twitter.com/ohmyzsh"
|
||||
printf "${BLUE}${BOLD}%s ${UNDER}%s${RESET}\n" "Want to get involved in the community? Join our Discord:" "https://discord.gg/ohmyzsh"
|
||||
printf "${BLUE}${BOLD}%s ${UNDER}%s${RESET}\n" "Get your Oh My Zsh swag at:" "https://shop.planetargon.com/collections/oh-my-zsh"
|
||||
else
|
||||
ret=$?
|
||||
printf "${RED}%s${RESET}\n" 'There was an error updating. Try again later?'
|
||||
fi
|
||||
|
||||
# Unset git-config values set just for the upgrade
|
||||
case "$resetAutoStash" in
|
||||
"") git config --unset rebase.autoStash ;;
|
||||
*) git config rebase.autoStash "$resetAutoStash" ;;
|
||||
esac
|
||||
|
||||
# Exit with `1` if the update failed
|
||||
exit $ret
|
||||
Reference in New Issue
Block a user