├── .editorconfig ├── license ├── readme.md ├── up.fish └── up.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = tab 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.json] 12 | indent_size = 2 13 | indent_style = space 14 | 15 | [*.md] 16 | indent_style = space 17 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Shannon Moeller (shannonmoeller.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # `up` 2 | 3 | Stop typing `../../..` endlessly. Use tab completion instead! Using `up` allows you to change your current directory to a parent of the current directory where the parent is specified by name or index. 4 | 5 | ## Install 6 | 7 | Written in 100% shell script, `up.sh` registers the `up` function and some completion functions via your `.bashrc` or `.zshrc` file. 8 | 9 | ### bash 10 | 11 | ``` 12 | curl --create-dirs -o ~/.config/up/up.sh https://raw.githubusercontent.com/shannonmoeller/up/master/up.sh 13 | echo 'source ~/.config/up/up.sh' >> ~/.bashrc 14 | ``` 15 | 16 | ### zsh 17 | 18 | ``` 19 | curl --create-dirs -o ~/.config/up/up.sh https://raw.githubusercontent.com/shannonmoeller/up/master/up.sh 20 | echo 'source ~/.config/up/up.sh' >> ~/.zshrc 21 | ``` 22 | 23 | ### fish 24 | 25 | Written in 100% fish script, `up.fish` registers the `up` function and some completion functions via `funcsave`. 26 | 27 | ``` 28 | curl --create-dirs -o ~/.config/up/up.fish https://raw.githubusercontent.com/shannonmoeller/up/master/up.fish 29 | source ~/.config/up/up.fish 30 | ``` 31 | 32 | ## Usage 33 | 34 | ``` 35 | $ up [dir|num|-] 36 | 37 | dir full or partial name of any parent directory 38 | num number of times you'd have to type `../` 39 | - previous working directory 40 | ``` 41 | 42 | ## Examples 43 | 44 | Up one level: 45 | 46 | ``` 47 | /home/chuck/foo/bar/baz/head/foot $ up 48 | /home/chuck/foo/bar/baz/head $ 49 | ``` 50 | 51 | Up multiple levels: 52 | 53 | ``` 54 | /home/chuck/foo/bar/baz/head/foot $ up 4 55 | /home/chuck/foo $ 56 | ``` 57 | 58 | Up by full name: 59 | 60 | ``` 61 | /home/chuck/foo/bar/baz/head/foot $ up bar 62 | /home/chuck/foo/bar $ 63 | ``` 64 | 65 | Up by partial name: 66 | 67 | ``` 68 | /home/chuck/foo/bar/baz/head/foot $ up ba 69 | /home/chuck/foo/bar/baz $ 70 | ``` 71 | 72 | Tab completion: 73 | 74 | ``` 75 | /home/chuck/foo/bar/baz/head/foot $ up 76 | bar/ baz/ chuck/ foo/ head/ home/ 77 | 78 | /home/chuck/foo/bar/baz/head/foot $ up h 79 | head/ home/ 80 | 81 | /home/chuck/foo/bar/baz/head/foot $ up ho 82 | /home/chuck/foo/bar/baz/head/foot $ up home/ 83 | /home $ 84 | ``` 85 | 86 | ---- 87 | 88 | MIT © [Shannon Moeller](http://shannonmoeller.com) 89 | -------------------------------------------------------------------------------- /up.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | # 3 | # up.fish: Quickly traverse the current working path. 4 | # [ Author ] endowdly 5 | # [ Email ] endowdly@gmail.com 6 | # [ Date Created ] 23 May, 2017 7 | # [ Last Modified ] 26 May, 2017 8 | # 9 | # fish fork from up.sh by Shannon Moeller 10 | # 11 | # source to use: source /path/to/up/up.fish 12 | 13 | function _updir 14 | if test $argv[1] = '/' -o -z $argv[1] -o -z $argv[2] 15 | return 16 | end 17 | 18 | set --local p (dirname "$argv[1]") 19 | set --local a (basename "$p") 20 | set --local b (basename "$argv[2]") 21 | 22 | if test -z $a -o -z $b 23 | return 24 | end 25 | 26 | if string match -iq "$b*" $a 27 | echo $p 28 | return 29 | end 30 | 31 | _updir $p $argv[2] 32 | # Ooo, look at this clever recursion! 33 | end 34 | 35 | function _upnum 36 | if test -z $argv[1] -o -z $argv[2] 37 | return 38 | end 39 | 40 | set --local p $argv[1] 41 | set --local i $argv[2] 42 | 43 | while test $i -ne 0 44 | set p (dirname $p) 45 | set i (math $i - 1) 46 | end 47 | 48 | echo $p 49 | end 50 | 51 | function up 52 | # up one 53 | if not count $argv > /dev/null 54 | cd .. 55 | return 56 | end 57 | 58 | # go back 59 | if test $argv[1] = '-' -o -d $argv[1] 60 | cd $argv[1] 61 | return 62 | end 63 | 64 | # check for num 65 | set --local regex '^[0-9]+$' 66 | 67 | if string match -rq $regex $argv[1] 68 | set d (_upnum $PWD $argv[1]) 69 | else 70 | set d (_updir $PWD $argv[1]) 71 | end 72 | 73 | if test -d $d 74 | cd $d 75 | return 76 | end 77 | 78 | echo -e "usage: up [dir|num|-]\npwd: $PWD" 79 | end 80 | 81 | function _up 82 | set --local p (string trim --chars=/ (dirname $PWD) | string split /) 83 | 84 | for d in $p 85 | echo $d 86 | end 87 | end 88 | 89 | complete -c up -fa "(_up)" 90 | funcsave up 91 | funcsave _up 92 | funcsave _updir 93 | funcsave _upnum 94 | 95 | # __END___ 96 | 97 | -------------------------------------------------------------------------------- /up.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # up.sh: Quickly traverse up the current working path. 4 | # Author: Shannon Moeller 5 | # Source to use: [ -f /path/to/up.sh ] && . /path/to/up.sh 6 | 7 | __updir() { 8 | if [[ "$1" == "/" || -z "$1" || -z "$2" ]]; then 9 | return 10 | fi 11 | 12 | local p="$(dirname "$1")" 13 | local a="$(basename "$p")" 14 | local b="$(basename "$2")" 15 | 16 | if [[ -z "$a" || -z "$b" ]]; then 17 | return 18 | fi 19 | 20 | if [[ "$a" == "$b"* ]]; then 21 | echo "$p" 22 | return 23 | fi 24 | 25 | __updir "$p" "$2" 26 | } 27 | 28 | __upnum() { 29 | if [[ -z "$1" || -z "$2" || ! "$2" =~ ^[0-9]+$ ]]; then 30 | return 31 | fi 32 | 33 | local p="$1" 34 | local i="$2" 35 | 36 | while (( i-- )); do 37 | p="$(dirname "$p")" 38 | done 39 | 40 | echo "$p" 41 | } 42 | 43 | _up() { 44 | local p="$(dirname $PWD)" 45 | local w="${COMP_WORDS[COMP_CWORD]}" 46 | 47 | COMPREPLY=( $(IFS=';' compgen -S/ -W "${p//\//;}" -- "$w") ) 48 | } 49 | 50 | up() { 51 | # up one 52 | if (( ! $# )); then 53 | cd .. 54 | return 55 | fi 56 | 57 | # up dir 58 | local d="$(__updir "$PWD" "$1")" 59 | 60 | if [[ -d "$d" ]]; then 61 | cd "$d" 62 | return 63 | fi 64 | 65 | # up num 66 | local n="$(__upnum "$PWD" "$1")" 67 | 68 | if [[ -d "$n" ]]; then 69 | cd "$n" 70 | return 71 | fi 72 | 73 | # fallback 74 | if [[ $1 == - || -d $1 ]]; then 75 | cd $1 76 | return 77 | fi 78 | 79 | # usage 80 | echo -e "usage: up [dir|num|-]\npwd: $PWD" 81 | } 82 | 83 | # zsh compatibility 84 | if [[ -n ${ZSH_VERSION-} ]]; then 85 | autoload -U +X bashcompinit && bashcompinit 86 | fi 87 | 88 | # tab-completion 89 | complete -o nospace -F _up up 90 | --------------------------------------------------------------------------------