From 31b8228fd8f376f82b9e966c97c0b007eb930a4f Mon Sep 17 00:00:00 2001 From: gd Date: Fri, 7 Jan 2022 20:10:17 +0300 Subject: [PATCH] init --- COPYING | 24 ++++++++++ README | 92 ++++++++++++++++++++++++++++++++++++ goto.sh | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 COPYING create mode 100644 README create mode 100644 goto.sh diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/COPYING @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to diff --git a/README b/README new file mode 100644 index 0000000..16500b8 --- /dev/null +++ b/README @@ -0,0 +1,92 @@ +**** +GOTO +**** + +A faster way to cd to commonly used directories inspired by commacd. Tested on +Bash 5.1, but should work on most versions. + +Installation +************ + +On most operatin systems with Bash run: + + $ curl -o ~/.goto.sh \ + -sSL https://gitea.gch.icu/ge/goto/raw/branch/master/goto.sh + $ echo '[ -f ~/.goto.sh ] && . ~/.goto.sh' >> ~/.bashrc + +Reread ~/.bashrc by command: + + $ source ~/.bashrc + +Usage +***** + +Available commands (actually is aliases to functions): + + s [] bookmark $PWD or (save into ~/.gotosave). + g [] goto directory. If you have only one bookmark dir will be + changed without prompt. Type dir number in prompt to cd. + +Run `g` to show the entire list of bookmarks and select the one you need. + +You don't even need to press `Enter` to confirm your selection -- just type in +the bookmark number. The exception is when you have a two-digit number (or more) +and you select a bookmark whose number is less than 10. Then you have to press +`Enter`. + +You can pass the Perl regular expression (processed by grep -Pi) as an for 'g'. +At the same time, if only one bookmark is found, then the directory will be +changed directly to it. If there are several bookmarks, you will be prompted to +choose the appropriate one. Also you can use autocompletion by pressing `Tab`. +It works in a similar way. + +Examples +-------- + +Previously set up your commonly used dirs. Specify dir as argument: + + $ s ~/Documents + $ s ~/Downloads + +or cd into dir and simply run + + $ s + +Goto directory by number: + + $ g + 0 ~/Documents/ + 1 ~/Downloads/ + : + => cd /home/user/Downloads + +Goto '~/Downloads' directory by regex: + + $ g w + => cd /home/user/Downloads + +Another way :) + + $ g 'do[^c]' + => cd /home/gd/Downloads + +and etc. + +Tips +**** + +Combining commacd, goto and Bash autocd option gives a great experience! + +Add to you ~/.bashrc following: + shopt -s autocd +Now you can type just directory name without 'cd' to change directory. + +Get commacd here: https://github.com/shyiko/commacd + +Alternatives? +************* + +Some goto alternatives: + + - aliases (yep, Bash aliases) + - https://github.com/huyng/bashmarks diff --git a/goto.sh b/goto.sh new file mode 100644 index 0000000..9949901 --- /dev/null +++ b/goto.sh @@ -0,0 +1,142 @@ +# * goto (goto directory) - bookmark directorie in Bash. +# * versuion: 0.1 + +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# 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 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. +# +# For more information, please refer to + +_goto_cd() { + ##### cd into directory ##### + + if [ ! -d "$1" ]; then + echo "goto: no such directory $1" >&2 + return 1 + fi + + if cd -- "$1" > /dev/null; then + echo "$1" + else + echo -e "\bgoto: cannot cd into $1" >&2 + fi + return "$?" +} + +_goto_prompt() { + ##### Prompt and cd ##### + + # Exit if no dirs in ~/.gotosave + if [ "${#dirs[@]}" -eq 0 ] || [[ "${dirs[@]}" == '' ]]; then + echo goto: nothing to do; return 1 + fi + + # cd into dir without prompt if you have single directory + # in ~/.gotosave + if [ "${#dirs[@]}" -eq 1 ]; then + _goto_cd "${dirs[@]}" && return 0 + fi + + # Print directory list + for i in "${!dirs[@]}"; do + echo -e "$i\t${dirs[$i]%%+(/)}/" | sed "s%${HOME}%~%" + done + + # Count digits in number of dirs for 'read' + local dirscount="$((${#dirs[@]}-1))" + local numlen="${#dirscount}" + + # Read input to 'num' and set 'target' directory + read -r -n "$numlen" -p ': ' num + if [[ "$num" =~ [0-9]+ ]]; then + target="${dirs[$num]}"; + # Print new line to prevent line concatenation + [ "${#num}" -eq "$numlen" ] && echo + elif [[ "$num" == '' ]]; then + return 1 # Just exit if you press Enter. + else + # Print new line and exit if printable chars passed. + # E.g. new line will be printed if you type 'q'. + echo; return 1 + fi + + # cd into directory + _goto_cd "$target" +} + +_goto_search() { + grep -iP "$1" ~/.gotosave +} + +_goto() { + ##### Main function ##### + + # Get directory list ('dirs' array) + dirs=() + if [ -f ~/.gotosave ]; then + if [ "$1" ]; then + # Search dirs with Perl regex + _source="$(_goto_search "$1")" + else + # Load all directories + _source="$(<~/.gotosave)" + fi + while read -r dir; do + dirs+=("$dir") + done <<< "$_source" + fi + + _goto_prompt # prompt and cd +} + +_goto_save() { + ##### Save PWD or 1 to ~/.gotosave file ##### + + local dir + if [ "$1" ]; then + dir="$1" + else + dir="$PWD" + fi + + # Exit if directory is already in ~/.gotosave + if grep "^${dir%%+(/)}\$" ~/.gotosave > /dev/null; then + return 1 + fi + + # Save directory + if echo "${dir%%+(/)}" >> ~/.gotosave; then + echo "$dir" + fi +} + +_goto_complete() { + # Autocomplete directory by pattern + local pattern=${COMP_WORDS[COMP_CWORD]} + local IFS=$'\n' + COMPREPLY=($(compgen -W "$(printf "%s\n" "$(_goto_search "$pattern")")" -- '')) +} + +complete -F _goto_complete g + +alias g='_goto' +alias s='_goto_save'