如何从单词的中间使zsh函数自动完成? [英] How do I make a zsh function autocomplet from the middle of a word?

查看:79
本文介绍了如何从单词的中间使zsh函数自动完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用zsh并编写了一个函数来替换cd函数.在一些帮助下,我得到了它的工作,就像我想要的那样(大多数情况下).这是对我的另一个问题的跟进.该功能几乎可以按我希望的方式工作,但是语法突出显示和自动完成功能仍然存在一些问题.

I use zsh and wrote a function to replace cd function. With some help I got it to work like I want it to (mostly). This is a followup to one of my other question. The function almost works like I want it to, but I still have some problems with syntax highlighting and autocompletion.

对于示例,假设您的目录如下:

For the examples, lets say your directories look like this:

/
    a/
        b/
        c/
            d/
        some_dir/

我还假设已获取以下代码:

I am also assuming the following code has been sourced:

cl () {
    local first=$( echo $1 | cut -d/ -f1 )
    if [ -d $first ]; then
        pushd $1 >/dev/null # If the first argument is an existing normal directory, move there
    else
        pushd ${PWD%/$first/*}/$1 >/dev/null # Otherwise, move to a parent directory or a child of that parent directory
    fi
}
_cl() {
    _cd
    pth=${words[2]}
    opts=""
    new=${pth##*/}
    local expl
    # Generate the visual formatting and store it in `$expl`
    _description -V ancestor-directories expl 'ancestor directories'
    [[ "$pth" != *"/"*"/"* ]] && middle="" || middle="${${pth%/*}#*/}/"
    if [[ "$pth" != *"/"* ]]; then
        # If this is the start of the path
        # In this case we should also show the parent directories
        local ancestor=$PWD:h
        while (( $#ancestor > 1 )); do
            # -f: Treat this as a file (incl. dirs), so you get proper highlighting.
            # -Q: Don't quote (escape) any of the characters.
            # -W: Specify the parent of the dir we're adding.
            # ${ancestor:h}: The parent ("head") of $ancestor.
            # ${ancestor:t}: The short name ("tail") of $ancestor.
            compadd "$expl[@]" -fQ -W "${ancestor:h}/" - "${ancestor:t}"
            # Move on to the next parent.
            ancestor=$ancestor:h
        done
    else
        # $first is the first part of the path the user typed in.
        # it it is part of the current direoctory, we know the user is trying to go back to a directory
        first=${pth%%/*}
        # $middle is the rest of the provided path
        if [ ! -d $first ]; then
            # path starts with parent directory
            dir=${PWD%/$first/*}/$first
            first=$first/
            # List all sub directories of the $dir/$middle directory
            if [ -d "$dir/$middle" ]; then
                for d in $(ls -a $dir/$middle); do
                    if [ -d $dir/$middle/$d ] && [[ "$d" != "." ]] && [[ "$d" != ".." ]]; then
                        compadd "$expl[@]" -fQ -W $dir/ - $first$middle$d
                    fi
                done
            fi
        fi
    fi
}
compdef _cl cl

问题:

在我的zshrc中,有一行:

In my zshrc, I have a line:

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' '+l:|=* r:|=*'

这应该使自动完成功能不区分大小写,并确保我可以开始输入目录名的最后一部分,并且仍然会用全名结束输入

This should make autocompletions case insensitive and make sure I can start typing the last part of a directory name, and in will still finnish the full name

示例:

$ cd /a
$ cd di[tab] # replaces 'di' with 'some_dir/'
$ cl di[tab] # this does not do anything. I would like it to replace 'di' with 'some_dir'

当我输入"di"时如何提示"some_dir"?

How do get it to suggest 'some_dir' when I type 'di'?

推荐答案

您的 matcher-list 中的第二个匹配器永远不会被调用,因为 _cl()返回真实"(实际上是退出状态 0 ),即使尚未添加任何匹配项也是如此.返回"true",则返回"true".导致 _main_complete()假定我们已经完成,因此将不尝试列表中的下一个匹配器.

The second matcher in your matcher-list never gets called, because _cl() returns "true" (exit status 0, actually) even when it has not added any matches. Returning "true" causes _main_complete() to assume that we're done completing and it will thus not try the next matcher in the list.

要解决此问题,请将以下内容添加到 _cl()的开头:

To fix this, add the following to the start of _cl():

local -i nmatches=$compstate[nmatches]

,然后到 _cl()的末尾:

(( compstate[nmatches] > nmatches ))

这样, _cl()将返回"true";仅当它设法实际添加完成时.

That way, _cl() will return "true" only when it has managed to actually add completions.

这篇关于如何从单词的中间使zsh函数自动完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