ambevar-dotfiles/.shell.d/funs_bash

231 lines
7.2 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

################################################################################
## 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