bash使用zsh等快捷方式扩展cd

has*_*san 6 bash expand cd path

是否有可能在bash中扩展类似的东西

cd /u/lo/b<点击标签>

cd /usr/local/bin

Ase*_*rre 6

对不起,我不能提前发布,我在工作,并且绑定功能比我最初想的更容易出问题.

这是我想出的:

绑定以下脚本:

#!/bin/bash
#$HOME/.bashrc.d/autocomplete.sh
autocomplete_wrapper() {
    BASE="${READLINE_LINE% *} "           #we save the line except for the last argument
    [[ "$BASE" == "$READLINE_LINE " ]] && BASE="";  #if the line has only 1 argument, we set the BASE to blank
    EXPANSION=($(autocomplete "${READLINE_LINE##* }"))
    [[ ${#EXPANSION[@]} -gt 1 ]] && echo "${EXPANSION[@]:1}"  #if there is more than 1 match, we echo them
    READLINE_LINE="$BASE${EXPANSION[0]}"  #the current line is now the base + the 1st element
    READLINE_POINT=${#READLINE_LINE}      #we move our cursor at the end of the current line
}

autocomplete() {
    LAST_CMD="$1"
    #Special starting character expansion for '~', './' and '/'
    [[ "${LAST_CMD:0:1}" == "~" ]] && LAST_CMD="$HOME${LAST_CMD:1}"
    S=1; [[ "${LAST_CMD:0:1}" == "/" || "${LAST_CMD:0:2}" == "./" ]] && S=2; #we don't expand those

    #we do the path expansion of the last argument here by adding a * before each /
    EXPANSION=($(echo "$LAST_CMD*" | sed s:/:*/:"$S"g))

    if [[ ! -e "${EXPANSION[0]}" ]];then #if the path cannot be expanded, we don't change the output
        echo "$LAST_CMD"
    elif [[ "${#EXPANSION[@]}" -eq 1 ]];then #else if there is only one match, we output it
        echo "${EXPANSION[0]}"
    else
        #else we expand the path as much as possible and return all the possible results
        while [[ $l -le "${#EXPANSION[0]}" ]]; do
            for i in "${EXPANSION[@]}"; do
                if [[ "${EXPANSION[0]:$l:1}" != "${i:$l:1}" ]]; then
                    CTRL_LOOP=1
                    break
                fi
            done
            [[ $CTRL_LOOP -eq 1 ]] && break
            ((l++))
        done
        #we add the partial solution at the beggining of the array of solutions
        echo "${EXPANSION[0]:0:$l} ${EXPANSION[@]}"
    fi
}
Run Code Online (Sandbox Code Playgroud)

使用以下命令:

    source "$HOME/.bashrc.d/autocomplete.sh" 
    bind -x '"\t" : autocomplete_wrapper'
Run Code Online (Sandbox Code Playgroud)

输出:

>$ cd /u/lo/b<TAB>
>$ cd /usr/local/bin


>$ cd /u/l<TAB>
/usr/local /usr/lib
>$ cd /usr/l
Run Code Online (Sandbox Code Playgroud)

可以将绑定行添加到您的~/.bashrc文件中,执行以下操作:

if [[ -s "$HOME/.bashrc.d/autocomplete.sh" ]]; then
    source "$HOME/.bashrc.d/autocomplete.sh" 
    bind -x '"\t" : autocomplete_wrapper'
fi
Run Code Online (Sandbox Code Playgroud)

(取自这个答案)

此外,我强烈建议不要将此命令绑定到您的Tab密钥,因为它会覆盖默认的自动完成.

注意:在某些情况下,如果您尝试自动完成,这将是错误的,因为完成"/path/with spaces/something"的最后一个参数由确定${READLINE_LINE##* }.如果在您的情况下这是一个问题,您应该编写一个函数,在考虑引号时返回行的最后一个参数

请随时要求进一步澄清,我欢迎任何改进此脚本的建议