zsh-users
 help / color / mirror / code / Atom feed
* complete based on contents of another folder or folders?
@ 2011-08-07 10:21 TJ Luoma
  2011-08-07 17:40 ` Peter Stephenson
  2011-08-07 20:23 ` Bart Schaefer
  0 siblings, 2 replies; 5+ messages in thread
From: TJ Luoma @ 2011-08-07 10:21 UTC (permalink / raw)
  To: Zsh Users

I know almost nothing about Zsh's completion feature, other than it's
cool and I wish I took better advantage of it.

Here's are some of first things I'd like to do. I'm hoping that
someone might be able to explain this in a way that will allow me to
replicate this in other scenarios.

1)
"open -a [tab]" should offer "any file found in

/Applications/
/Applications/Microsoft Office 2011/
/Applications/Utilities/
/Applications/iWork '09/

which ends with '.app' and should not show the dirname (and doesn't
need to show the '.app' suffix, but that's not crucial).

(I assume that once completion is setup, 'open -a B[tab]' will only
offer apps which start with the letter "B")

I have to assume that someone has already invented this particular
'wheel' already.

2) Similarly

        get_app [tab]

should offer completions based on files found in
~/Dropbox/get_app/rcs/ with the following stipulations:

- I only want the part of the filename up until the first literal "."
(and each file has at least one ".")
- no filenames do NOT have spaces in them
- subfolders may exist, but should be ignored (same is true for files
which begin with '.')

Thanks!

TjL

