执行主类时如何使bash自动完成Java限定类名

时间:2018-08-27 17:35:14

标签: java bash autocomplete

手动键入Java主类的类名很麻烦,尤其是在深层包结构中。我希望bash制表符补全可以根据类的目录结构自动完成类名。

如何定制bash来做到这一点?

(我添加了自己的解决方案,但我会接受更好的答案。)

1 个答案:

答案 0 :(得分:1)

bash内置命令complete可用于自定义bash中的制表符补全。

有关更多信息,请参见bash documentation

简而言之,这可以通过为Java complete -F _comp_java java指定自定义完成功能来完成。 然后,该函数可以使用变量COMP_WORDS和COMP_CWORD在命令行中访问单词(和当前单词索引),以生成可能的补全列表。 可能的补全必须放置在数组COMPREPLY中。内置compgen可以与ls命令的输出结合使用,以找到以当前单词开头的所有路径。 然后可以修改这些可能的补全以用点代替斜杠。

这是执行此操作的一种方法。任何更清洁的解决方案都可以接受。

_comp_java () {
    prev=${COMP_WORDS[$COMP_CWORD - 1]}

    case $prev in
        "-jar")
            COMPREPLY=($(compgen -A file -- ${COMP_WORDS[$COMP_CWORD]}))
            ;;
        *)
            fields=($(echo ${COMP_WORDS[$COMP_CWORD]} | tr "." "\n"));
            [ "${COMP_WORDS[$COMP_CWORD]: -1}" == "." ] && lastIdx=0 || lastIdx=1
            [ ${#COMP_WORDS[$COMP_CWORD]} -eq 0 ] || [ ${lastIdx} -eq 0 ] && lastWord='' || lastWord=${fields[${#fields[@]}-1]}
            [ ${#COMP_WORDS[$COMP_CWORD]} -eq 0 ] && fields=() || fields=($(echo ${fields[*]:0:${#fields[@]}-$lastIdx}))
            [ ${lastIdx} -eq 0 ] && prefix=${COMP_WORDS[$COMP_CWORD]} || prefix=$(tr ' ' '.' <<< $(echo "${fields[@]}."))
            [ "${prefix:0}" == "." ] && prefix=""

            COMPREPLY=( $(compgen -W "$(ls $(tr ' ' '/' <<< $(echo ${fields[@]})))" -- $lastWord ))
            COMPREPLY=(${COMPREPLY[@]/#/$prefix})
            COMPREPLY=(${COMPREPLY[@]/%/.})
            COMPREPLY=(${COMPREPLY[@]/.class./})
            COMPREPLY=(${COMPREPLY[@]/.java./})
            ;;
    esac
    return 0
}

complete -o nospace -o filenames -F _comp_java java