SmartAudio/scripts/cdirs/cdirs.sh

1124 lines
36 KiB
Bash
Executable File

#!/bin/bash
# config file
gmpy_cdirs_config="$(gettop)/scripts/cdirs/cdirsrc.tina"
cdir_options_list="hn:l:p:k:t:f:F:"
lsdir_options_list="hp:"
cldir_options_list="gha"
setdir_options_list="hg"
cdir_options_list_full="reload,reset,num:,label:,path:,help,key:tag:,find:,Find:,default-key:,find-maxdepth:"
lsdir_options_list_full="path:,help"
cldir_options_list_full="all,reset,help,reload,global"
setdir_options_list_full="global,help"
init_options_list_full="replace-cd,help"
cdir() {
local flag word opts key f_dirname F_dirname find_maxdepth
opts="$(getopt -l "${cdir_options_list_full}" -o "${cdir_options_list}" -- $@)" || return 1
eval set -- "${opts}"
while true
do
case "$1" in
-h|--help)
gmpy_cdirs_print_help "cdir"
return 0
;;
-l|--label)
flag="label"
shift
word="$1"
shift
break
;;
-n|--num)
flag="num"
shift
word="$1"
shift
break
;;
-p|--path)
flag="path"
shift
word="$1"
shift
break
;;
--reload)
gmpy_cdirs_load_config
gmpy_cdirs_load_global_labels
return 0
;;
--reset)
gmpy_cdirs_reset
return 0
;;
-k|--key|-t|--tag)
shift
gmpy_cdirs_check_key "${1}" || {
echo "$1: No this key"
return 1
}
key="$1"
shift
;;
-f|--find)
shift
f_dirname="$1"
shift
;;
-F|--Find)
shift
F_dirname="$1"
shift
;;
--default-key)
shift
gmpy_cdirs_set_default_key "$1" || {
echo "$1: No This Key"
return 1
}
return 0
;;
--find-maxdepth)
shift
gmpy_cdirs_check_whether_num "$1" \
&& find_maxdepth="$1" \
|| {
echo "$1: Invaild Input - Not Num"
return 1
}
shift
;;
--)
shift
break
esac
done
[ -n "${find_maxdepth}" ] && {
[ "$#" -eq 0 -a -z "${f_dirname}" -a -z "${F_dirname}" ] && {
gmpy_cdirs_set_find_maxdepth "${find_maxdepth}"
return 0
}
}
# -f|--find|-F|--Find
if [ -n "${f_dirname}" ]; then
key=${key:-${gmpy_cdirs_default_key}}
[ -z "${key}" ] && return 0
gmpy_cdirs_cd_find_process "${f_dirname}" "${key}" "${find_maxdepth}"
return 0
elif [ -n "${F_dirname}" ]; then
gmpy_cdirs_cd_find_process "${F_dirname}" "${find_maxdepth}"
return 0
fi
if [ -n "${flag}" ]; then
gmpy_cdirs_replace_cd "$(_cdir "${word}" "${flag}")"
elif [ "$#" -gt "1" ]; then #for path with space
gmpy_cdirs_replace_cd "$*"
elif [ "$#" -eq "0" ]; then
gmpy_cdirs_replace_cd
elif [ "$#" -eq "1" ] && ([ "$1" = "," ] || [ "$1" = '0' ]); then
local path="$(gmpy_cdirs_get_path_from_num "0")"
[ -z "${path}" ] && return 0
gmpy_cdirs_replace_cd "${path}"
else
gmpy_cdirs_replace_cd "$(_cdir "$1")"
fi
}
setdir() {
local flag opts
flag="no_global"
opts="$(getopt -l "${setdir_options_list_full}" -o "${setdir_options_list}" -- $@)" || return 1
eval set -- "${opts}"
while true
do
case "$1" in
-h|--help)
gmpy_cdirs_print_help "setdir"
return 0
;;
-g|--global)
flag="global"
shift
;;
--)
shift
break
esac
done
if [ "$#" -lt "2" ]; then
if [ "$1" = ',' ]; then
gmpy_cdirs_set_mark
else
gmpy_cdirs_print_help "setdir"
fi
elif [ "$#" -eq "2" ]; then
_setdir $@ "${flag}"
elif [ "$#" -gt "2" ]; then
_setdir "$1" "$(shift;echo "$*")" "${flag}"
fi
}
lsdir() {
local opts word
local flag="not_only_path"
opts=`getopt -o "${lsdir_options_list}" -l "${lsdir_options_list_full}" -- $@` || return 1
eval set -- "${opts}"
while true
do
case "$1" in
-h|--help)
gmpy_cdirs_print_help "lsdir"
return 0
;;
-p|--path)
flag="only_path"
shift
word="$1"
shift
;;
--)
shift
break
;;
esac
done
[ -n "${word}" -a "${flag}" = "only_path" ] \
&& _lsdir "${flag}" "${word}" \
|| _lsdir "${flag}" $@
}
cldir() {
local opts all_flag
local global_flag="no_global"
opts="$(getopt -l "${cldir_options_list_full}" -o "${cldir_options_list}" -- $@)" || return 1
eval set -- "${opts}"
while true
do
case "$1" in
-h|--help)
gmpy_cdirs_print_help "cldir"
return 0
;;
--reset)
gmpy_cdirs_reset
return 0
;;
--reload)
gmpy_cdirs_load_global_labels
return 0
;;
-a|--all)
shift
all_flag="all"
;;
-g|--global)
shift
global_flag="global"
;;
--)
shift
break
;;
esac
done
if [ "${all_flag}" = "all" ]; then
local res="n"
while true
do
read -n 1 -p "Are you sure to clear all labels$([ "${global_flag}" = "global" ] \
&& echo " but also global labels")? [y/n] " res
echo
case "${res}" in
y|Y)
break
;;
n|N)
return 0
;;
*)
continue
;;
esac
done
gmpy_cdirs_clear_all "${global_flag}"
return 0
fi
if [ $# -lt 1 ]; then
gmpy_cdirs_print_help "cldir"
return 1
fi
_cldir "${global_flag}" $@
}
# _cdir <label|num|path> [num|label|path](point out the type)
_cdir() {
[ -f "$1" -a ! "$2" = "num" -a ! "$2" = "label" ] && {
echo "$1"
return 0
}
echo "$(gmpy_cdirs_get_path "$1" "$2")"
}
# _lsdir <only_path|not_only_path> [num1|label1|path1] [num2|label2|path2] ...
_lsdir() {
local path_flag="$1" && shift
[ "${path_flag}" = "not_only_path" ] && {
printf '\033[32m%s\t%-16s\t%s\033[0m\n' "num" "label" "path"
printf '\033[32m%s\t%-16s\t%s\033[0m\n' "---" "-----" "----"
}
if [ "$#" -gt 0 ]; then
for para in $@
do
if [ "${para}" = "," ]; then
if [ "${path_flag}" = "not_only_path" ]; then
gmpy_cdirs_list_mark
else
gmpy_cdirs_get_path "0" "num"
fi
else
if [ "${path_flag}" = "not_only_path" ]; then
gmpy_cdirs_ls_one_dir "${para}"
else
gmpy_cdirs_get_path "${para}"
fi
fi
done
else
gmpy_cdirs_ls_all_dirs
fi
}
# _setdir <label> <path> <global|no_global>
_setdir() {
local path="$(gmpy_cdirs_get_absolute_path "$2")"
local num
if [ -z "${path}" -o ! -d ${path} ]; then
echo -e "\033[31m${path} isn't existed or directory\033[0m"
return 2
fi
gmpy_cdirs_check_label "$1" || {
echo -en "\033[31mERROR: label fromat\n\033[0m"
echo -n "label starts with "
[ -n "${gmpy_cdirs_first_symbol}" ] \
&& echo -n "'${gmpy_cdirs_first_symbol}'" \
|| echo -n "letter"
echo -n " and combinates with letter, number and symbol "
echo "'${gmpy_cdirs_label_symbol}'"
return 1
}
if gmpy_cdirs_check_label_existed "$1"; then
echo -en "\033[31mmodify:\033[0m\t"
num="$(gmpy_cdirs_get_num_from_label "$1")"
gmpy_cdirs_clear_dir "$3" "$1" &>/dev/null
else
echo -en "\033[31mcreate:\033[0m\t"
num="$(gmpy_cdirs_get_num_cnt)"
gmpy_cdirs_add_num_cnt
fi
gmpy_cdirs_set_env "$3" "${num}" "$1" "${path}"
gmpy_cdirs_ls_format "${num}" "$1" "${path}"
}
# _cldir <no_global|global> <num1|label1|path1> <num2|label2|path2> ...
_cldir() {
local global_flag="$1"
shift
for para in $@
do
if [ "${para}" = "," ]; then
gmpy_cdirs_clear_mark
else
gmpy_cdirs_clear_dir "${global_flag}" "${para}"
fi
done
}
##########################################################################################
# #
# cdirs library #
# version: 2.000 #
# author: gmpy #
# date: 2017-1-10 #
# #
##########################################################################################
# /tmp/cdirs/cdirs.env.$$
# <num> <label> <path>
# 3 work /home/user/cdirs
#================ count num ================#
gmpy_cdirs_get_num_cnt() {
[ -z "${gmpy_cdirs_cnt}" ] && export gmpy_cdirs_cnt=1
echo "${gmpy_cdirs_cnt}"
}
gmpy_cdirs_add_num_cnt() {
export gmpy_cdirs_cnt="$(( ${gmpy_cdirs_cnt} + 1 ))"
}
#================ mark ================#
# gmpy_cdirs_set_mark
gmpy_cdirs_set_mark() {
[ -r "${gmpy_cdirs_env}" -a -w "${gmpy_cdirs_env}" ] || return 1
if grep "^0 " ${gmpy_cdirs_env} &>/dev/null; then
gmpy_cdirs_clear_dir "no_global" "0" &>/dev/null
echo -en "\033[31mmodify:\033[0m\t"
else
echo -en "\033[31mcreate:\033[0m\t"
fi
gmpy_cdirs_set_env "no_global" "0" "," "${PWD}"
gmpy_cdirs_list_mark
}
# gmpy_cdirs_list_mark
gmpy_cdirs_list_mark() {
gmpy_cdirs_ls_one_dir "0"
}
# gmpy_cdirs_clear_mark
gmpy_cdirs_clear_mark() {
gmpy_cdirs_check_label_existed "0" && {
gmpy_cdirs_clear_dir "no_global" "0"
}
}
#================ GET path\label\num\env ================#
# gmpy_cdirs_get_path_from_num <num>
gmpy_cdirs_get_path_from_num() {
[ -r "${gmpy_cdirs_env}" ] \
&& eval "awk '\$1~/^$1$/{print \$3}' ${gmpy_cdirs_env}"
}
# gmpy_cdirs_get_path_from_label <label>
gmpy_cdirs_get_path_from_label() {
[ -r "${gmpy_cdirs_env}" ] \
&& eval "awk '\$2~/^$1$/{print \$3}' ${gmpy_cdirs_env}"
}
# gmpy_cdirs_get_label_from_num <num>
gmpy_cdirs_get_label_from_num() {
[ -r "${gmpy_cdirs_env}" ] \
&& eval "awk '\$1~/^$1$/{print \$3}' ${gmpy_cdirs_env}"
}
# gmpy_cdirs_get_num_from_label <label>
gmpy_cdirs_get_num_from_label() {
[ -r "${gmpy_cdirs_env}" ] \
&& eval "awk '\$2~/^$1$/{print \$1}' ${gmpy_cdirs_env}"
}
# gmpy_cdirs_get_env_from_num <num>
gmpy_cdirs_get_env_from_num() {
[ -r "${gmpy_cdirs_env}" ] \
&& eval "awk '\$1~/^$1$/{print \$1 \" \" \$2 \" \" \$3}' ${gmpy_cdirs_env}"
}
# gmpy_cdirs_get_env_from_path <path>
# allow more than one envs
gmpy_cdirs_get_env_from_path() {
[ -r "${gmpy_cdirs_env}" ] \
&& egrep "$1/?$" ${gmpy_cdirs_env} | sort -k 1 -n | awk '{print $1 " " $2 " " $3}'
}
# gmpy_cdirs_get_env_from_label <label>
# enable echo more than one env if input regular expression
gmpy_cdirs_get_env_from_label() {
[ -r "${gmpy_cdirs_env}" ] \
&& eval "awk '\$2~/^$1$/{print \$1 \" \" \$2 \" \" \$3}' ${gmpy_cdirs_env}" \
| sort -k 1 -n
}
# gmpy_cdirs_get_all_num
gmpy_cdirs_get_all_num() {
[ -r "${gmpy_cdirs_env}" ] \
&& awk '{print $1}' ${gmpy_cdirs_env}
}
# gmpy_cdirs_get_all_label
gmpy_cdirs_get_all_label() {
[ -r "${gmpy_cdirs_env}" ] \
&& awk '($2!~/^,$/ && $1!~/^$/){print $2}' ${gmpy_cdirs_env}
}
# gmpy_cdirs_get_path <label|num|path> [num|label|path](point out the type)
gmpy_cdirs_get_path() {
local _type
[ -n "$2" ] && _type="$2" || _type="$(gmpy_cdirs_check_type "$1")"
case "${_type}" in
"num")
echo "$(gmpy_cdirs_get_path_from_num "$1")"
;;
"label")
gmpy_cdirs_check_label_existed "$1" \
&& echo "$(gmpy_cdirs_get_path_from_label "$1")" \
|| echo "$1"
;;
*)
echo "$1"
;;
esac
}
# gmpy_cdirs_get_absolute_path <path>
gmpy_cdirs_get_absolute_path() {
local pwd_path="${PWD}"
local para_path="$1"
# deal with word like - ~ . ..
if [ "${para_path}" = "-" ]; then
echo "${OLDPWD}"
return 0
elif [ "${para_path}" = "." ]; then
echo "${PWD}"
return 0
elif [ "${para_path}" = ".." ]; then
echo "${PWD%/*}"
return 0
elif [ "${para_path}" = "~" ]; then
echo "${HOME}"
return 0
elif [ "${para_path:0:1}" = "~" ]; then
para_path="${HOME}${para_path:1}"
fi
# delete last letter /
para_path=$(echo "${para_path}" | sed 's/\(.*\)\/$/\1/g')
# deal with word like ./ ../
while [ -n "$(echo "${para_path}" | egrep "\./|\.\./")" ]
do
if [ "${para_path%%/*}" = ".." ]; then
pwd_path="${pwd_path%/*}"
elif [ ! "${para_path%%/*}" = "." ]; then
pwd_path="${pwd_path}/${para_path%%/*}"
fi
para_path="${para_path#*/}"
done
if [ ! "${pwd_path}" = "${PWD}" ]; then
echo "${pwd_path}/${para_path}"
elif [ -d "${para_path}" ] && [ ! "${para_path:0:1}" = "/" ]; then
echo "${PWD}/${para_path}"
else
echo "${para_path}"
fi
}
#================ CHECK path\label\num ================#
# gmpy_cdirs_check_type <label|num|path>
# only check the string format but not whether exist the dir
# num: only number
# path: string wiht ./ or ../ or /, sometime it can be ~ or begin with ~
# label: others else
gmpy_cdirs_check_type() {
if [ "$#" -ne "1" ]; then
return 1
fi
if $(echo "$1" | egrep "^[0-9]+$" &>/dev/null); then
echo "num"
return 0
fi
if [ -n "$(echo "$1" | egrep "\./|\.\./|/")" ] \
|| [ "${1:0:1}" = "~" ] \
|| [ "$1" = "-" ] \
|| [ "$1" = "." ] \
|| [ "$1" = ".." ]; then
echo "path"
return 0
fi
gmpy_cdirs_check_label "$1" && echo "label" || echo "null"
}
# gmpy_cdirs_check_label <label>
gmpy_cdirs_check_label() {
[ -n "$(echo "$1" \
| egrep "^${gmpy_cdirs_first_symbol}[[:alpha:]]([[:alnum:]]*${gmpy_cdirs_label_symbol}*[[:alnum:]]*)*$")" ] \
&& return 0 || return 1
}
#gmpy_cdirs_check_label_existed <num|label>
gmpy_cdirs_check_label_existed() {
[ -r "${gmpy_cdirs_env}" ] || return 1
case "$(gmpy_cdirs_check_type "$1")" in
"label")
grep " $1 " ${gmpy_cdirs_env} &>/dev/null && return 0 || return 1
;;
"num")
grep "^$1 " ${gmpy_cdirs_env} &>/dev/null && return 0 || return 1
;;
*)
return 1
;;
esac
}
#================ LIST path\label\num ================#
# gmpy_cdirs_ls_all_dirs
gmpy_cdirs_ls_all_dirs() {
local oIFS line
[ -r "${gmpy_cdirs_env}" ] || return 1
oIFS="${IFS}"
IFS=$'\n'
for line in $(grep -v "^$" ${gmpy_cdirs_env} | sort -k 1 -n)
do
IFS="${oIFS}"
gmpy_cdirs_ls_format ${line}
IFS=$'\n'
done
IFS="${oIFS}"
}
# gmpy_cdirs_ls_one_dir <num|label|path>
gmpy_cdirs_ls_one_dir() {
case "`gmpy_cdirs_check_type "$1"`" in
num)
gmpy_cdirs_ls_format $(gmpy_cdirs_get_env_from_num "$1")
;;
path)
gmpy_cdirs_ls_format $(gmpy_cdirs_get_env_from_path "$1")
;;
*) #support regular expression
gmpy_cdirs_ls_format $(gmpy_cdirs_get_env_from_label "$1")
;;
esac
}
# gmpy_cdirs_ls_format <num> <label> <path>
gmpy_cdirs_ls_format() {
[ $# -ne 3 ] && return 1
echo "$@" \
| awk '{printf ("\033[32m%d)\t%-16s\t%s\033[0m\n",$1,$2,$3)}'
}
#================ CLEAR path\label\num ================#
# gmpy_cdirs_clear_global_label_from_label <label>
gmpy_cdirs_clear_global_label_from_label() {
[ $# -lt 1 ] && return 1
[ ! -f ${gmpy_cdirs_default} ] && return 2
sed -i "/^$1 *=/d" ${gmpy_cdirs_default} && return 0 || return 1
}
# gmpy_cdirs_clear_dir <global|no_global> <num|label|path>
gmpy_cdirs_clear_dir() {
local env num label
case "$(gmpy_cdirs_check_type "$2")" in
"num")
env="$(gmpy_cdirs_get_env_from_num "$2" | head -n 1)"
num="$2"
label="$(echo "${env}" | awk '{print $2}')"
;;
"label")
env="$(gmpy_cdirs_get_env_from_label "$2" | head -n 1)"
num="$(echo "${env}" | awk '{print $1}')"
label="${2}"
;;
"path")
env="$(gmpy_cdirs_get_env_from_path "$2" | head -n 1)"
num="$(echo "${env}" | awk '{print $1}')"
label="$(echo "${env}" | awk '{print $2}')"
;;
*)
return 1
;;
esac
[ -z "${env}" -o -z "${num}" -o -z "${label}" ] && return 1
echo -ne "\033[31mdelete:\t\033[0m"
[ "$1" = "global" ] && {
gmpy_cdirs_clear_global_label_from_label "${label}" \
&& echo -ne "\033[33m[global]\033[0m"
}
[ -r "${gmpy_cdirs_env}" -a -w "${gmpy_cdirs_env}" ] || return 1
eval "sed -i '/^${num} /d' ${gmpy_cdirs_env}"
gmpy_cdirs_ls_format ${env}
}
# gmpy_cdirs_clear_all [no_global|global]
gmpy_cdirs_clear_all() {
[ "$1" = "global" ] && echo > ${gmpy_cdirs_default}
[ -w "${gmpy_cdirs_env}" ] \
&& echo > ${gmpy_cdirs_env}
}
#================ SET path\label\num ================#
# gmpy_cdirs_set_global_dir <label> <path>
gmpy_cdirs_set_global_dir() {
echo "$1 = ${path}" >> ${gmpy_cdirs_default}
}
# gmpy_cdirs_set_env <global|no_global> <num> <label> <path>
gmpy_cdirs_set_env() {
[ "$1" = "global" ] \
&& gmpy_cdirs_set_global_dir "$3" "$4" && echo -ne "\033[33m[global]\033[0m"
[ -w "${gmpy_cdirs_env}" ] \
&& echo "$2 $3 $4" >> ${gmpy_cdirs_env}
}
# gmpy_cdirs_reset
# Turn back to initial status
gmpy_cdirs_reset() {
gmpy_cdirs_clear_all
gmpy_cdirs_cnt=1
gmpy_cdirs_load_config
gmpy_cdirs_load_global_labels
}
#================ global dirs ================#
# gmpy_cdirs_load_global_labels
# load default label by ~/.cdir_default
gmpy_cdirs_load_global_labels() {
eval "[ ! -f ${gmpy_cdirs_default} ] && return 2"
local line
local oIFS="${IFS}"
IFS=$'\n'
for line in $(eval "cat ${gmpy_cdirs_default}" | egrep -v "^#.*$|^$" | grep "=")
do
IFS="${oIFS}"
# Enable path with variable
_setdir $(echo ${line%%=*}) "$(eval echo ${line##*=})" "no_global"
IFS=$'\n'
done
IFS="${oIFS}"
}
#================ help ================#
# gmpy_cdirs_print_help <cdir|lsdir|setdir|cldir>
gmpy_cdirs_print_help() {
case "$1" in
cdir)
echo -e "\033[33mcdir [-h|--help] [--reload] [--reset] [num|label|path]\033[0m"
echo -e "\033[33mcdir [<-n|--num> <num>] [<-l|--label|> <label>] [<-p|--path> <path>]\033[0m"
echo -e "\033[33mcdir [-f|--find <dir> [-k|--key <key>]]\033[0m"
echo -e "\033[33mcdir <,>\033[0m"
echo "--------------"
echo -e "\033[32mcdir <num|label|path> :\033[0m"
echo -e " cd to path that pointed out by num|label|path\n"
echo -e "\033[32mcdir <,> :\033[0m"
echo -e " cd to special label-path, which is set by \"setdir ,\", see also \"setdir --help\"\n"
echo -e "\033[32mcdir [-h|--help] :\033[0m"
echo -e " show this introduction\n"
echo -e "\033[32mcdir [-n|--num] <parameter> :\033[0m"
echo -e " describe parameter as num mandatorily\n"
echo -e "\033[32mcdir [-l|--label] <parameter> :\033[0m"
echo -e " describe parameter as label mandatorily\n"
echo -e "\033[32mcdir [-p|--path] <parameter> :\033[0m"
echo -e " describe parameter as path mandatorily\n"
echo -e "\033[32mcdir [--reload] :\033[0m"
echo -e " reload ~/.cdir_default, which record the static label-path\n"
echo -e "\033[32mcdir [--reset] :\033[0m"
echo -e " clear all label-path and reload ~/.cdir_default, which record the static label-path\n"
echo -e "\033[32mcdir [-f|--find <dir> [-k|--key <key>]]\033[0m"
echo -e " search dir in key-path. use -k|--key to appoint key or use default key\n"
echo -e " you can set your key and key-path in ~/.cdirsrc with variable gmpy_cdirs_default_key and gmpy_cdirs_key\n"
echo -e " you can also set search max depth by variable gmpy_cdirs_search_max_depth\n"
echo -e "\033[31mNote: cdir is a superset of cd, so you can use it as cd too (In fact, my support for this scripts is to replace cd)\033[0m"
;;
setdir)
echo -e "\033[33msetdir [-h|--help] [-g|--global] <label> <path>\033[0m"
echo -e "\033[33msetdir <,>\033[0m"
echo "--------------"
echo -e "\033[32msetdir <label> <path> :\033[0m"
echo -e " set label to path, after that, you can use \"cdir label\" or \"cdir num\" to go to path (the num is setted by system and you can see by command \"lsdir\""
echo -e " moreover, path strings is support characters like . or .. or ~ or -"
echo -e " eg. \"setdir work .\" or \"setdir cdirs ~/cdirs\" or \"setdir last_dir -\" or others\n"
echo -e "\033[32msetdir <,> :\033[0m"
echo -e " set current path as a special label ',' , which is usefull and quick for recording working path , you can go back fastly by \"cdir ,\"\n"
echo -e "\033[32msetdir [-h|--help] :\033[0m"
echo -e " show this introduction\n"
echo -e "\033[32msetdir [-g|--global] <label> <path> :\033[0m"
echo -e " set label to path, moreover, record it in ~/.cdir_default. In this way, you can set this label-path automatically everytimes you run a terminal\n"
echo -en "\033[31mNote: label starts with "
[ -n "${gmpy_cdirs_first_symbol}" ] \
&& echo -n "'${gmpy_cdirs_first_symbol}'" \
|| echo -n "letter"
echo -n " and combinates with letter, number and symbol "
echo -e "'${gmpy_cdirs_label_symbol}'\033[0m"
;;
cldir)
echo -e "\033[33mcldir [-h|--help] [-g|--global] [-a|--all] [--reset] [--reload] <num1|label1|path1> <num2|label2|path2> ...\033[0m"
echo -e "\033[33mcldir <,>\033[0m"
echo "--------------"
echo -e "\033[32mcldir <num1|label1|path1> <num2|label2|path2> ... :\033[0m"
echo -e " clear the label-path. if path, clear all label-path matching this path\n"
echo -e "\033[32mcldir <,>:\033[0m"
echo -e " clear the special label-path. see also \"setdir --help\"\n"
echo -e "\033[32mcldir [-h|--help] :\033[0m"
echo -e " show this introduction\n"
echo -e "\033[32mcldir [-g|--global] <num|label|path> :\033[0m"
echo -e " unset label to path, moreover, delete it in ~/.cdir_default. see also \"setdir -h|--hlep\"\n"
echo -e "\033[32mcldir [-a|--all] :\033[0m"
echo -e " clear all label-path\n"
echo -e "\033[32mcldir [--reset] :\033[0m"
echo -e " clear all label-path and reload ~/.cdir_default, which record the static label-path\n"
echo -e "\033[32mcldir [--reload] :\033[0m"
echo -e " reload ~/.cdir_default, which record the static label-path"
;;
lsdir)
echo -e "\033[33mlsdir [-h|--help] [-p|--path <num|label|path>] <num1|label1|path1> <num2|label2|path2> ...\033[0m"
echo -e "\033[33mlsdir <,>\033[0m"
echo "--------------"
echo -e "\033[32mlsdir <num1|label1|path1> <num2|label2|path2> ... :\033[0m"
echo -e " list the label-path. if path, list all label-path matching this path\n"
echo -e "\033[32mlsdir <,> :\033[0m"
echo -e " list the special label-path. see also \"setdir --help\"\n"
echo -e "\033[32mlsdir [-h|--help] :\033[0m"
echo -e " show this introduction\n"
echo -e "\033[32mlsdir [-p|--path <num|label|path>] :\033[0m"
echo -e " only print path of label-path, which is usefull to embedded in other commands"
echo -e " eg. cat \`lsdir -p cdirs\`/readme.txt => cat /home/user/cdirs/readme.txt"
;;
esac
}
#================ basical ================#
#gmpy_cdirs_load_config
gmpy_cdirs_load_config() {
eval "[ -f "${gmpy_cdirs_config}" ] && source ${gmpy_cdirs_config}"
}
# gmpy_cdirs_replace_cd <path>
gmpy_cdirs_replace_cd() {
if [ -n "$*" ]; then
builtin cd "$*"
else
builtin cd
fi
}
gmpy_cdirs_init() {
local opts="$(getopt -l "${init_options_list_full}" -o "h" -- $@)" || return 1
eval set -- "${opts}"
while true
do
case "$1" in
-h|--help)
shift
;;
--replace-cd)
alias cd="cdir"
shift
;;
--)
shift
break
;;
*)
shift
;;
esac
done
gmpy_cdirs_load_config
gmpy_cdirs_env="/tmp/cdirs/cdirs.env.$$" \
&& mkdir -p /tmp/cdirs -m 777\
&& touch ${gmpy_cdirs_env}
[ -z "${gmpy_cdirs_default}" ] \
&& gmpy_cdirs_default="${HOME}/.cdirs_default"
gmpy_cdirs_load_global_labels &>/dev/null
complete -F gmpy_cdirs_complete_func -o dirnames "setdir" "lsdir" "cldir"
complete -F gmpy_cdirs_complete_func -o dirnames -A directory "cdir" \
"$([ "$(type -t cd)" = "alias" ] && echo "cd")"
}
#================ completation ================#
# gmpy_cdirs_complete_func <input>
gmpy_cdirs_complete_func() {
local cmd="$1"
local cur="${COMP_WORDS[COMP_CWORD]}"
local pre="${COMP_WORDS[COMP_CWORD-1]}"
local line="${COMP_LINE}"
local complete_list
case "${cmd}" in
cldir|lsdir)
if [ "${cur:0:2}" = "--" ]; then
complete_list="--$(eval "echo \"\${${cmd}_options_list_full}\" | sed 's/,/ --/g' | sed 's/://g'")"
elif [ "${cur:0:1}" = "-" ]; then
complete_list="$(eval "echo \"\${${cmd}_options_list}\" | sed 's/://g' | sed 's/[[:alpha:]]/-& /g'")"
else
complete_list="$(gmpy_cdirs_get_all_label)"
fi
;;
setdir)
if [ "${cur:0:2}" = "--" ]; then
complete_list="--$(echo "${setdir_options_list_full}" | sed 's/,/ --/g' | sed 's/://g')"
elif [ "${cur:0:1}" = "-" ]; then
complete_list="$(echo "${setdir_options_list}" | sed 's/://g' | sed 's/[[:alpha:]]/-& /g')"
else
local opts_cnt="$(( $(echo ${line} | wc -w) - $(echo "${line}" | sed -r 's/ -[[:alpha:]]+ / /g' | wc -w) ))"
[ $(( ${COMP_CWORD} - ${opts_cnt} )) -eq 1 ] && complete_list="$(gmpy_cdirs_get_all_label)"
fi
;;
cd|cdir)
case "${pre}" in
"-l"|"--label")
complete_list="$(gmpy_cdirs_get_all_label)"
;;
"-n"|"--num")
complete_list="$(gmpy_cdirs_get_all_num)"
;;
"-p"|"--path")
complete_list=
;;
"-k"|"--key"|"-t"|"--tag"|"--default-key")
complete_list="$(gmpy_cdirs_get_all_key)"
;;
"--find-maxdepth")
complete_list=
;;
"-f"|"--find")
local key opt cnt find_maxdepth
# get key
cnt=0
for opt in ${COMP_WORDS[@]}
do
cnt=$(( ${cnt} + 1 ))
[ "${opt}" = "-k" \
-o "${opt}" = "-t" \
-o "${opt}" = "--key" \
-o "${opt}" = "--tag" ] && break
done
key="${COMP_WORDS[cnt]:-${gmpy_cdirs_default_key}}"
# get find_maxdepth
cnt=0
for opt in ${COMP_WORDS[@]}
do
cnt=$(( ${cnt} + 1 ))
[ "${opt}" = "--find-maxdepth" ] && break
done
find_maxdepth="${COMP_WORDS[cnt]}"
[ -n "${key}" ] && {
[ "${key}" = "${gmpy_cdirs_complete_key}" \
-a -n "${gmpy_cdirs_complete_dirs}" ] \
&& complete_list="${gmpy_cdirs_complete_dirs}" \
|| {
complete_list="$(gmpy_cdirs_get_all_dirs_from_key "${key}" "${find_maxdepth}")"
gmpy_cdirs_complete_dirs="${complete_list}"
gmpy_cdirs_complete_key="${key}"
}
}
;;
"-F"|"--Find")
local opt cnt find_maxdepth
# get find_maxdepth
cnt=0
for opt in ${COMP_WORDS[@]}
do
cnt=$(( ${cnt} + 1 ))
[ "${opt}" = "--find-maxdepth" ] && break
done
find_maxdepth="${COMP_WORDS[cnt]}"
[ -n "${gmpy_cdirs_complete_dirs}" -a -z "${gmpy_cdirs_complete_key}" ] \
&& complete_list="${gmpy_cdirs_complete_dirs}" \
|| {
complete_list="$(gmpy_cdirs_get_all_dirs_from_pwd "${find_maxdepth}")"
gmpy_cdirs_complete_dirs="${complete_list}"
unset gmpy_cdirs_complete_key
}
;;
*)
if [ "${cur:0:2}" = "--" ]; then
complete_list="--$(echo "${cdir_options_list_full}" | sed 's/,/ --/g' | sed 's/://g')"
elif [ "${cur:0:1}" = "-" ]; then
complete_list="$(echo "${cdir_options_list}" | sed 's/://g' | sed 's/[[:alpha:]]/-& /g')"
elif [ -n "${gmpy_cdirs_first_symbol}" -a "${cur:0:1}" = "${gmpy_cdirs_first_symbol}" ]; then
complete_list="$(gmpy_cdirs_get_all_label)"
elif [ -z "${gmpy_cdirs_first_symbol}" ]; then
complete_list="$(gmpy_cdirs_get_all_label)"
fi
;;
esac
;;
esac
COMPREPLY=($(compgen -W "${complete_list}" -- "${cur}"))
}
#================ key path ================#
#gmpy_cdirs_set_find_maxdepth <num>
gmpy_cdirs_set_find_maxdepth() {
gmpy_cdirs_check_whether_num "$1" \
&& gmpy_cdirs_search_max_depth="$1" || return 1
}
#gmpy_cdirs_set_default_key <key>
gmpy_cdirs_set_default_key() {
gmpy_cdirs_check_key "$1" \
&& gmpy_cdirs_default_key="$1" \
|| return 1
}
#gmpy_cdirs_get_all_key
gmpy_cdirs_get_all_key() {
[ -n "${gmpy_cdirs_key}" ] \
&& echo "${gmpy_cdirs_key[@]}" \
| sed 's/\;/\n/g' \
| awk '{print $1}'
}
#gmpy_cdirs_get_path_from_key() <key>
gmpy_cdirs_get_path_from_key() {
[ -n "${gmpy_cdirs_key}" ] \
&& echo "${gmpy_cdirs_key[@]}" \
| sed 's/\;/\n/g' \
| eval "awk '\$1~/^$1\$/{print \$3}'"
}
#gmpy_cdirs_find_dir_from_key <key> <dir> [find_maxdepth]
gmpy_cdirs_find_dir_from_key() {
local cmd kpath find_maxdepth
kpath="$(gmpy_cdirs_get_path_from_key "$1")"
[ -z "${kpath}" ] && return 0
find_maxdepth="${3:-${gmpy_cdirs_search_max_depth}}"
gmpy_cdirs_check_whether_num "${find_maxdepth}" || unset find_maxdepth
cmd="$([ -n "${find_maxdepth}" ] \
&& echo "-maxdepth ${find_maxdepth}")"
cmd="find ${kpath} ${cmd} -name \"${2}\" -type d 2>/dev/null"
echo $(eval "${cmd}")
}
#gmpy_cdirs_get_all_dirs_from_key <key> [find_maxdepth]
gmpy_cdirs_get_all_dirs_from_key() {
local cmd kpath find_maxdepth
kpath="$(gmpy_cdirs_get_path_from_key $1)"
[ -z "${kpath}" ] && return 0
find_maxdepth="${2:-${gmpy_cdirs_search_max_depth}}"
gmpy_cdirs_check_whether_num "${find_maxdepth}" || unset find_maxdepth
cmd="$([ -n "${find_maxdepth}" ] \
&& echo "-maxdepth ${find_maxdepth}")"
cmd="find ${kpath} ${cmd} -type d 2>/dev/null | xargs -I {} basename {}"
echo $(eval "${cmd}")
}
#gmpy_cdirs_check_key <key>
gmpy_cdirs_check_key() {
[ -n "${gmpy_cdirs_key}" ] \
&& echo "${gmpy_cdirs_key[@]}" \
| sed 's/\;/\n/g' \
| awk '{print $1}' \
| grep -w "${1}" &>/dev/null
}
#gmpy_cdirs_cd_find_process <dirname> <key> <find_maxdepth>
#gmpy_cdirs_cd_find_process <dirname> <find_maxdepth>
gmpy_cdirs_cd_find_process() {
local f_result dirname
if [ "$#" -gt "2" ]; then
f_result=($(gmpy_cdirs_find_dir_from_key "$2" "$1" "$3"))
else
f_result=($(gmpy_cdirs_find_dir_from_pwd "$1" "$2"))
fi
local f_cnt=${#f_result[@]}
if [ "${f_cnt}" -gt "1" ]; then
local cnt=0
local result
echo "Which one do you want:"
for result in ${f_result[@]}
do
echo "${cnt}: ${result}"
cnt="$(( ${cnt} + 1 ))"
done
while true
do
read -p "Your choice: " cnt
gmpy_cdirs_check_whether_num "${cnt}" || {
echo -e "\033[31m${cnt}: Invaild Input - Not Num\033[0m"
continue
}
[ "${cnt}" -ge "${f_cnt}" ] && {
echo -e "\033[31m${cnt}: Invaild Input - Error Num\033[0m"
continue
}
echo -e "\033[32m${f_result[cnt]}\033[0m"
gmpy_cdirs_replace_cd "${f_result[cnt]}"
break
done
elif [ "${f_cnt}" -eq "1" ]; then
echo -e "\033[32m${f_result}\033[0m"
gmpy_cdirs_replace_cd "${f_result}"
else
echo -e "\033[31mCan't find $1\033[0m"
fi
unset gmpy_cdirs_complete_dirs
unset gmpy_cdirs_complete_key
}
#gmpy_cdirs_find_dir_from_pwd <dir> [find_maxdepth]
gmpy_cdirs_find_dir_from_pwd() {
local cmd find_maxdepth
find_maxdepth="${2:-${gmpy_cdirs_search_max_depth}}"
gmpy_cdirs_check_whether_num "${find_maxdepth}" || unset find_maxdepth
cmd="$([ -n "${find_maxdepth}" ] \
&& echo "-maxdepth ${find_maxdepth}")"
cmd="find ${PWD} ${cmd} -name \"${1}\" -type d 2>/dev/null"
echo $(eval "${cmd}")
}
#gmpy_cdirs_get_all_dirs_from_pwd [find_maxdepth]
gmpy_cdirs_get_all_dirs_from_pwd() {
local cmd find_maxdepth
find_maxdepth="${1:-${gmpy_cdirs_search_max_depth}}"
gmpy_cdirs_check_whether_num "${find_maxdepth}" || unset find_maxdepth
cmd="$([ -n "${find_maxdepth}" ] \
&& echo "-maxdepth ${find_maxdepth}")"
cmd="find ${PWD} ${cmd} -type d 2>/dev/null | xargs -I {} basename {}"
echo $(eval "${cmd}")
}
#gmpy_cdirs_check_whether_num <num>
gmpy_cdirs_check_whether_num() {
echo "$1" | egrep "^[[:digit:]]+$" &>/dev/null
}
gmpy_cdirs_init $@