【问题标题】:How to show only first level subdir in bash auto-completion?如何在bash自动完成中仅显示第一级子目录?
【发布时间】:2017-04-06 17:48:22
【问题描述】:

我有这个 bash 完成文件

#/etc/bash_completion.d/mycommand

_mycommand()
{
    local cur
    COMPREPLY=()

    _init_completion || return

    #Variable to hold the current word
    cur="${COMP_WORDS[COMP_CWORD]}"

    #array variable COMPREPLY

    dirs=('Rootdir/
        Secondrootdir/ 
        Rootdir/Subdir/
        Secondrootdir/Anothersubdir/
        Secondrootdir/Thirdsubdir/
        Secondrootdir/Anothersubdir/Subsubdir/'
    )

    COMPREPLY=($(compgen -W "$dirs" "$cur"))

}

#Assign the auto-completion function _mycommand for our command mycommand.
complete -F _mycommand mycommand

当我有多项选择并按两次 TAB 时,我看到以下内容:

$ mycommand Secondrootdir/
Secondrootdir/
Secondrootdir/Anothersubdir/
Secondrootdir/Anothersubdir/Subsubdir/
Secondrootdir/Thirdsubdir/

但我只想查看当前输入的Secondrootdir

的一级深层子目录

像这样:

$ mycommand Secondrootdir/
Anothersubdir/ Thirdsubdir/

cd 命令做得很好

$ cd Music/
kattymusic/ Playlists/  Relax/

但我不明白 cd 自动完成是如何工作的。

有人可以帮帮我吗?

【问题讨论】:

  • 没有。他们在远程服务器上。而且我只能使用 API 接收它们的列表。
  • 谢谢。很好的例子,但我想要相反的东西。
  • 我会为此付出更大的努力,希望我能成功。
  • 问题是 - 如果我将计算输入斜杠的数量,并在数字+1 斜杠之后修剪输出字符串,那么当我点击制表符时,自动完成将停止。

标签: linux bash shell ubuntu bash-completion


【解决方案1】:

感谢这篇文章

Bash completion: compgen a wordlist as if they were paths - Only suggest up until next slash

最后代码是这样的

#/etc/bash_completion.d/mycommand

_mycommand()
{
    local cur i

    _init_completion || return

    compopt -o filenames

    #Variable to hold the current word
    cur="${COMP_WORDS[COMP_CWORD]}"


    dirs='Rootdir/Subdir/ Secondrootdir/Thirdsubdir/ Secondrootdir/Anothersubdir/Subsubdir/'

    # If we include root dirs we have to remove them
    # e.g we have Secondrootdir/ Secondrootdir/Anothersubdir/ Secondrootdir/Anothersubdir/Subsubdir/'
    # we need to skip the shorties path and remain only the longest one Secondrootdir/Anothersubdir/Subsubdir/'
    # dirs='Rootdir/ 
    #     Secondrootdir/
    #     Rootdir/Subdir/
    #     Secondrootdir/Anothersubdir/
    #     Secondrootdir/Thirdsubdir/
    #     Secondrootdir/Anothersubdir/Subsubdir/'

    arr=($(compgen -W "$dirs" -- $cur))
    for path in "${arr[@]}"
    do

        local trailing_trim

        # Determine what to trim from the end
        trailing_trim="${path#${cur%/*}/}/"
        trailing_trim="${trailing_trim#*/}"
        trailing_trim="${trailing_trim%/}"


        # Don't add a space if there is more to complete
        [[ "$trailing_trim" != "" ]] && compopt -o nospace

        # Remove the slash if mark-directories is off
        if ! _rl_enabled mark-directories
        then
            # If The current typed path doesnt have a slash in it yet check if
            # it is the full first portion of a path and ignore everything after
            # if it is. We don't have to do this once the typed path has a slash
            # in it as the logic above will pick up on it
            [[ "$cur" != */* && "$path" == ${cur}/* ]] && path="$cur/$trailing_trim"    

            trailing_trim="/$trailing_trim"
        fi

        COMPREPLY[i++]="${path%%${trailing_trim}}"

    done



}

#Assign the auto-completion function _mycommand for our command mycommand.
complete -F _mycommand mycommand

【讨论】:

    【解决方案2】:

    我找到了解决方案,而且非常简单。

    只需一行代码就能发挥作用

    # This forces readline to only display the last item separated by a slash
    compopt -o filenames
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-14
      • 2017-04-08
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多