Programmable Completion 可编程补全
当试图对一个命令的参数进行词的补全时,如果已经使用内建命令 complete 定义了这个命令的补全规则 ( compspec),将启动可编程补全功能 (参见下面的 shell 内建命令(SHELL BUILTIN COMMANDS) 章节)。
首先,命令名被确认。如果针对这个命令有补全规则的定义,那么将使用 规则来产生可能的词的补全的列表。如果命令词是一个路径全名,将首先搜索 针对这个路径全名的规则。如果针对这个路径全名没有找到规则,将尝试查找 针对最后一个斜杠后面的部分的规则。
一旦找到了一个规则,它将用作产生匹配的词。如果没有找到,将进行上面 Completing 中描述的 bash 默认的补全。
首先,将执行规则指定的动作。只有以被补全的词开始的匹配词才会被返回。 当在文件或目录名补全中使用 -f 或 -d 选项时,shell 变量 FIGNORE 将用于对匹配进行过滤。
接下来,将产生所有由-G 选项给出的文件名扩展模式指定的补全。 模式产生的词不必匹配要补全的词。shell 变量 GLOBIGNORE 不会用于过滤匹配结果,但是变量 FIGNORE 会被使用。
接下来,将考虑 -W 选项的参数指定的字符串。这个字符串首先被 划分,用特殊变量 IFS 中的字符作为分隔符。shell 引用被当作一个词。 接下来,每个词被扩展,使用上面 EXPANSION 中描述的 brace expansion, tilde expansion, parameter 和 variable expansion, command substitution, arithmetic expansion, 以及 pathname expansion 规则处理。对于结果,再使用上面 Word Splitting 中描述的规则划分成词。 扩展的结果与要补全的词进行前部一致的比较,匹配的词成为可能的补全。
在这些匹配被产生后,任何由 -F 和 -C 选项指定的 shell 函数和命令将被执行。当命令或函数被执行时,变量 COMP_LINE 和 COMP_POINT 被赋值,使用上面 Shell Variables 中的规则。 如果要执行 shell 函数,还将设置变量 COMP_WORDS 和 COMP_CWORD 当函数或命令被执行时,第一个参数是等待参数被补全的命令的名称, 第二个参数是要补全的词,第三个参数是当前命令行中,要补全的词前面的词。 对要补全的词产生的补全不会进行任何过滤;函数或命令在产生匹配时有完全的自由。
任何 -F 指定的函数将被首先执行。函数可以使用任何 shell 功能, 包含内建命令 compgen,来产生匹配。它必须将可能的补全放到数组变量 COMPREPLY 中。
接下来,任何 -C 选项指定的命令将被执行,其执行环境与命令替换 的环境相同。它应当向标准输出打印一个补全的列表,每行一个。 反斜杠可以用来转义一个新行符,如果需要的话。
所有可能的补全都产生之后,将对列表进行 -X 选项指定的任何过滤。 过滤器是一个模式,和路径名扩展中的一样;模式中的 & 替换为 要补全的词。字面上的 & 可以用反斜杠转义;反斜杠在进行匹配时被删除。 任何匹配这个模式的补全将从列表中删除。前导的 ! 将使模式含义相反; 这种情况下,任何不匹配这个模式的补全将被删除。
最后,B-P 和 -S 指定的任何前缀和后缀被添加到补全列表的每个 成员后面,结果返回给 readline 补全代码,作为可能的补全列表。
如果先前执行的动作没有产生任何匹配,并且在定义 compspec 规则时,为 complete 命令提供了 -o dirname 选项,将尝试目录名补全。
默认情况下,如果找到了一个规则,它产生的任何东西都被返回给补全代码, 作为可能的补全的全集。不再尝试默认的 bash 补全,readline 默认的 文件名补全也会禁止。如果定义规则时,为 complete 命令提供了 -o default 选项,在规则没有产生匹配时将进行 readline 默认的补全处理。
当一个规则指出期望目录名补全时,可编程补全函数强制 readline 在补全的名称 后面添加一个斜杠,如果它是一个到目录的符号连接。然后还要经过 readline 变量 mark-directories 的值处理,不管 readline 变量 mark-symlinked-directories 的值是什么。