233 lines
7.2 KiB
Bash
233 lines
7.2 KiB
Bash
## -*- mode:sh -*- #
|
|
################################################################################
|
|
## Bash specific functions
|
|
################################################################################
|
|
|
|
if isShell "bash"; then
|
|
|
|
##==============================================================================
|
|
## Browse History
|
|
##==============================================================================
|
|
# Parameters usage -- should be set before sourcing the function.
|
|
if [ -d "$SHELLDIR" ]; then
|
|
BHISTORY="${SHELLDIR}/bhistory"
|
|
else
|
|
BHISTORY="$HOME/.bhistory"
|
|
fi
|
|
BHISTFILESIZE=20
|
|
BHISTREVERT=true
|
|
BHISTLOADLAST=true
|
|
|
|
|
|
# Where to store the history file.
|
|
if [ "$BHISTORY" == "" ]; then
|
|
if [ -d "$SHELLDIR" ]; then
|
|
BHISTORY="${SHELLDIR}/bhistory"
|
|
else
|
|
BHISTORY="$HOME/.bhistory"
|
|
fi
|
|
fi
|
|
# History prompted to the user.
|
|
# BHISTFILESIZE +1 entry are stored, the additional one
|
|
# is for the current directory to be remembered for new session.
|
|
[ "$BHISTFILESIZE" == "" ] && BHISTFILESIZE=20
|
|
|
|
# If true, first listed is last browsed.
|
|
[ "$BHISTREVERT" == "" ] && BHISTREVERT=true
|
|
|
|
# Go back to previous folder when starting a new session.
|
|
[ "$BHISTLOADLAST" == "" ] && BHISTLOADLAST=true
|
|
|
|
|
|
# Prevent infinite recursiveness when sourcing multiple times.
|
|
unalias cd>/dev/null 2>&1
|
|
|
|
# SEED is used to generate uniq filenames.
|
|
SEED=$(date "+%y-%m-%d-%H%M%S")
|
|
|
|
# Makes sure destination folder exists.
|
|
mkdir -p $(dirname "$BHISTORY")
|
|
|
|
# Use 'head' or 'tail' depending on BHISTREVERT
|
|
if $BHISTREVERT; then
|
|
BFUNC=head
|
|
BFUNCREV=tail
|
|
touch "${BHISTORY}-true"
|
|
if [ -e "$BHISTORY" -a -e "${BHISTORY}-false" ]; then
|
|
rm -rf "${BHISTORY}-false"
|
|
touch "${BHISTORY}-${SEED}_REV"
|
|
tac "$BHISTORY" > "${BHISTORY}_${SEED}_REV"
|
|
cat "${BHISTORY}_${SEED}_REV" > "$BHISTORY"
|
|
rm -rf "${BHISTORY}_${SEED}_REV"
|
|
fi
|
|
else
|
|
BFUNC=tail
|
|
BFUNCREV=head
|
|
touch "${BHISTORY}-false"
|
|
if [ -e "$BHISTORY" -a -e "${BHISTORY}-true" ]; then
|
|
rm -rf "${BHISTORY}-true"
|
|
touch "${BHISTORY}-${SEED}_REV"
|
|
tac "$BHISTORY" > "${BHISTORY}_${SEED}_REV"
|
|
cat "${BHISTORY}_${SEED}_REV" > "$BHISTORY"
|
|
rm -rf "${BHISTORY}_${SEED}_REV"
|
|
fi
|
|
fi
|
|
|
|
|
|
# Go back to previous folder when starting a new session.
|
|
# Need to put this part before the new 'cd' is set to prevent $HOME from being added as last entry in the history.
|
|
if [ $BHISTLOADLAST -a -e $BHISTORY ]; then
|
|
LASTPATH="$($BFUNC -n1 $BHISTORY)"
|
|
if [[ -e "$LASTPATH" ]]; then
|
|
cd "$LASTPATH"
|
|
fi
|
|
unset LASTPATH
|
|
fi
|
|
|
|
|
|
function bcd(){
|
|
# First character is an hyphen.
|
|
if [ "${1:0:1}" == "-" ]; then
|
|
if [ ${#1} -eq 1 ]; then # cd -
|
|
cd -
|
|
else
|
|
DEST=${1:1} # After the hyphen
|
|
|
|
# Check if the content after the hyphen is a number.
|
|
if [[ $DEST == ${DEST//[^0-9]/} ]]; then
|
|
let DEST=$DEST # Set DEST as an integer only here to avoid errors.
|
|
|
|
if $BHISTREVERT; then
|
|
let DEST=${DEST}+1
|
|
fi
|
|
|
|
NEWPATH=$(head -n$DEST "$BHISTORY"|tail -n1)
|
|
echo ${NEWPATH}
|
|
cd "${NEWPATH}"
|
|
else
|
|
cd "$1"
|
|
fi
|
|
fi
|
|
else
|
|
if [ -z "$1" ]; then
|
|
cd
|
|
else
|
|
cd "$1"
|
|
fi
|
|
fi
|
|
|
|
|
|
## Let's update the history.
|
|
touch $BHISTORY
|
|
|
|
# A buffer is used to avoid flow errors.
|
|
if $BHISTREVERT; then
|
|
echo ${PWD} >> "${BHISTORY}_$SEED"
|
|
cat "$BHISTORY" >> "${BHISTORY}_$SEED"
|
|
else
|
|
cat "$BHISTORY" >> "${BHISTORY}_$SEED"
|
|
echo "${PWD}" >> "${BHISTORY}_$SEED"
|
|
fi
|
|
|
|
# The 'awk' command makes sure there is duplicates.
|
|
# If the history size is beyond the limit set by $BHISTFILESIZE+1, it is cut.
|
|
# The '+1' is for storing the current folder which is not displayed to the used.
|
|
let BHISTSIZEREAL=${BHISTFILESIZE}+1
|
|
awk ' !x[$0]++' "${BHISTORY}_$SEED" | $BFUNC -n $BHISTSIZEREAL > "$BHISTORY"
|
|
|
|
rm "${BHISTORY}_$SEED"
|
|
}
|
|
|
|
function bhistory(){
|
|
if [ ! -e "$BHISTORY" ]; then
|
|
echo "Browse history empty"
|
|
else
|
|
let BHISTDISPLAY=$(cat "$BHISTORY"| wc -l)-1
|
|
$BFUNCREV -n$BHISTDISPLAY "$BHISTORY"| cat -n
|
|
fi
|
|
}
|
|
|
|
# Clean -- buggy?
|
|
#unset BFUNC BFUNCREV SEED BHISTSIZEREAL
|
|
|
|
# Replace 'cd' command
|
|
alias cd='bcd'
|
|
|
|
shopt -s extglob # To allow bash to understand generic expression
|
|
shopt -s progcomp # To enable the programmable completion
|
|
set +o nounset # Otherwise some completions will fail
|
|
complete -A directory cd
|
|
|
|
|
|
##==============================================================================
|
|
## Alias auto completion
|
|
##==============================================================================
|
|
# wrap_alias takes three arguments:
|
|
# $1: The name of the alias
|
|
# $2: The command used in the alias
|
|
# $3: The arguments in the alias all in one string
|
|
# Generate a wrapper completion function (completer) for an alias
|
|
# based on the command and the given arguments, if there is a
|
|
# completer for the command, and set the wrapper as the completer for
|
|
# the alias.
|
|
#function wrap_alias() {
|
|
# [[ "$#" == 3 ]] || return 1
|
|
#
|
|
# local alias_name="$1"
|
|
# local aliased_command="$2"
|
|
# local alias_arguments="$3"
|
|
# local num_alias_arguments=$(echo "$alias_arguments" | wc -w)
|
|
#
|
|
# # The completion currently being used for the aliased command.
|
|
# local completion=$(complete -p $aliased_command 2> /dev/null)
|
|
#
|
|
# # Only a completer based on a function can be wrapped so look for -F
|
|
# # in the current completion. This check will also catch commands
|
|
# # with no completer for which $completion will be empty.
|
|
# echo $completion | grep -q -- -F || return 0
|
|
#
|
|
# local namespace=alias_completion::
|
|
#
|
|
# # Extract the name of the completion function from a string that
|
|
# # looks like: something -F function_name something
|
|
# # First strip the beginning of the string up to the function name by
|
|
# # removing "* -F " from the front.
|
|
# local completion_function=${completion##* -F }
|
|
# # Then strip " *" from the end, leaving only the function name.
|
|
# completion_function=${completion_function%% *}
|
|
#
|
|
# # Try to prevent an infinite loop by not wrapping a function
|
|
# # generated by this function. This can happen when the user runs
|
|
# # this twice for an alias like ls='ls --color=auto' or alias l='ls'
|
|
# # and alias ls='l foo'
|
|
# [[ "${completion_function#$namespace}" != $completion_function ]] && return 0
|
|
#
|
|
# local wrapper_name="${namespace}${alias_name}"
|
|
#
|
|
# eval "
|
|
#function ${wrapper_name}() {
|
|
# let COMP_CWORD+=$num_alias_arguments
|
|
# args=( \"${alias_arguments}\" )
|
|
# COMP_WORDS=( $aliased_command \${args[@]} \${COMP_WORDS[@]:1} )
|
|
# $completion_function
|
|
# }
|
|
#"
|
|
#
|
|
# To create the new completion we use the old one with two
|
|
# replacements:
|
|
# 1) Replace the function with the wrapper.
|
|
# local new_completion=${completion/-F * /-F $wrapper_name }
|
|
# 2) Replace the command being completed with the alias.
|
|
# new_completion="${new_completion% *} $alias_name"
|
|
|
|
# eval "$new_completion"
|
|
#}
|
|
|
|
# For each defined alias, extract the necessary elements and use them
|
|
# to call wrap_alias.
|
|
#eval "$(alias -p | sed -e 's/alias \([^=][^=]*\)='\''\([^ ][^ ]*\) *\(.*\)'\''/wrap_alias \1 \2 '\''\3'\'' /')"
|
|
|
|
#unset wrap_alias
|
|
|
|
fi
|