zsh-users
 help / color / mirror / Atom feed
* detect if command has a completion function
       [not found] <301108111.164161.1598719628682.ref@mail.yahoo.com>
@ 2020-08-29 16:47 ` vapnik spaknik
  2020-08-29 17:21   ` Marc Cornellà
                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: vapnik spaknik @ 2020-08-29 16:47 UTC (permalink / raw)
  To: Zsh Users

Hi,
    how can I detect if a given command has a completion function, from within another function?
I want to loop over many commands quickly, so I want to avoid resorting to searching directories with find if possible.

The reason I need this capability is to help with a function I've written for cleaning up .zshrc files.
I tend to collect lots of "compdef _gnu_generic cmd1 cmd2..." lines in my .zshrc, but many of the commands flagged for completion with _gnu_generic are not present on other systems where I install the same .zshrc. I wrote a function which checks the commands mentioned in those "compdef _gnu_generic" lines, and removes any that are not present on the system:

function cleanup-compdefs() {
    local okcmds=() numcols=120
    for cmd in ${(i)$(grep -e "^compdef _gnu_generic" ~/.zshrc|sed 's/compdef _gnu_generic//')}; do
	if which ${cmd} &>/dev/null; then
	    okcmds+="$(basename ${cmd})"
	fi
    done
    local line i=1
    while [[ ${i} -le ${#okcmds} ]]; do
	line="compdef _gnu_generic"
	while [[ ${#line} -lt ${numcols} ]]; do
	    line+=" ${okcmds[${i}]}"
	    i=$((${i} + 1))
	done
	echo "${line}"
    done
}

However, I also want it to check which of the commands already have completion functions defined, so that they can also be removed.
Can anyone help?



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: detect if command has a completion function
  2020-08-29 16:47 ` detect if command has a completion function vapnik spaknik
@ 2020-08-29 17:21   ` Marc Cornellà
       [not found]   ` <AM6PR02MB56389D8F9832FA6C58D8EF6E84530@AM6PR02MB5638.eurprd02.prod.outlook.com>
  2020-08-29 18:33   ` Bart Schaefer
  2 siblings, 0 replies; 5+ messages in thread
From: Marc Cornellà @ 2020-08-29 17:21 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: Zsh Users

>     how can I detect if a given command has a completion function, from within another function?
> I want to loop over many commands quickly, so I want to avoid resorting to searching directories with find if possible.
>
> The reason I need this capability is to help with a function I've written for cleaning up .zshrc files.
> I tend to collect lots of "compdef _gnu_generic cmd1 cmd2..." lines in my .zshrc, but many of the commands flagged for completion with _gnu_generic are not present on other systems where I install the same .zshrc.

You can use the `$_comps` array which controls which completion
function is assigned to a command.
For example, the completion function for `ls` is `_ls`:

  $ echo $_comps[ls]
  _ls

And so on

Marc


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: detect if command has a completion function
       [not found]   ` <AM6PR02MB56389D8F9832FA6C58D8EF6E84530@AM6PR02MB5638.eurprd02.prod.outlook.com>
@ 2020-08-29 17:38     ` vapnik spaknik
  0 siblings, 0 replies; 5+ messages in thread
From: vapnik spaknik @ 2020-08-29 17:38 UTC (permalink / raw)
  To: Marc Cornellà; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 334 bytes --]

 

>On Saturday, August 29, 2020, 06:21:21 PM GMT+1, Marc Cornellà <marc.cornella@live.com> wrote:
>
>You can use the `$_comps` array which controls which completion
>function is assigned to a command.
>For example, the completion function for `ls` is `_ls`:
>
>  $ echo $_comps[ls]
>
>  _ls

Perfect, thankyou!


  

[-- Attachment #2: Type: text/html, Size: 445 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: detect if command has a completion function
  2020-08-29 16:47 ` detect if command has a completion function vapnik spaknik
  2020-08-29 17:21   ` Marc Cornellà
       [not found]   ` <AM6PR02MB56389D8F9832FA6C58D8EF6E84530@AM6PR02MB5638.eurprd02.prod.outlook.com>
@ 2020-08-29 18:33   ` Bart Schaefer
  2020-08-29 19:27     ` Bart Schaefer
  2 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2020-08-29 18:33 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: Zsh Users

On Sat, Aug 29, 2020 at 9:47 AM vapnik spaknik <vapniks@yahoo.com> wrote:
>
> The reason I need this capability is to help with a function I've written for cleaning up .zshrc files.
> ... I wrote a function which checks the commands mentioned in those "compdef _gnu_generic" lines, and removes any that are not present on the system:

Don't bother removing the compdef lines, just remove their results.
That way you won't have to add things back again if you install one of
those missing programs.

completed=( ${(k)_comps:#([^[:alnum:]]*)} )
installed=( ${(k)builtins} ${(k)functions} ${(k)commands} )
not_installed=( ${completed:|installed} )
unset '_comps['${^not_installed}']'

Just be sure you have done all your zmodloads and autoloads before
executing the above, or you'll remove completions for some builtins
and functions.

Older zsh will not have the ${name:|arrayname} syntax so you might
have to resort to

not_installed=( ${completed:#${~:-(${(j:|:)${(q)installed}})}} )


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: detect if command has a completion function
  2020-08-29 18:33   ` Bart Schaefer
@ 2020-08-29 19:27     ` Bart Schaefer
  0 siblings, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2020-08-29 19:27 UTC (permalink / raw)
  To: Zsh Users

On Sat, Aug 29, 2020 at 11:33 AM Bart Schaefer
<schaefer@brasslantern.com> wrote:
>
>  Don't bother removing the compdef lines, just remove their results.

This could be taken a step further:

all_comps=( ${(v)_comps} )
completed=( ${(k)_comps:#-*} )
installed=( ${(k)builtins} ${(k)functions} ${(k)commands} )
not_installed=( ${completed:|installed} )
unset '_comps['${^not_installed}']'
used_comps=( ${(v)_comps} )
unused_comps=( ${all_comps:|used_comps} )
unfunction ${(k)functions:*unused_comps}

(Note the tweak to completed=(...), I think -* covers what needs ignoring.)


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-08-29 19:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <301108111.164161.1598719628682.ref@mail.yahoo.com>
2020-08-29 16:47 ` detect if command has a completion function vapnik spaknik
2020-08-29 17:21   ` Marc Cornellà
     [not found]   ` <AM6PR02MB56389D8F9832FA6C58D8EF6E84530@AM6PR02MB5638.eurprd02.prod.outlook.com>
2020-08-29 17:38     ` vapnik spaknik
2020-08-29 18:33   ` Bart Schaefer
2020-08-29 19:27     ` Bart Schaefer

zsh-users

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.vuxu.org/zsh-users

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 zsh-users zsh-users/ http://inbox.vuxu.org/zsh-users \
		zsh-users@zsh.org
	public-inbox-index zsh-users

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.users


code repositories for the project(s) associated with this inbox:

	https://git.vuxu.org/mirror/zsh/

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git