Cd : Make cdd find exact match first.

This commit is contained in:
Dmitry Voronin 2024-01-09 19:53:36 +03:00 committed by desktop
parent 40b97132a7
commit 1028ad1120
4 changed files with 57 additions and 21 deletions

View file

@ -1,26 +1,36 @@
# CD (back) to directory. # CD (back to) directory.
# Finds first directory that matches the input (case-insensitive). # Goes to the exact-match dir first. If no exact match found, it finds first directory that contains the input (case-insensitive).
# Usage: cdd <DIR> # Usage: cdd <DIR>
function cdd() { function cdd() {
local target="${1}" local target="${1}"
local array
if [[ "${target}" = "" ]]; then
help cdd
return 2
fi
local array=($(_cdd_directories))
local result local result
IFS='/' read -r -a array <<< "${PWD}"
array=("${array[@]:1}")
# Make search case-insensitive. # Check for exact match ELSE look for containing.
shopt -s nocasematch if _contains ${target} ${array[@]}; then
local current="${PWD%/*}"
result="${current%\/$target\/*}/${target}"
else
# Make search case-insensitive.
shopt -s nocasematch
# Find desired dir. # Find dir name that contains input.
local found=1 local found=1
for (( idx=${#array[@]}-2 ; idx>=0 ; idx-- )); do for (( idx=${#array[@]}-1 ; idx>=0 ; idx-- )); do
dir="${array[idx]}" dir="${array[idx]}"
[[ "${dir}" =~ "${target}" ]] && found=0 [[ "${dir}" =~ "${target}" ]] && found=0
[[ ${found} = 0 ]] && result="/${dir}${result}" [[ ${found} = 0 ]] && result="/${dir}${result}"
done done
# Clean-up??? # Clean-up???
shopt -u nocasematch shopt -u nocasematch
fi
# Go there! # Go there!
if [[ "${result}" != "" ]]; then if [[ "${result}" != "" ]]; then
@ -31,12 +41,19 @@ function cdd() {
fi fi
} }
_cdd_directories() { # Get list of all parent dirs.
function _cdd_directories() {
local array local array
IFS='/' read -r -a array <<< "${PWD}" IFS='/' read -r -a array <<< "${PWD}"
array=("${array[@]:1}") array=("${array[@]:1}")
unset array[-1] unset array[-1]
_autocomplete_first "${array[@]}" printf "%s\n" "${array[@]}"
} }
complete -o nosort -o filenames -F _cdd_directories cdd function _comp_cdd() {
local IFS=$'\n'
local dirs=($(_cdd_directories))
_autocomplete_first ${dirs[@]}
}
complete -o nosort -o filenames -F _comp_cdd cdd

View file

@ -124,7 +124,7 @@ function parse_titlecase() {
continue continue
fi fi
if [[ "${minors[@]}" =~ $(echo ${part} | sed -e "s/[${_PARSE_SPLIT_CHARS}]//g") ]]; then if _contains $(echo ${part} | sed -e "s/[${_PARSE_SPLIT_CHARS}]//g") ${minors[@]}; then
echo -n "${part}" echo -n "${part}"
else else
echo -n "${part^}" echo -n "${part^}"

View file

@ -97,3 +97,22 @@ function _debug() {
function _info() { function _info() {
>&2 echo -e "${color_bwhite}${*}${color_default}" >&2 echo -e "${color_bwhite}${*}${color_default}"
} }
# Check if array contains an element (strict).
# Usage: _contains <ELEMENT> <ARRAY>
function _contains() {
local IFS=$'\n'
local target="${1}"
local array="${@:2}"
if [[ "${target}" = "" ]] || [[ "${array}" = "" ]]; then
help _contains
return 2
fi
for item in ${array[@]}; do
[[ "${item}" = "${target}" ]] && return 0
done
return 1
}

View file

@ -51,7 +51,7 @@ Command|Description
Command|Description Command|Description
---|--- ---|---
`cdd <DIR>`|CD (back) to directory. Finds first directory that matches the input (case-insensitive). `cdd <DIR>`|CD (back to) directory. Goes to the exact-match dir first. If no exact match found, it finds first directory that contains the input (case-insensitive).
## Checksum. ## Checksum.