Add zsh/oh my zsh/w10k

This commit is contained in:
Tim
2020-01-22 17:37:20 +01:00
committed by Tim
parent ca9600417a
commit 55329b15f9
839 changed files with 62270 additions and 13 deletions

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Markus Færevaag
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.

View File

@ -0,0 +1,159 @@
wd
==
[![Build Status](https://travis-ci.org/mfaerevaag/wd.png?branch=master)](https://travis-ci.org/mfaerevaag/wd)
`wd` (*warp directory*) lets you jump to custom directories in zsh, without using `cd`. Why? Because `cd` seems inefficient when the folder is frequently visited or has a long path.
![tty.gif](https://raw.githubusercontent.com/mfaerevaag/wd/master/tty.gif)
*NEWS*: If you are not using zsh, check out the c-port, [wd-c](https://github.com/mfaerevaag/wd-c), which works with all shells using wrapper functions.
### Setup
### oh-my-zsh
`wd` comes bundled with [oh-my-zshell](https://github.com/ohmyzsh/ohmyzsh)!
Just add the plugin in your `~/.zshrc` file:
plugins=(... wd)
#### Automatic
Run either in terminal:
* `curl -L https://github.com/mfaerevaag/wd/raw/master/install.sh | sh`
* `wget --no-check-certificate https://github.com/mfaerevaag/wd/raw/master/install.sh -O - | sh`
##### Arch ([AUR](https://aur.archlinux.org/))
# yaourt -S zsh-plugin-wd-git
#### Manual
* Clone this repo to your liking
* Add `wd` function to `.zshrc` (or `.profile` etc.):
wd() {
. ~/path/to/cloned/repo/wd/wd.sh
}
* Install manpage. From `wd`'s base directory (requires root permissions):
# cp wd.1 /usr/share/man/man1/wd.1
# chmod 644 /usr/share/man/man1/wd.1
Note, when pulling and updating `wd`, you'll need to do this again in case of changes to the manpage.
#### Completion
If you're NOT using [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh) and you want to utilize the zsh-completion feature, you will also need to add the path to your `wd` installation (`~/bin/wd` if you used the automatic installer) to your `fpath`. E.g. in your `~/.zshrc`:
fpath=(~/path/to/wd $fpath)
Also, you may have to force a rebuild of `zcompdump` by running:
$ rm -f ~/.zcompdump; compinit
### Usage
* Add warp point to current working directory:
$ wd add foo
If a warp point with the same name exists, use `add!` to overwrite it.
Note, a warp point cannot contain colons, or only consist of only spaces and dots. The first will conflict in how `wd` stores the warp points, and the second will conflict with other features, as below.
You can omit point name to use the current directory's name instead.
* From an other directory (not necessarily), warp to `foo` with:
$ wd foo
* You can warp back to previous directory, and so on, with this dot syntax:
$ wd ..
$ wd ...
This is a wrapper for the zsh `dirs` function.
(You might need `setopt AUTO_PUSHD` in your `.zshrc` if you hare not using [oh-my-zshell](https://github.com/ohmyzsh/ohmyzsh)).
* Remove warp point test point:
$ wd rm foo
You can omit point name to use the current directory's name instead.
* List all warp points (stored in `~/.warprc`):
$ wd list
* List files in given warp point:
$ wd ls foo
* Show path of given warp point:
$ wd path foo
* List warp points to current directory, or optionally, path to given warp point:
$ wd show
* Remove warp points to non-existent directories.
$ wd clean
Use `clean!` to not be prompted with confirmation (force).
* Print usage with no opts or the `help` argument:
$ wd help
* Print the running version of `wd`:
$ wd --version
* Specifically set the config file (default `~/.warprc`), which is useful when testing:
$ wd --config ./file <action>
* Force `exit` with return code after running. This is not default, as it will *exit your terminal*, though required when testing/debugging.
$ wd --debug <action>
* Silence all output:
$ wd --quiet <action>
### Testing
`wd` comes with a small test suite, run with [shunit2](https://code.google.com/p/shunit2/). This can be used to confirm that things are working as it should on your setup, or to demonstrate an issue.
To run, simply `cd` into the `test` directory and run the `tests.sh`.
$ ./tests.sh
### License
The project is licensed under the [MIT-license](https://github.com/mfaerevaag/wd/blob/master/LICENSE).
### Finally
If you have issues, feedback or improvements, don't hesitate to report it or submit a pull-request. In the case of an issue, we would much appreciate if you would include a failing test in `test/tests.sh`. For an explanation on how to run the tests, read the section "Testing" in this README.
Credit to [altschuler](https://github.com/altschuler) for an awesome idea.
Hope you enjoy!

View File

@ -0,0 +1,93 @@
#compdef wd
zstyle ':completion:*:descriptions' format '%B%d%b'
zstyle ':completion::complete:wd:*:commands' group-name commands
zstyle ':completion::complete:wd:*:warp_points' group-name warp_points
zstyle ':completion::complete:wd::' list-grouped
zmodload zsh/mapfile
function _wd() {
local CONFIG=$HOME/.warprc
local ret=1
local -a commands
local -a warp_points
warp_points=( "${(f)mapfile[$CONFIG]//$HOME/~}" )
typeset -A points
while read -r line
do
arr=(${(s,:,)line})
name=${arr[1]}
target_path=${arr[2]}
# replace ~ from path to fix completion (#17)
target_path=${target_path/#\~/$HOME}
points[$name]=$target_path
done < $CONFIG
commands=(
'add:Adds the current working directory to your warp points'
'add!:Overwrites existing warp point'
'rm:Removes the given warp point'
'list:Outputs all stored warp points'
'ls:Show files from given warp point'
'path:Show path to given warp point'
'show:Outputs all warp points that point to the current directory or shows a specific target directory for a point'
'help:Show this extremely helpful text'
'clean:Remove points warping to nonexistent directories'
'clean!:Remove nonexistent directories without confirmation'
'..:Go back to last directory'
)
_arguments -C \
'1: :->first_arg' \
'2: :->second_arg' && ret=0
local target=$words[2]
case $state in
first_arg)
_describe -t warp_points "Warp points" warp_points && ret=0
_describe -t commands "Commands" commands && ret=0
;;
second_arg)
case $target in
add\!|rm)
_describe -t points "Warp points" warp_points && ret=0
;;
add)
_message 'Write the name of your warp point' && ret=0
;;
show)
_describe -t points "Warp points" warp_points && ret=0
;;
ls)
_describe -t points "Warp points" warp_points && ret=0
;;
path)
_describe -t points "Warp points" warp_points && ret=0
;;
*)
# complete sub directories from the warp point
_path_files -W "(${points[$target]})" -/ && ret=0
;;
esac
;;
esac
return $ret
}
_wd "$@"
# Local Variables:
# mode: Shell-Script
# sh-indentation: 2
# indent-tabs-mode: nil
# sh-basic-offset: 2
# End:
# vim: ft=zsh sw=2 ts=2 et

View File

@ -0,0 +1,7 @@
# WARP DIRECTORY
# ==============
# oh-my-zsh plugin
#
# @github.com/mfaerevaag/wd
eval "wd() { source '${0:A:h}/wd.sh' }"

View File

@ -0,0 +1,479 @@
#!/bin/zsh
# WARP DIRECTORY
# ==============
# Jump to custom directories in terminal
# because `cd` takes too long...
#
# @github.com/mfaerevaag/wd
# version
readonly WD_VERSION=0.4.6
# colors
readonly WD_BLUE="\033[96m"
readonly WD_GREEN="\033[92m"
readonly WD_YELLOW="\033[93m"
readonly WD_RED="\033[91m"
readonly WD_NOC="\033[m"
## functions
# helpers
wd_yesorno()
{
# variables
local question="${1}"
local prompt="${question} "
local yes_RETVAL="0"
local no_RETVAL="3"
local RETVAL=""
local answer=""
# read-eval loop
while true ; do
printf $prompt
read -r answer
case ${answer:=${default}} in
Y|y|YES|yes|Yes )
RETVAL=${yes_RETVAL} && \
break
;;
N|n|NO|no|No )
RETVAL=${no_RETVAL} && \
break
;;
* )
echo "Please provide a valid answer (y or n)"
;;
esac
done
return ${RETVAL}
}
wd_print_msg()
{
if [[ -z $wd_quiet_mode ]]
then
local color=$1
local msg=$2
if [[ $color == "" || $msg == "" ]]
then
print " ${WD_RED}*${WD_NOC} Could not print message. Sorry!"
else
print " ${color}*${WD_NOC} ${msg}"
fi
fi
}
wd_print_usage()
{
cat <<- EOF
Usage: wd [command] [point]
Commands:
add <point> Adds the current working directory to your warp points
add Adds the current working directory to your warp points with current directory's name
add! <point> Overwrites existing warp point
add! Overwrites existing warp point with current directory's name
rm <point> Removes the given warp point
rm Removes the given warp point with current directory's name
show <point> Print path to given warp point
show Print warp points to current directory
list Print all stored warp points
ls <point> Show files from given warp point (ls)
path <point> Show the path to given warp point (pwd)
clean! Remove points warping to nonexistent directories
-v | --version Print version
-d | --debug Exit after execution with exit codes (for testing)
-c | --config Specify config file (default ~/.warprc)
-q | --quiet Suppress all output
help Show this extremely helpful text
EOF
}
wd_exit_fail()
{
local msg=$1
wd_print_msg $WD_RED $msg
WD_EXIT_CODE=1
}
wd_exit_warn()
{
local msg=$1
wd_print_msg $WD_YELLOW $msg
WD_EXIT_CODE=1
}
wd_getdir()
{
local name_arg=$1
point=$(wd_show $name_arg)
dir=${point:28+$#name_arg+7}
if [[ -z $name_arg ]]; then
wd_exit_fail "You must enter a warp point"
break
elif [[ -z $dir ]]; then
wd_exit_fail "Unknown warp point '${name_arg}'"
break
fi
}
# core
wd_warp()
{
local point=$1
local sub=$2
if [[ $point =~ "^\.+$" ]]
then
if [[ $#1 < 2 ]]
then
wd_exit_warn "Warping to current directory?"
else
(( n = $#1 - 1 ))
cd -$n > /dev/null
fi
elif [[ ${points[$point]} != "" ]]
then
if [[ $sub != "" ]]
then
cd ${points[$point]/#\~/$HOME}/$sub
else
cd ${points[$point]/#\~/$HOME}
fi
else
wd_exit_fail "Unknown warp point '${point}'"
fi
}
wd_add()
{
local force=$1
local point=$2
if [[ $point == "" ]]
then
point=$(basename $PWD)
fi
if [[ $point =~ "^[\.]+$" ]]
then
wd_exit_fail "Warp point cannot be just dots"
elif [[ $point =~ "[[:space:]]+" ]]
then
wd_exit_fail "Warp point should not contain whitespace"
elif [[ $point == *:* ]]
then
wd_exit_fail "Warp point cannot contain colons"
elif [[ ${points[$point]} == "" ]] || $force
then
wd_remove $point > /dev/null
printf "%q:%s\n" "${point}" "${PWD/#$HOME/~}" >> $WD_CONFIG
wd_print_msg $WD_GREEN "Warp point added"
# override exit code in case wd_remove did not remove any points
# TODO: we should handle this kind of logic better
WD_EXIT_CODE=0
else
wd_exit_warn "Warp point '${point}' already exists. Use 'add!' to overwrite."
fi
}
wd_remove()
{
local point=$1
if [[ $point == "" ]]
then
point=$(basename $PWD)
fi
if [[ ${points[$point]} != "" ]]
then
local config_tmp=$WD_CONFIG.tmp
if sed -n "/^${point}:.*$/!p" $WD_CONFIG > $config_tmp && mv $config_tmp $WD_CONFIG
then
wd_print_msg $WD_GREEN "Warp point removed"
else
wd_exit_fail "Something bad happened! Sorry."
fi
else
wd_exit_fail "Warp point was not found"
fi
}
wd_list_all()
{
wd_print_msg $WD_BLUE "All warp points:"
entries=$(sed "s:${HOME}:~:g" $WD_CONFIG)
max_warp_point_length=0
while IFS= read -r line
do
arr=(${(s,:,)line})
key=${arr[1]}
length=${#key}
if [[ length -gt max_warp_point_length ]]
then
max_warp_point_length=$length
fi
done <<< $entries
while IFS= read -r line
do
if [[ $line != "" ]]
then
arr=(${(s,:,)line})
key=${arr[1]}
val=${arr[2]}
if [[ -z $wd_quiet_mode ]]
then
printf "%${max_warp_point_length}s -> %s\n" $key $val
fi
fi
done <<< $entries
}
wd_ls()
{
wd_getdir $1
ls ${dir/#\~/$HOME}
}
wd_path()
{
wd_getdir $1
echo $(echo $dir | sed "s:${HOME}:~:g")
}
wd_show()
{
local name_arg=$1
# if there's an argument we look up the value
if [[ ! -z $name_arg ]]
then
if [[ -z $points[$name_arg] ]]
then
wd_print_msg $WD_BLUE "No warp point named $name_arg"
else
wd_print_msg $WD_GREEN "Warp point: ${WD_GREEN}$name_arg${WD_NOC} -> $points[$name_arg]"
fi
else
# hax to create a local empty array
local wd_matches
wd_matches=()
# do a reverse lookup to check whether PWD is in $points
PWD="${PWD/$HOME/~}"
if [[ ${points[(r)$PWD]} == $PWD ]]
then
for name in ${(k)points}
do
if [[ $points[$name] == $PWD ]]
then
wd_matches[$(($#wd_matches+1))]=$name
fi
done
wd_print_msg $WD_BLUE "$#wd_matches warp point(s) to current directory: ${WD_GREEN}$wd_matches${WD_NOC}"
else
wd_print_msg $WD_YELLOW "No warp point to $(echo $PWD | sed "s:$HOME:~:")"
fi
fi
}
wd_clean() {
local force=$1
local count=0
local wd_tmp=""
while read line
do
if [[ $line != "" ]]
then
arr=(${(s,:,)line})
key=${arr[1]}
val=${arr[2]}
if [ -d "${val/#\~/$HOME}" ]
then
wd_tmp=$wd_tmp"\n"`echo $line`
else
wd_print_msg $WD_YELLOW "Nonexistent directory: ${key} -> ${val}"
count=$((count+1))
fi
fi
done < $WD_CONFIG
if [[ $count -eq 0 ]]
then
wd_print_msg $WD_BLUE "No warp points to clean, carry on!"
else
if $force || wd_yesorno "Removing ${count} warp points. Continue? (Y/n)"
then
echo $wd_tmp >! $WD_CONFIG
wd_print_msg $WD_GREEN "Cleanup complete. ${count} warp point(s) removed"
else
wd_print_msg $WD_BLUE "Cleanup aborted"
fi
fi
}
local WD_CONFIG=$HOME/.warprc
local WD_QUIET=0
local WD_EXIT_CODE=0
local WD_DEBUG=0
# Parse 'meta' options first to avoid the need to have them before
# other commands. The `-D` flag consumes recognized options so that
# the actual command parsing won't be affected.
zparseopts -D -E \
c:=wd_alt_config -config:=wd_alt_config \
q=wd_quiet_mode -quiet=wd_quiet_mode \
v=wd_print_version -version=wd_print_version \
d=wd_debug_mode -debug=wd_debug_mode
if [[ ! -z $wd_print_version ]]
then
echo "wd version $WD_VERSION"
fi
if [[ ! -z $wd_alt_config ]]
then
WD_CONFIG=$wd_alt_config[2]
fi
# check if config file exists
if [ ! -e $WD_CONFIG ]
then
# if not, create config file
touch $WD_CONFIG
fi
# load warp points
typeset -A points
while read -r line
do
arr=(${(s,:,)line})
key=${arr[1]}
# join the rest, in case the path contains colons
val=${(j,:,)arr[2,-1]}
points[$key]=$val
done < $WD_CONFIG
# get opts
args=$(getopt -o a:r:c:lhs -l add:,rm:,clean\!,list,ls:,path:,help,show -- $*)
# check if no arguments were given, and that version is not set
if [[ ($? -ne 0 || $#* -eq 0) && -z $wd_print_version ]]
then
wd_print_usage
# check if config file is writeable
elif [ ! -w $WD_CONFIG ]
then
# do nothing
# can't run `exit`, as this would exit the executing shell
wd_exit_fail "\'$WD_CONFIG\' is not writeable."
else
# parse rest of options
for o
do
case "$o"
in
-a|--add|add)
wd_add false $2
break
;;
-a!|--add!|add!)
wd_add true $2
break
;;
-r|--remove|rm)
wd_remove $2
break
;;
-l|list)
wd_list_all
break
;;
-ls|ls)
wd_ls $2
break
;;
-p|--path|path)
wd_path $2
break
;;
-h|--help|help)
wd_print_usage
break
;;
-s|--show|show)
wd_show $2
break
;;
-c|--clean|clean)
wd_clean false
break
;;
-c!|--clean!|clean!)
wd_clean true
break
;;
*)
wd_warp $o $2
break
;;
--)
break
;;
esac
done
fi
## garbage collection
# if not, next time warp will pick up variables from this run
# remember, there's no sub shell
unset wd_warp
unset wd_add
unset wd_remove
unset wd_show
unset wd_list_all
unset wd_print_msg
unset wd_yesorno
unset wd_print_usage
unset wd_alt_config
unset wd_quiet_mode
unset wd_print_version
unset args
unset points
unset val &> /dev/null # fixes issue #1
if [[ ! -z $wd_debug_mode ]]
then
exit $WD_EXIT_CODE
else
unset wd_debug_mode
fi