329 lines
8.1 KiB
Plaintext
329 lines
8.1 KiB
Plaintext
function cd_history () {
|
|
local old
|
|
local p
|
|
local b
|
|
if [ -z "$1" ]
|
|
then \cd "$HOME"
|
|
return
|
|
fi
|
|
old=$( tail -n 149 "$HOME/.bash_cdhistory" )
|
|
echo "$old" > "$HOME/.bash_cdhistory"
|
|
\cd "$1"
|
|
p=$( pwd )
|
|
b=$( basename "$p" )
|
|
echo $b":"$p >> "$HOME/.bash_cdhistory"
|
|
}
|
|
alias cd=cd_history
|
|
|
|
function qcd() {
|
|
local OPTIND
|
|
local OPTARG
|
|
local opt
|
|
local case
|
|
|
|
while getopts ae:hiILl:m opt
|
|
do case "$opt" in
|
|
a)
|
|
# Adding
|
|
local name=${!OPTIND}
|
|
if [ -z "$name" ]
|
|
then name=$( basename $( pwd ))
|
|
fi
|
|
|
|
echo "$name":$( pwd )
|
|
echo "$name":$( pwd ) >> ~/.qcd
|
|
return
|
|
;;
|
|
i)
|
|
case="-i"
|
|
;;
|
|
I)
|
|
echo "See ~/.bash_completion for possible duplicates"
|
|
echo '
|
|
have qcd &&
|
|
_qcd()
|
|
{
|
|
local cur
|
|
local d
|
|
COMPREPLY=()
|
|
cur=${COMP_WORDS[COMP_CWORD]}
|
|
if [[ "$cur" == -* ]]; then
|
|
COMPREPLY=( $( compgen -W "-a -i -h -l -L -m" -- $cur ) )
|
|
return 0
|
|
fi
|
|
COMPREPLY=( $( compgen -W "$( grep -h ^"$cur" ~/.qcd <( tac ~/.bash_cdhistory ) | cut -d: -f1 )" ) )
|
|
}
|
|
complete -F _qcd qcd
|
|
' >> ~/.bash_completion
|
|
. /etc/bash_completion
|
|
touch ~/.qcd ~/.bash_cdhistory
|
|
return
|
|
;;
|
|
L)
|
|
echo ==History ~/.bash_cdhistory:
|
|
cat ~/.bash_cdhistory
|
|
echo
|
|
echo ==Saved ~/.qcd:
|
|
cat ~/.qcd
|
|
return
|
|
;;
|
|
l)
|
|
local d=$( grep $case -h ^"$OPTARG" ~/.qcd <( tac ~/.bash_cdhistory ) | head -n 1 )
|
|
d=${d/*:/}
|
|
echo $d
|
|
return
|
|
;;
|
|
e)
|
|
local d=$( grep $case -h ^"$OPTARG" ~/.qcd <( tac ~/.bash_cdhistory ) | head -n 1 )
|
|
d="${d/*:/}"
|
|
echo QCD=$d
|
|
QCD="$d"
|
|
return
|
|
;;
|
|
m)
|
|
local IFS=$'\n'
|
|
touch ~/.qcd ~/.bash_cdhistory
|
|
touch ~/.qcd.tmp ~/.bash_cdhistory.tmp
|
|
for line in $( cat ~/.bash_cdhistory );
|
|
do if [ -d "${line/*:/}" ];
|
|
then echo "$line" >> ~/.bash_cdhistory.tmp
|
|
fi
|
|
done
|
|
mv ~/.bash_cdhistory.tmp ~/.bash_cdhistory
|
|
for line in $( cat ~/.qcd );
|
|
do if [ -d "${line/*:/}" ];
|
|
then echo "$line" >> ~/.qcd.tmp
|
|
fi
|
|
done
|
|
mv ~/.qcd.tmp ~/.qcd
|
|
return
|
|
;;
|
|
h)
|
|
echo 'qcd [-hiLm]|[-al] [name]
|
|
Change current working path based on the list ~/.qcd
|
|
Keeps a history of folders visited in ~/.bash_cdhistory
|
|
|
|
-a [name] Adds the path to the list
|
|
You may add the name of the path, but when omitted
|
|
the basename will be used
|
|
-e [name] Show the match, store in variable QCD
|
|
-i Case insensitive search, must come first.
|
|
-I Install, with autocompletion (use only once)
|
|
-l [name] Show the match, but do not change
|
|
-L Lists the paths
|
|
-m Maintain the list, deleting non-existing entries'
|
|
return
|
|
;;
|
|
esac
|
|
done
|
|
shift $(($OPTIND - 1))
|
|
if [ -z "$1" ]
|
|
then [[ $OPTIND -gt 1 ]] && return
|
|
\cd; return
|
|
fi
|
|
unset OPTSTRING
|
|
unset OPTIND
|
|
if [ "$1" = "-" ]
|
|
then d=$( tail -n 1 ~/.bash_cdhistory )
|
|
d=${d/*:/}
|
|
\cd "$d"
|
|
return
|
|
fi
|
|
d=$( grep $case -h ^"$1" ~/.qcd <( tac ~/.bash_cdhistory ) | head -n 1 )
|
|
d=${d/*:/}
|
|
if [ ! -z "$d" ]
|
|
then \cd "$d"
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
function whenfilechanges() {
|
|
[ -z "$1" ] && { echo 'Usage: whenfilechanges "file" "some" "command"
|
|
Follows the modification time of the "file" and runs the command
|
|
at every change. '
|
|
return
|
|
}
|
|
[ -e "$1" ] || { echo $1 not found
|
|
return
|
|
}
|
|
local fname
|
|
local otime
|
|
local ntime
|
|
|
|
fname=$1
|
|
shift 1
|
|
otime=$( stat -c %Z "$fname" )
|
|
while :
|
|
do ntime=$( stat -c %Z "$fname" )
|
|
[ "$ntime" -ne "$otime" ] && {
|
|
eval "$@"
|
|
otime=$( stat -c %Z "$fname" )
|
|
}
|
|
|
|
sleep 2
|
|
done
|
|
|
|
}
|
|
|
|
function gcd() {
|
|
# guess cd, find first match in folder
|
|
local dname
|
|
local bname
|
|
local match
|
|
local join
|
|
set -o pipefail
|
|
join="$@"
|
|
join=${join// /.}
|
|
dname=$( dirname "$join" )
|
|
bname=$( basename "$join" )
|
|
match=$( ls -d "$dname"/*/ | grep "$bname" | head -n 1 )
|
|
[[ ! "$match" = "" ]] && {
|
|
echo $match | grep --color=always "$bname"
|
|
\cd "$match"
|
|
return
|
|
}
|
|
match=$( ls -d "$dname"/*/ | grep -i "$bname" | head -n 1 )
|
|
[[ ! "$match" = "" ]] && {
|
|
echo $match | grep -i --color=always "$bname"
|
|
\cd "$match"
|
|
return
|
|
}
|
|
echo No match.
|
|
}
|
|
|
|
function fcd() {
|
|
# gcd future fork
|
|
local cdto
|
|
{ cdto=$( python -c '
|
|
import sys,os,re,termios,tty
|
|
if len(sys.argv)==1:
|
|
print("Arguments: [dir/]pattern_to_match_folders")
|
|
sys.exit(0)
|
|
def G():
|
|
return "\033[32;1m"
|
|
def R():
|
|
return "\033[31;1m"
|
|
def Z():
|
|
return "\033[0m"
|
|
def CS():
|
|
return "1234567890qwertyuiop"
|
|
class getch:
|
|
def get(self):
|
|
fd = sys.stdin.fileno()
|
|
old_settings = termios.tcgetattr(fd)
|
|
try:
|
|
tty.setraw(sys.stdin.fileno())
|
|
ch = sys.stdin.read(1)
|
|
finally:
|
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
|
return ch
|
|
|
|
pattern=".".join(sys.argv[1:])
|
|
|
|
pat_dir=os.path.dirname(pattern)
|
|
if pat_dir=="":
|
|
pat_dir="."
|
|
pat_base=os.path.basename(pattern)
|
|
if not os.path.exists(pat_dir):
|
|
print(pat_dir+": "+R()+"No such folder"+Z())
|
|
sys.exit(1)
|
|
current_folders=[d for d in os.listdir(pat_dir) if os.path.isdir(d)]
|
|
current_folders=[d for d in current_folders if not d.startswith(".")]
|
|
current_folders.sort()
|
|
|
|
match_case=re.compile(".*"+pat_base+".*")
|
|
repl_case=re.compile("("+pat_base+")")
|
|
|
|
matching_folders=[d for d in current_folders if match_case.match(d)]
|
|
matches=[repl_case.sub(G()+"\g<1>"+Z(),d) for d in matching_folders]
|
|
|
|
if len(matching_folders)==0:
|
|
match_nocase=re.compile(".*"+pat_base+".*",re.I)
|
|
repl_nocase=re.compile(pat_base,re.I)
|
|
matching_folders=[d for d in current_folders if match_nocase.match(d)]
|
|
matches=[repl_case.sub(G()+pat_base+Z(),d) for d in matching_folders]
|
|
|
|
if len(matching_folders)==1:
|
|
print(matches[0])
|
|
sys.stderr.write(os.path.join(pat_dir,matching_folders[0]))
|
|
sys.exit(0)
|
|
if len(matching_folders)==0:
|
|
print(R()+"no matches"+Z())
|
|
sys.exit(1)
|
|
for i,m in enumerate(matches[0:20]):
|
|
print(CS()[i]+": "+m)
|
|
ch=getch()
|
|
key_in=ch.get()
|
|
try:
|
|
key_index=CS().index(key_in)
|
|
key_match=matching_folders[key_index]
|
|
except ValueError,IndexError:
|
|
sys.exit(1)
|
|
sys.stderr.write(os.path.join(pat_dir,key_match))
|
|
' "$@" 2>&1 1>&$out); } {out}>&1 ; \cd "$cdto"
|
|
|
|
}
|
|
|
|
function rmv () {
|
|
#mv with rsync
|
|
local sources
|
|
sources=()
|
|
# remove / from ends, if target is an existing folder
|
|
for (( i=1; i<=$(($#-1)); i++ ))
|
|
do if [ -d "${@: -1}" ]
|
|
then sources+=("${!i%/}")
|
|
else sources+=("${!i}")
|
|
fi
|
|
done
|
|
rsync -vaP --remove-source-files "${sources[@]}" "${@: -1}"
|
|
# remove empty folders from sources (not last argument)
|
|
for (( i=1; i<=$(($#-1)); i++ ))
|
|
do if [ -d "${!i}" ]
|
|
then find "${!i}" -depth -type d -exec rmdir \{\} \;
|
|
fi
|
|
done
|
|
}
|
|
|
|
function igrep () {
|
|
# Interactive grep
|
|
local args
|
|
args="-i -e "
|
|
while true
|
|
do read -e -i "$args" args
|
|
echo $@
|
|
grep --color=auto $args "$@"
|
|
if [ "$?" -ne 0 ]
|
|
then echo _no_matches_ | grep --color=auto ".*"
|
|
fi
|
|
done
|
|
|
|
}
|
|
|
|
function ised () {
|
|
# Interactive sed
|
|
local args
|
|
if [ ! -f "$1" ]; then echo must give atleast one file; return 1;fi;
|
|
args="-e s/string//g"
|
|
while true
|
|
do read -e -i "$args" args
|
|
echo input files: "$@"
|
|
eval sed $args "$@"
|
|
if [ "$?" -ne 0 ]
|
|
then echo Error output | grep --color=auto ".*"
|
|
fi
|
|
done
|
|
|
|
}
|
|
|
|
function foldermenu_prompt {
|
|
[ -f .foldermenu ] && {
|
|
echo -n "f:"
|
|
foldermenu -lf 10 || echo -n "*"
|
|
} || {
|
|
true
|
|
}
|
|
}
|
|
|