ps - Is there an "intro-to-zsh-completion" (aka "completion for
dummies" ;-) somewhere?


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

* Re: complete based on contents of another folder or folders?
  2011-08-07 10:21 complete based on contents of another folder or folders? TJ Luoma
@ 2011-08-07 17:40 ` Peter Stephenson
  2011-08-07 20:23 ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2011-08-07 17:40 UTC (permalink / raw)
  To: Zsh Users

On Sun, 7 Aug 2011 06:21:49 -0400
TJ Luoma <luomat@gmail.com> wrote:
> I know almost nothing about Zsh's completion feature, other than it's
> cool and I wish I took better advantage of it.
> 
> Here's are some of first things I'd like to do. I'm hoping that
> someone might be able to explain this in a way that will allow me to
> replicate this in other scenarios.
> 
> 1)
> "open -a [tab]" should offer "any file found in
> 
> /Applications/
> /Applications/Microsoft Office 2011/
> /Applications/Utilities/
> /Applications/iWork '09/
> 
> which ends with '.app' and should not show the dirname (and doesn't
> need to show the '.app' suffix, but that's not crucial).

You want something like

_open() {          
  local -a app_path
  app_path=(/Applications/*(/))
  _path_files -W app_path -g '*.app'
}
compdef _open open
 
> 2) Similarly
> 
>         get_app [tab]
> 
> should offer completions based on files found in
> ~/Dropbox/get_app/rcs/ with the following stipulations:
> 
> - I only want the part of the filename up until the first literal "."
> (and each file has at least one ".")
> - no filenames do NOT have spaces in them
> - subfolders may exist, but should be ignored (same is true for files
> which begin with '.')

Probably easiest to use globbing in the completion function rather than
file completion.

_get_app() {
   local -a found
   local expl

   found=(~/Dropbox/get_app/rcs/*(.))
   found=(${found%%.*})
   _wanted apps expl 'app' compadd -a found
}

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: complete based on contents of another folder or folders?
  2011-08-07 10:21 complete based on contents of another folder or folders? TJ Luoma
  2011-08-07 17:40 ` Peter Stephenson
@ 2011-08-07 20:23 ` Bart Schaefer
  2011-08-08 12:54   ` TJ Luoma
  2011-08-08 14:34   ` TJ Luoma
  1 sibling, 2 replies; 5+ messages in thread
From: Bart Schaefer @ 2011-08-07 20:23 UTC (permalink / raw)
  To: Zsh Users

I'm sending this even though PWS already answered, because it takes
a somewhat different tack on the question, and I'd already written most
of it ...

On Aug 7,  6:21am, TJ Luoma wrote:
} 
} ps - Is there an "intro-to-zsh-completion" (aka "completion for
} dummies" ;-) somewhere?

http://zsh.sourceforge.net/Guide/zshguide06.html#l144 perhaps?  You
probably want specifically to read the section on "new" completion.

} 1)
} "open -a [tab]" should offer "any file found in
} [...] 
} which ends with '.app' and should not show the dirname (and doesn't
} need to show the '.app' suffix, but that's not crucial).

This should already be handled for you if you have enabled "new"
completion with the "compinit" function in your startup files.

There's an entire subtree Completion/Darwin/ in the zsh sources that
has MacOS X functions.  Completion/Darwin/Type/_retrieve_mac_apps is
used to populate the list of applications for most Darwin completers.
It uses Spotlight to find all the .app files that "open" might call.

Of course this might not help much with providing an example of how
to write such a completer yourself.  (See PWS's example.)

} (I assume that once completion is setup, 'open -a B[tab]' will only
} offer apps which start with the letter "B")

Yep.

} 2) Similarly
} 
}         get_app [tab]
} 
} should offer completions based on files found in
} ~/Dropbox/get_app/rcs/ with the following stipulations:

This doesn't exist by default so it's probably a better example.  Let's
build it up, starting with "based on files":

    compdef _files get_app

"found in ~/Dropbox/get_app/rcs/":

    compdef "_files -W ~/Dropbox/get_app/rcs/" get_app

} - no filenames do NOT have spaces in them

I'm not sure what that means.  "All filenames DO have spaces" perhaps?
In any case this shouldn't matter, completion will take care of doing
quoting.

} - subfolders may exist, but should be ignored (same is true for files
} which begin with '.')

Files beginning with "." are ignored by default, as with globbing,
unless you explicitly have a leading dot on the word you complete.

To exclude subfolders, you have to add a completion style that only
matches files:

    zstyle ':completion::complete:get_app::*' file-patterns '*(.)'

There is a similar option for the _files completer --

    compdef "_files -g '*(.)' -W ~/Dropbox/get_app/rcs/" get_app

-- but it doesn't work the same way; it applies at any point in the
folder hierarchy, whereas the file-patterns style will determine if
the subfolder is considered at all.  There is a useful side-effect
of the -g option which is that files matching the pattern are placed
in a separate "completion group" from directory names, so files are
completed first and directories appear only when you've exhausted all
possible files.  You may find you prefer that to omitting them.

} - I only want the part of the filename up until the first literal "."
} (and each file has at least one ".")

At this point you've gone beyond what can be done with configurations
of the existing completions, because omitting part of the matching
name (as opposed to the leading path) is a special condition that's
not generally passed through all the layers of helper functions.

(If you wanted to remove specific substrings like ".jpg" it could be
done with a matcher-list zstyle, but I don't believe there's any way
to configure a matcher-list for "anything following a dot".)

As in PWS's example, it's usual to start by defining a function using
the command name preceded by an underscore.  I suggest only a single
improvement to PWS's function, which is to apply :t to the $found glob
to get the effect of the -W option in removing the leading path.

  _get_app() {
    local -a found
    local expl

    found=(~/Dropbox/get_app/rcs/*(.:t))
    found=(${found%%.*})
    _wanted apps expl 'app' compadd -a found
  }

Then of course you also need:

  compdef _get_app get_app

You can get this automatically by placing in your $fpath a file named
_get_app that looks like this (remove the "snip" lines obviously):

-- 8< -- snip -- 8< --
#compdef get_app
local -a found
local expl

found=(~/Dropbox/get_app/rcs/*(.:t))
found=(${found%%.*})
_wanted apps expl 'app' compadd -a found
-- 8< -- snip -- 8< --


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

* Re: complete based on contents of another folder or folders?
  2011-08-07 20:23 ` Bart Schaefer
@ 2011-08-08 12:54   ` TJ Luoma
  2011-08-08 14:34   ` TJ Luoma
  1 sibling, 0 replies; 5+ messages in thread
From: TJ Luoma @ 2011-08-08 12:54 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Sun, Aug 7, 2011 at 4:23 PM, Bart Schaefer <schaefer@brasslantern.com> wrote:
> I'm sending this even though PWS already answered, because it takes
> a somewhat different tack on the question, and I'd already written most
> of it ...

Thanks to you both. Having more than one way to do it is helpful as I
try to learn.

I've bookmarked these both until I have a chance to actually play with
this "live" but you've given me a lot to go on.

Thanks!

TjL


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

* Re: complete based on contents of another folder or folders?
  2011-08-07 20:23 ` Bart Schaefer
  2011-08-08 12:54   ` TJ Luoma
@ 2011-08-08 14:34   ` TJ Luoma
  1 sibling, 0 replies; 5+ messages in thread
From: TJ Luoma @ 2011-08-08 14:34 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Sun, Aug 7, 2011 at 4:23 PM, Bart Schaefer <schaefer@brasslantern.com> wrote:

> } - no filenames do NOT have spaces in them
>
> I'm not sure what that means.  "All filenames DO have spaces" perhaps?
> In any case this shouldn't matter, completion will take care of doing
> quoting.

(It means I'm a moron.)

I conflated "no filenames have spaces" and "filenames do NOT have
spaces" and created a double negative which said exactly the opposite
of what I was trying to say.



> } - I only want the part of the filename up until the first literal "."
> } (and each file has at least one ".")
>
> At this point you've gone beyond what can be done with configurations
> of the existing completions, because omitting part of the matching
> name (as opposed to the leading path) is a special condition that's
> not generally passed through all the layers of helper functions.
>
> (If you wanted to remove specific substrings like ".jpg" it could be
> done with a matcher-list zstyle, but I don't believe there's any way
> to configure a matcher-list for "anything following a dot".)

Actually the files do all have the same "suffix" but in this instance
I can just rename the files by removing everything after the dot,
which was superfluous information anyway.

Thanks again.

TjL


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

end of thread, other threads:[~2011-08-08 14:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-07 10:21 complete based on contents of another folder or folders? TJ Luoma
2011-08-07 17:40 ` Peter Stephenson
2011-08-07 20:23 ` Bart Schaefer
2011-08-08 12:54   ` TJ Luoma
2011-08-08 14:34   ` TJ Luoma

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).