Last active
April 11, 2021 04:30
-
-
Save babarot/1a0218c9e71b9f2e1835 to your computer and use it in GitHub Desktop.
description
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# @(#) bookmarker.sh ver.1.4.0 2013.08.12 | |
# | |
# Copyright (c) 2013, b4b4r07 | |
# All rights reserved. | |
# | |
# Redistribution and use in source and binary forms, with or without modification, are permitted provided | |
# that the following conditions are met: | |
# | |
# * Redistributions of source code must retain the above copyright notice, this list of conditions | |
# and the following disclaimer. | |
# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the | |
# following disclaimer in the documentation and/or other materials provided with the distribution. | |
# * Neither the name of Huy Nguyen nor the names of contributors | |
# may be used to endorse or promote products derived from this software without | |
# specific prior written permission. | |
# | |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED | |
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | |
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
# POSSIBILITY OF SUCH DAMAGE. | |
# | |
# USAGE: | |
# . bookmarker.sh | |
# | |
################################################################################################################### | |
[ "$BASH_VERSION" ] || return 1 | |
declare -r version="1.4.0" | |
declare -r author="b4b4r07" | |
declare -r bookmarkdir=~/.bookmarkdir | |
declare -r bookmarklist=$bookmarkdir/bookmarklist | |
declare -r bookmarklog=$bookmarkdir/bookmarklog | |
declare -r bookmarktemp=$bookmarkdir/bookmarktemp | |
declare -ri exit_usage=0 | |
declare OPTION_T= | |
function _bookmark_usage() { | |
local -i width=$( stty 'size' <'/dev/tty' | cut -d' ' -f2 ) | |
local -a commands=( "edit" "show" "regist" "go" "print" "delete" ) | |
if [ $# -eq 0 ]; then | |
echo -en "${commands[@]}\n\n" | |
_bookmark_usage "${commands[@]}" | |
return 0 | |
fi | |
for list do | |
echo -en "Usage: " | |
case "$list" in | |
'edit') | |
echo -en "edit [OPTION]\n" | |
echo -en " Edit bookmark-list.\n\n" | |
echo -en "Options:\n" | |
echo -en " -r, --readonly display bookmark-log readonly.\n" | |
echo -en " -h, --help display this help and exit.\n\n" | |
shift | |
;; | |
'show') | |
echo -en "show [OPTION]\n" | |
echo -en " Display all registration names and paths.\n" | |
echo -en " All options cannot be used together.\n\n" | |
echo -en "Options:\n" | |
echo -en " -h, --help display this help and exit.\n" | |
echo -en " -c, --count count the use number of times of the registed name.\n" | |
echo -en " -r, --refresh check if all registed paths are available.\n" | |
echo -en " -s, --sort sort registed names with a turn showing frequent use and display it.\n" | |
echo -en " -m, --mru display the list which you used ten from a bookmark-list recently.\n" | |
echo -en " -p, --plane display the list without a color.\n\n" | |
shift | |
;; | |
'regist') | |
echo -en "reg [OPTION] [name]\n" | |
echo -en " If there is an argument, register by the argument name\n" | |
echo -en " and otherwise register it current directory name.\n\n" | |
echo -en "Options:\n" | |
echo -en " -t, --temp generate the name and path as disposable element.\n" | |
echo -en " -h, --help display this help and exit.\n\n" | |
shift | |
;; | |
'go') | |
echo -en "go [name]\n" | |
echo -en " If there is an argument, go to the name of path\n" | |
echo -en " and otherwise do movement like 'show'.\n\n" | |
echo -en "Options:\n" | |
echo -en " -h, --help display this help and exit.\n\n" | |
shift | |
;; | |
'print') | |
echo -en "p name\n" | |
echo -en " print the name of path.\n\n" | |
echo -en "Options:\n" | |
echo -en " -h, --help display this help and exit.\n\n" | |
echo -en "Examples:\n" | |
echo -en " cp myfile \`p reg_dir\`\n\n" | |
shift | |
;; | |
'delete') | |
echo -en "del name\n" | |
echo -en " delete the name and path.\n\n" | |
echo -en "Options:\n" | |
echo -en " -h, --help display this help and exit.\n\n" | |
shift | |
;; | |
'refresh') | |
echo -en "show -r\n" | |
echo -en "Please refer to page 'show'.\n" | |
shift | |
;; | |
'count') | |
echo -en "show -c\n" | |
echo -en "Please refer to page 'show'.\n" | |
shift | |
;; | |
'sort') | |
echo -en "show -s\n" | |
echo -en "Please refer to page 'show'.\n" | |
shift | |
;; | |
'mru') | |
echo -en "show -m\n" | |
echo -en "Please refer to page 'show'.\n" | |
shift | |
;; | |
esac | |
[ "$#" -ne 0 ] && for ((i=0; i<$width; i++)); do | |
echo -en "_" | |
done && echo -en "\n\n" | |
done | |
echo -en "\nReport bugs to <[email protected]>.\n" | |
return $exit_usage | |
} | |
function _bookmark_initialize() { | |
[ -d $bookmarkdir ] && return 1 | |
local ans | |
mkdir -p $bookmarkdir | |
touch $bookmarklist $bookmarklog $bookmarktemp | |
echo -en "Do you display a help? [y/N]: " | |
read ans | |
if [ "$ans" = "y" ] || [ "$ans" = "Y" ]; then | |
_bookmark_usage | ${PAGER:-less} | |
return $exit_usage | |
fi | |
cp $0 $bookmarkdir | |
return 0 | |
} | |
function _bookmark_edit() { | |
[ ! -e $bookmarklist ] && { echo "$(basename $bookmarklist): No exist"; return 1; } | |
[ "$1" = "-h" ] || [ "$1" = "--help" ] && { _bookmark_usage ${FUNCNAME##*_}; return $exit_usage; } | |
[ "$1" = "-r" ] || [ "$1" = "--readonly" ] && { tail -10r $bookmarklog; return 0; } | |
if which vi vim >/dev/null; then | |
vim $bookmarklist | |
return 0 | |
else | |
$EDITOR $bookmarklist || { | |
echo "cannot edit bookmark-list" 1>&2 | |
return 1 | |
} | |
return 0 | |
fi | |
} | |
function _bookmark_show() { | |
[ ! -e $bookmarklist ] && { echo "$(basename $bookmarklist): No exist"; return 1; } | |
local OPT | |
for OPT in "$@" | |
do | |
case "$OPT" in | |
'-h'|'--help' ) | |
_bookmark_usage ${FUNCNAME##*_} | |
return $exit_usage | |
;; | |
'-c'|'--count' ) | |
_bookmark_count | |
shift 1 | |
return 0 | |
;; | |
'-r'|'--refresh' ) | |
if _bookmark_refresh; then | |
return 0 | |
else | |
return 1 | |
fi | |
;; | |
'-s'|'--sort' ) | |
_bookmark_sort | |
shift 1 | |
return 0 | |
;; | |
'-m'|'--mru' ) | |
_bookmark_mru | |
shift 1 | |
return 0 | |
;; | |
'-p'|'--plane' ) | |
cat $bookmarklist | sed "s $HOME ~ g" | |
shift 1 | |
return 0 | |
;; | |
'--'|'-' ) | |
shift 1 | |
param+=( "$@" ) | |
break | |
;; | |
-*) | |
echo "${FUNCNAME##*_}: illegal option -- '$(echo $1 | sed 's/^-*//')'" 1>&2 | |
return 1 | |
;; | |
*) | |
if [[ ! -z "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then | |
param+=( "$1" ) | |
shift 1 | |
fi | |
;; | |
esac | |
done | |
[ ! -f $bookmarklist ] && touch $bookmarklist | |
[ ! -f $bookmarklog ] && touch $bookmarklog | |
[ ! -f $bookmarktemp ] && touch $bookmarktemp | |
local -i i= | |
local -a name=( $( awk '{print $1}' $bookmarklist ) ) | |
local -a path=( $( awk '{print $2}' $bookmarklist ) ) | |
for ((i=0; i<${#name[*]}; i++)); do | |
if grep -w ${name[i]} $bookmarklog >/dev/null; then | |
printf "\033[31m%-15s\033[m%s\n" ${name[i]} ${path[i]} | |
elif grep -w ${name[i]} $bookmarktemp >/dev/null; then | |
printf "\033[01;36m%-15s\033[m%s\n" ${name[i]} ${path[i]} | |
else | |
printf "\033[33m%-15s\033[m%s\n" ${name[i]} ${path[i]} | |
fi | |
done | sed "s $HOME ~ g" | |
unset name path i OPT | |
} | |
function _bookmark_regist() { | |
[ ! -e $bookmarklist ] && touch $bookmarklist | |
local OPT | |
for OPT in "$@" | |
do | |
case "$OPT" in | |
'-h'|'--help' ) | |
_bookmark_usage ${FUNCNAME##*_} | |
return $exit_usage | |
;; | |
'-t'|'--temp' ) | |
shift 1 | |
local -i OPTION_T=1 | |
;; | |
'--'|'-' ) | |
shift 1 | |
param+=( "$@" ) | |
break | |
;; | |
-*) | |
echo "${FUNCNAME##*_}: illegal option -- '$(echo $1 | sed 's/^-*//')'" 1>&2 | |
return 1 | |
;; | |
esac | |
done | |
local -i limit=$(( $( stty 'size' <'/dev/tty' | cut -d' ' -f1 ) - 2 )) | |
[ $( wc -l <$bookmarklist ) -ge $limit ] && { | |
echo "The maximum number that can enroll in a bookmark-list is $limit cases." | |
return 1 | |
} | |
local -i i= | |
local name= | |
[ $# -eq 0 ] && name=${PWD##*/} || name="$1" | |
[ ${#name} -gt 14 ] && { echo "Please input 14 characters or less."; return 1; } | |
if awk '{print $1}' $bookmarklist | command grep -w "$name" >/dev/null; then | |
echo "$name: already exist" | |
return 1 | |
else | |
[ "$OPTION_T" ] && printf "%-15s%s\n" $name $(pwd) >>$bookmarktemp | |
printf "%-15s%s\n" $name $(pwd) >>$bookmarklist | |
return 0 | |
fi | |
unset limit i name OPT | |
} | |
function _bookmark_go() { | |
[ "$1" = "-h" ] || [ "$1" = "--help" ] && { _bookmark_usage ${FUNCNAME##*_}; return $exit_usage; } | |
local name=$( awk '{print $1}' $bookmarklist | command grep -w -E "^$1$" ) | |
local path=$( awk '$1 ~ /'^$1'$/' $bookmarklist | awk '{print $2}' ) | |
if [[ $# -eq 0 ]]; then | |
echo "${FUNCNAME##*_}: too few arguments" | |
echo "Try '${FUNCNAME##*_} --help' for more information." | |
return 1 | |
elif [[ $# -eq 1 ]]; then | |
if [[ -z "$name" ]]; then | |
echo "$1: No such path in $(basename $bookmarklist)" | |
return 1 | |
else | |
if cd "$path" 2>/dev/null; then | |
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >>$bookmarklog | |
if [ -f $bookmarktemp ]; then | |
if awk '{print $2}' $bookmarktemp | grep -x $path >/dev/null; then | |
_bookmark_delete $name | |
sed -i '' "/^$1/d" $bookmarktemp | |
fi | |
fi | |
return 0 | |
else | |
echo "$path: an invalid pass" | |
_bookmark_delete "$name" | |
echo "$name: deleted" | |
return 1 | |
fi | |
fi | |
else | |
_bookmark_usage ${FUNCNAME##*_} | |
return $exit_usage | |
fi | |
unset name path | |
} | |
function _bookmark_print() { | |
[ "$1" = "-h" ] || [ "$1" = "--help" ] && { _bookmark_usage ${FUNCNAME##*_}; return $exit_usage; } | |
local name=$( awk '{print $1}' $bookmarklist | command grep -w -E "^$1$" ) | |
local path=$( awk '$1 ~ /'^$1'$/' $bookmarklist | awk '{print $2}' ) | |
if [[ $# -eq 1 ]]; then | |
if [[ -z "$name" ]]; then | |
echo "$1: No such path in $(basename $bookmarklist)" | |
return 1 | |
else | |
if (cd "$path" >/dev/null 2>&1); then | |
echo "$path" | |
return 0 | |
else | |
echo "$path: an invalid pass" | |
_bookmark_delete "$name" | |
echo "$name: deleted" | |
return 1 | |
fi | |
fi | |
else | |
echo "${FUNCNAME##*_}: too few arguments" | |
echo "Try '${FUNCNAME##*_} --help' for more information." | |
return 1 | |
fi | |
unset name path | |
} | |
function _bookmark_delete() { | |
[ ! -e $bookmarklist ] && { echo "$(basename $bookmarklist): No exist"; return 1; } | |
[ "$1" = "-h" ] || [ "$1" = "--help" ] && { _bookmark_usage ${FUNCNAME##*_}; return $exit_usage; } | |
[ ! -s $bookmarklist ] && { echo "$(basename $bookmarklist) is empty."; return 1; } | |
[ $# -eq 0 ] && { | |
echo "${FUNCNAME##*_}: too few arguments" | |
echo "Try '${FUNCNAME##*_} --help' for more information." | |
return 1 | |
} | |
local -i i= | |
for f do | |
local -a name=( $( awk '{print $1}' $bookmarklist | command grep -ivw -E "$f" ) ) | |
local -a path=( $( command grep -ivw -E "^$f" $bookmarklist | awk '{print $2}' ) ) | |
if awk '{print $1}' $bookmarklist | command grep -w -E "^$f" >/dev/null; then | |
for ((i=0; i<${#name[*]}; i++)); do | |
printf "%-15s%s\n" ${name[i]} ${path[i]} | |
done >$bookmarklist | |
sed -i '' "/$f$/d" $bookmarklog 2>/dev/null | |
if [ -f $bookmarktemp ]; then | |
if awk '{print $1}' $bookmarktemp | grep -w "$f" >/dev/null; then | |
sed -i '' "/^$f/d" $bookmarktemp | |
fi | |
fi | |
else | |
echo "$1: No such path in $(basename $bookmarklist)" | |
return 1 | |
fi | |
unset i name path f | |
done | |
} | |
function _bookmark_refresh() { | |
local -i i= | |
local -i count=0 | |
local -a name=( $( awk '{print $1}' $bookmarklist ) ) | |
local -a path=( $( awk '{print $2}' $bookmarklist ) ) | |
local -r line=$( wc -l <$bookmarklist ) | |
for ((i=0; i<"$line"; i++)); do | |
if [ -d "${path[i]}" ]; then | |
let count++ | |
else | |
_bookmark_delete "${name[i]}" | |
fi | |
done | |
if [ $count -eq $line ]; then | |
echo "All paths are available." | |
return 1 | |
else | |
_bookmark_show | |
return 0 | |
fi | |
unset i count name path line | |
} | |
function _bookmark_count() { | |
[ "$1" = "-h" ] || [ "$1" = "--help" ] && { _bookmark_usage ${FUNCNAME##*_}; return $exit_usage; } | |
local OLDIFS=$IFS | |
IFS=$'\n' | |
local -i i= | |
local -a ary= | |
local -a reg=( $( awk '{print $1}' $bookmarklist ) ) | |
for ((i=0; i<${#reg[*]}; i++)); do | |
ary[i]=$( sort -k3 $bookmarklog -k1,2r | uniq -c -f2 | sort | grep -w "${reg[i]}" | awk '{print $1,$4}' ) | |
[ -z "${ary[i]}" ] && ary[i]="0 ${reg[i]}" | |
done | |
local -a num=( $( echo "${ary[*]}" | awk '{print $1}' ) ) | |
local -a name=( $( echo "${ary[*]}" | awk '{print $2}' ) ) | |
local -a path=( $( awk '{print $2}' $bookmarklist ) ) | |
for ((i=0; i<${#num[*]}; i++)); do | |
printf "%3d: \033[31m%-15s\033[m%s\n" ${num[i]} ${name[i]} ${path[i]} | |
done | sed "s $HOME ~ g" | |
IFS=$OLDIFS | |
unset OLDIFS i ary reg num name path | |
} | |
function _bookmark_sort() { | |
[ "$1" = "-h" ] || [ "$1" = "--help" ] && { _bookmark_usage ${FUNCNAME##*_}; return $exit_usage; } | |
local -i i= | |
local -a name=( $( _bookmark_count | sort -k1nr | awk '{print $2}' ) ) | |
local -a path=( $( _bookmark_count | sort -k1nr | awk '{print $3}' ) ) | |
for ((i=0; i<${#name[*]}; i++)); do | |
printf "\033[31m%-20s\033[m%s\n" ${name[i]} ${path[i]} | |
done | sed "s $HOME ~ g" | |
unset i name path | |
} | |
function _bookmark_mru() { | |
local -a reg=( $( awk '{print $1}' $bookmarklist ) ) | |
local -a list=( $( tail -30 -r $bookmarklog ) ) | |
local -a temp=(),mru,num,path | |
local OLDIFS=$IFS | |
IFS=$'\n' | |
local -i i= | |
local -a uniq_num=( $( sort -k3 $bookmarklog -k1,2r | uniq -c -f2 | sort ) ) | |
for ((i=0; i<${#list[*]}; i++)); do | |
if ! echo "${temp[@]}" | grep -w ${list[i]} >/dev/null; then | |
temp[i]=${list[i]} | |
mru+=( $( echo "${reg[*]}" | grep -w ${list[i]} ) ) | |
fi | |
done | |
local -a num= | |
local -a date= | |
local -a path= | |
local -a target=( $( echo "${uniq_num[*]}" | grep "${reg[*]}" ) ) | |
for ((i=0; i<${#mru[*]}; i++)); do | |
num+=( $( echo "${target[*]}" | grep -w ${mru[i]} | awk '{print $1}' ) ) | |
date+=( $( echo "${target[*]}" | grep -w ${mru[i]} | awk '{print $2,$3}' ) ) | |
path+=( $( grep -E -w "^${mru[i]}" $bookmarklist ) ) | |
done | |
local -a t= | |
local -i length=$( | |
for ((i=0; i<${#path[*]}; i++)); do | |
t[i]=$( echo ${path[i]} | sed "s $HOME ~ g" ) | |
echo ${#t[i]} | |
done | sort -nr | head -1 | |
) | |
for ((i=0; i<${#num[*]}; i++)); do | |
printf "%3d: \033[31m%-15s\033[m%-$(( ${length} -3 ))s (%s)\n" \ | |
${num[i]} $( echo ${path[i]} | awk '{print $1}' ) $( echo ${path[i]} | awk '{print $2}' ) ${date[i]} | |
done | sed "s $HOME ~ g" | |
IFS=$OLDIFS | |
unset reg list temp OLDIFS i uniq_num mru target num date path length t | |
} | |
function _bookmark_candidacy() { | |
[ ! -f $bookmarklist ] && return 1 | |
echo $( awk '{print $1}' $bookmarklist ) | |
} | |
function _bookmark_complement() { | |
local curw | |
COMPREPLY=() | |
curw=${COMP_WORDS[COMP_CWORD]} | |
COMPREPLY=( $( compgen -W '`_bookmark_candidacy`' -- $curw ) ) | |
return 0 | |
} | |
[ -d $bookmarkdir ] && unset _bookmark_initialize || _bookmark_initialize | |
alias bookmark='_bookmark_usage' | |
alias edit='_bookmark_edit' | |
alias show='_bookmark_show' | |
alias reg='_bookmark_regist' | |
alias go='_bookmark_go' | |
alias del='_bookmark_delete' | |
alias p='_bookmark_print' | |
complete -F _bookmark_complement go | |
complete -F _bookmark_complement del | |
complete -F _bookmark_complement p | |
# okashi | |
# okashi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment