From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 3424 invoked from network); 11 Nov 2021 13:51:22 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 11 Nov 2021 13:51:22 -0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Message-ID:Date:Content-ID: Content-Type:MIME-Version:Subject:To:References:From:In-reply-to:Reply-To:Cc: Content-Transfer-Encoding:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=0KgXGFsvn5NygkydaC9xPWNxFzpj1FncW9IQeK1Rx3w=; b=Ok0axLWfinACWwtgMxIFrDKJ+0 xIxlw0GFpFkCPSUiHKVrlRiVkCyWUoLcfpUwuoAfE8udJaQm5pwoNKnhMLjfDvp4SJb2dMEKGgC56 YyZ6EdXLLNVB7maRqFwSxoV08sTF149stHb4D6VlyqqLmM//EXm3/DfRGOoGbjyVKt76zEeIwNkwi PQUOtN6v3O2jzLedh6ryhoMBsVwrafymxdXNDUANydbyShloBb9b7xzVcnxWYselfWVuESpookhwO XorYKw+EfgNQhysBav8mDmaA8aRv/Kwgwkfh1YS5e8TMvEjYcIiqmPRt3+1sBK3rCgXvnDU5W2vHD nKCTauGw==; Received: from authenticated user by zero.zsh.org with local id 1mlAU5-000OYW-L0; Thu, 11 Nov 2021 13:51:21 +0000 Received: from authenticated user by zero.zsh.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) id 1mlATr-000OGU-Qg; Thu, 11 Nov 2021 13:51:07 +0000 Received: from [192.168.178.21] (helo=hydra) by mail.kiddle.eu with esmtp(Exim 4.94.2) (envelope-from ) id 1mlATr-000NeI-5r for zsh-workers@zsh.org; Thu, 11 Nov 2021 14:51:07 +0100 In-reply-to: <77920-1636594918.537752@n8BC.rFQv.eL6F> From: Oliver Kiddle References: <77920-1636594918.537752@n8BC.rFQv.eL6F> To: Zsh hackers list Subject: Re: [BUG] Any type of file in command position gets misleadingly completed as 'executable file' MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <90908.1636638667.1@hydra> Date: Thu, 11 Nov 2021 14:51:07 +0100 Message-ID: <90909-1636638667.178839@O2iu.6E8K.CADT> X-Seq: 49564 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: I wrote: > However, it is surely a bug that $end is not reinitialised with each > iteration of the for loop. That makes it difficult to use the > description we were passed for the globbed-files but to put the > globbed-files first and directories second. > > It also looks like a bug that the recursive-files style is only > implemented where $end is set. And here is a patch to address those two points. The recursive-files code should really consider directories passed with -W instead of $PWD but all the handling of that is down in _path_files so that's not trivial. I've not changed the workings of recursive-files, it appears in full in the patch due to reindentation. The documentation claims that you can use %d in the description to get at the description supplied to the function. This isn't working, at least as far back as 4.2.1 and probably well beyond. It isn't even clear how this might ever have been implemented. The zformat in _next_label, comptags -A and $curtag perhaps. I'm not going to go further down that rabbit hole and have removed the line in the documentation. Oliver diff --git a/Completion/Unix/Type/_files b/Completion/Unix/Type/_files index 4ddec1e12..f03b4a148 100644 --- a/Completion/Unix/Type/_files +++ b/Completion/Unix/Type/_files @@ -92,7 +92,10 @@ for def in "$pats[@]"; do pat="${${sdef%%:${tag}*}//\\:/:}" if [[ "$sdef" = *:${tag}:* ]]; then + # If the file-patterns spec includes a description, use it and give the + # group/description options from it precedence over passed in parameters. descr="${(Q)sdef#*:${tag}:}" + end= else if (( $opts[(I)-X] )); then descr= @@ -108,26 +111,30 @@ for def in "$pats[@]"; do while _next_label "$tag" expl "$descr"; do _comp_ignore=( $_comp_ignore $ign ) if [[ -n "$end" ]]; then - if _path_files -g "$pat" "$opts[@]" "$expl[@]"; then - ret=0 - elif [[ $PREFIX$SUFFIX != */* ]] && zstyle -a ":completion:${curcontext}:$tag" recursive-files rfiles; then - for rfile in $rfiles; do - if [[ $PWD/ = ${~rfile} ]]; then - if [[ -z $subtree ]]; then - subtree=( **/*(/) ) - fi - for prepath in $subtree; do - oprefix=$PREFIX - PREFIX=$prepath/$PREFIX - _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 - PREFIX=$oprefix - done - break - fi - done - fi + expl=( "$opts[@]" "$expl[@]" ) else - _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0 + expl+=( "$opts[@]" ) + fi + + if _path_files -g "$pat" "$expl[@]"; then + ret=0 + elif [[ $PREFIX$SUFFIX != */* ]] && \ + zstyle -a ":completion:${curcontext}:$tag" recursive-files rfiles + then + for rfile in $rfiles; do + if [[ $PWD/ = ${~rfile} ]]; then + if [[ -z $subtree ]]; then + subtree=( **/*(/) ) + fi + for prepath in $subtree; do + oprefix=$PREFIX + PREFIX=$prepath/$PREFIX + _path_files -g "$pat" "$expl[@]" && ret=0 + PREFIX=$oprefix + done + break + fi + done fi done (( ret )) || break diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index a8beece2d..1adceb536 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -1524,9 +1524,10 @@ If no `tt(:)var(tag)' is given the `tt(files)' tag will be used. The var(tag) may also be followed by an optional second colon and a description, which will be used for the `tt(%d)' in the value of the tt(format) style (if that is set) instead of the default -description supplied by the completion function. If the description -given here contains itself a `tt(%d)', that is replaced with the -description supplied by the completion function. +description supplied by the completion function. The inclusion +of a description also gives precedence to associated options such as +for completion grouping so it can be used where files should be +separated. For example, to make the tt(rm) command first complete only names of object files and then the names of all files if there is no matching @@ -1548,6 +1549,15 @@ all files using the pattern `tt(*)' at the first step and stops when it sees this pattern. Note also it will never try a pattern more than once for a single completion attempt. +To separate directories into a separate group from the files but still +complete them at the first attempt, a description needs to be given. +Note that directories need to be explicitly excluded from the +globbed-files because `tt(*)' will match directories. For grouping, it +is also necessary to set the tt(group-name) style. + +example(zstyle ':completion:*' file-patterns \ + '%p+LPAR()^-/RPAR():globbed-files *(-/):directories:location') + During the execution of completion functions, the tt(EXTENDED_GLOB) option is in effect, so the characters `tt(#)', `tt(~)' and `tt(^)' have special meanings in the patterns. @@ -1971,9 +1981,10 @@ obtained by setting the style to an empty string (i.e. tt('')). ) kindex(list-dirs-first, completion style) item(tt(list-dirs-first))( -This is used by file completion. If set, directories to be completed -are listed separately from and before completion for other files, -regardless of tag ordering. +This is used by file completion and corresponds to a particular +setting of the tt(file-patterns) style. +If set, the default directories to be completed +are listed separately from and before completion for other files. ) kindex(list-grouped, completion style) item(tt(list-grouped))(