zsh-users
 help / color / mirror / code / Atom feed
* dsf
@ 2013-01-07 10:01 Daniel
  2013-01-08  9:41 ` completer that first expands global aliases (Re: dsf) Daniel
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel @ 2013-01-07 10:01 UTC (permalink / raw)
  To: zsh-users

I have a nice little recent-files completer, see below.
(found here: http://michael.stapelberg.de/Artikel/zsh_recent_completion )

What I would like to add to this, is for it to expand global aliases inline,
before trying to complete (and thus ending up completing files in my aliased
directory).

I started trying to meld _generic and _expand_alias, but with my lack of
fluency in zsh, I just made a mess :) Any help out there? Is there perhaps some
generic way for having this done for all completion? A zstyle for
_main_complete?


# 'ctrl-x r' will complete the 12 last modified (mtime) files/directories
zle -C newest-files complete-word _generic
bindkey '^Xr' newest-files
zstyle ':completion:newest-files:*' completer _files
zstyle ':completion:newest-files:*' file-patterns '*~.*(omN[1,12])'
zstyle ':completion:newest-files:*' menu select yes
zstyle ':completion:newest-files:*' sort false
zstyle ':completion:newest-files:*' matcher-list 'b:=*' # important


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

* completer that first expands global aliases  (Re: dsf)
  2013-01-07 10:01 dsf Daniel
@ 2013-01-08  9:41 ` Daniel
  2013-01-08  9:58   ` Peter Stephenson
  2013-01-08 13:06   ` Oliver Kiddle
  0 siblings, 2 replies; 10+ messages in thread
From: Daniel @ 2013-01-08  9:41 UTC (permalink / raw)
  To: zsh-users

Sorry for the random subject there, didn't mean to scary anybody away :)

On 2013-01-07, Daniel <quite@hack.org> wrote:
> I have a nice little recent-files completer, see below.
> (found here: http://michael.stapelberg.de/Artikel/zsh_recent_completion )
>
> What I would like to add to this, is for it to expand global aliases inline,
> before trying to complete (and thus ending up completing files in my aliased
> directory).
>
> I started trying to meld _generic and _expand_alias, but with my lack of
> fluency in zsh, I just made a mess :) Any help out there? Is there perhaps some
> generic way for having this done for all completion? A zstyle for
> _main_complete?
>
>
> # 'ctrl-x r' will complete the 12 last modified (mtime) files/directories
> zle -C newest-files complete-word _generic
> bindkey '^Xr' newest-files
> zstyle ':completion:newest-files:*' completer _files
> zstyle ':completion:newest-files:*' file-patterns '*~.*(omN[1,12])'
> zstyle ':completion:newest-files:*' menu select yes
> zstyle ':completion:newest-files:*' sort false
> zstyle ':completion:newest-files:*' matcher-list 'b:=*' # important



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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-08  9:41 ` completer that first expands global aliases (Re: dsf) Daniel
@ 2013-01-08  9:58   ` Peter Stephenson
  2013-01-08 13:06   ` Oliver Kiddle
  1 sibling, 0 replies; 10+ messages in thread
From: Peter Stephenson @ 2013-01-08  9:58 UTC (permalink / raw)
  To: zsh-users

On Tue, 08 Jan 2013 09:41:55 +0000 (UTC)
Daniel <quite@hack.org> wrote:
> On 2013-01-07, Daniel <quite@hack.org> wrote:
> > I have a nice little recent-files completer, see below.
> > (found here:
> > http://michael.stapelberg.de/Artikel/zsh_recent_completion )
> >
> > What I would like to add to this, is for it to expand global
> > aliases inline, before trying to complete (and thus ending up
> > completing files in my aliased directory).
> >
> > I started trying to meld _generic and _expand_alias, but with my
> > lack of fluency in zsh, I just made a mess :) Any help out there?
> > Is there perhaps some generic way for having this done for all
> > completion? A zstyle for _main_complete?

I can't see a straightforward way of doing this; it looks like it needs
some complicated rewriting of _expand_alias into some other function, as
you were trying.

It might be possible to rig up something at a higher level (probably ZLE
widgets rather than completion) to call _expand_alias, ensuring it
accepts the result with all expansions, then call the generic completion
you want, but I haven't thought that through.

pws


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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-08  9:41 ` completer that first expands global aliases (Re: dsf) Daniel
  2013-01-08  9:58   ` Peter Stephenson
@ 2013-01-08 13:06   ` Oliver Kiddle
  2013-01-08 17:01     ` Daniel
  1 sibling, 1 reply; 10+ messages in thread
From: Oliver Kiddle @ 2013-01-08 13:06 UTC (permalink / raw)
  To: Daniel, zsh-users

Daniel wrote:
> I have a nice little recent-files completer, see below.
> (found here: http://michael.stapelberg.de/Artikel/zsh_recent_completion )
> 
> What I would like to add to this, is for it to expand global aliases inline,
> before trying to complete (and thus ending up completing files in my aliased
> directory).
> 
> I started trying to meld _generic and _expand_alias, but with my lack of
> fluency in zsh, I just made a mess :) Any help out there? Is there perhaps some

> zstyle ':completion:newest-files:*' completer _files

You can insert _expand_alias before _files in the list of completer
functions. I'm not sure if that works in the way you want: a global
alias will simply be expanded. If you tried that and it didn't work then
I would suspect that your default completer style is getting precedence
over this one. Try using more colons instead of a *:

zstyle ':completion:newest-files::::' completer _expand_alias _files

If this doesn't behave in the way you would like, perhaps give us some
examples of your global aliases and what you behaviour you would like.

> zstyle ':completion:newest-files:*' file-patterns '*~.*(omN[1,12])'
> zstyle ':completion:newest-files:*' menu select yes
> zstyle ':completion:newest-files:*' sort false
> zstyle ':completion:newest-files:*' matcher-list 'b:=*' # important

I do this in a somewhat different way. The comment on the last line
isn't particularly helpful. It makes matching use substrings so for
example typing
  ls pdf<Ctrl-X>r
will match *pdf* in order of file modification. Note that matching is
done after the globbing so if you have more than 12 newer files than any
of the matching ones, you won't get anything.

I use _match instead so if I want the most recent PDF file, I complete
after *.pdf. I also need the match-original style set for that to work.

I can't think of a different way to limit the number of matches to 12. I
simply turn off completion listing for the widget and it is rare that I
need to cycle through more than a couple of matches. This also has the
advantage that you can invoke reverse-menu-complete to get the oldest
file (which is sometimes useful).

I use the following:
  zstyle ':completion:most-recent-*::::' completer _menu _files _match
  zstyle ':completion:most-recent-*:*' file-sort modification
  zstyle ':completion:most-recent-*:*' hidden all
  zstyle ':completion:(match-word|most-recent-*):*' match-original both
  zstyle ':completion:most-recent-file:*' file-patterns '*(.):normal\ files'
  zstyle ':completion:most-recent-dir:*' file-patterns '*(/):directories'
  bindkey '^Xm' most-recent-file
  bindkey '^XM' most-recent-dir
  zle -C most-recent-file menu-complete _generic
  zle -C most-recent-dir menu-complete _generic

Note that I have a separate widget for directories. You may also want to
experiment with using _complete instead of _files to make it more
intelligent, at least in theory:
  zstyle ':completion:most-recent-*::::' completer _menu _complete _match
  zstyle ':completion:most-recent-file:*' file-patterns '%p(N):globbed-files'

Oliver



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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-08 13:06   ` Oliver Kiddle
@ 2013-01-08 17:01     ` Daniel
  2013-01-08 18:24       ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel @ 2013-01-08 17:01 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: zsh-users


Thanks for your time, this is all a bit above me, and perhaps I should learn
more about zle and all to deserve the fancy and particular things I want...

> You can insert _expand_alias before _files in the list of completer
> functions. I'm not sure if that works in the way you want: a global
> alias will simply be expanded. If you tried that and it didn't work then
> I would suspect that your default completer style is getting precedence
> over this one. Try using more colons instead of a *:

Yes, it just expands the global alias, and then quits (?!). I would like it to
first expand, and then proceed with matching, or whatever it should do.

I have a couple of global aliases for directories:

  alias -g DL="~/dl/"

I tried out your most-recent-* and it seems fine and more robust. I can't get
it to work the way I want though. 

>   zstyle ':completion:most-recent-*::::' completer _menu _complete _match

If I add the _expand_alias like below, hitting ^Xm gives the expansion with a
trailing space. And nothing more happens. The hash is the cursor position:

  zstyle ':completion:most-recent-*::::' completer _expand_alias _menu _complete _match

  $ cat ~/dl/ #    

And if I add it after _menu, I get the expansion without a trailing space.
Hitting ^Xm again then sure enough gives me the newest file in "DL".

  zstyle ':completion:most-recent-*::::' completer _menu _expand_alias _complete _match

  $ cat ~/dl/#

Maybe the problem is related to alias expansion being inherently based on
words, and will typically expand with a trailing space. Is these directory
shortcuts I want a reasonable use of global aliases, or do I want something
else...?


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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-08 17:01     ` Daniel
@ 2013-01-08 18:24       ` Bart Schaefer
  2013-01-08 21:29         ` Daniel
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2013-01-08 18:24 UTC (permalink / raw)
  To: zsh-users

On Jan 8,  6:01pm, Daniel wrote:
}
} If I add the _expand_alias like below, hitting ^Xm gives the expansion with a
} trailing space. And nothing more happens. The hash is the cursor position:
} 
}   zstyle ':completion:most-recent-*::::' completer _expand_alias _menu _complete _match
} 
}   $ cat ~/dl/ #    

The problem here is that the completer style tries each function in the
list until it finds one that succeeds (returns 0) at which point it
stops.  So you need _expand_alias to "fail" (return nonzero).

You can hack this by using a little wrapper function:

    _expand_alias_hack() {
      _expand_alias "$@"
      return 1
    }
    zstyle ':completion:most-recent-*::::' completer \
    	_expand_alias_hack _menu _complete _match

However, a cleaner way to do it would be to use the compprefuncs array.
This documentation for this is rather minimal; it's mostly used by the
_next_tags widget to force completion to walk through the tags array.
However, you can use it for oether completers as well.

In this case, you can either create a new widget for the most-recent-*
completion and assign to compprefuncs in the widget, or you can embed it
in the completer style definition by using the -e option:

    zstyle -e ':completion:most-recent-*::::' completer \
	'compprefuncs=(_expand_alias) reply=(_menu _complete _match)'

Note the quoting, it's important.

-- 
Barton E. Schaefer


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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-08 18:24       ` Bart Schaefer
@ 2013-01-08 21:29         ` Daniel
  2013-01-09  4:40           ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel @ 2013-01-08 21:29 UTC (permalink / raw)
  To: zsh-users

> In this case, you can either create a new widget for the most-recent-*
> completion and assign to compprefuncs in the widget, or you can embed it
> in the completer style definition by using the -e option:
>
>     zstyle -e ':completion:most-recent-*::::' completer \
> 	'compprefuncs=(_expand_alias) reply=(_menu _complete _match)'

Ah, I understand how this is supposed to work; both your examples. Though,
neither of them does work. I have to press ^Xm twice, first to expand my DL,
and a second time to get a first file match.



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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-08 21:29         ` Daniel
@ 2013-01-09  4:40           ` Bart Schaefer
  2013-01-09  7:29             ` Daniel
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2013-01-09  4:40 UTC (permalink / raw)
  To: zsh-users

On Jan 8,  9:29pm, Daniel wrote:
} Subject: Re: completer that first expands global aliases  (Re: dsf)
}
} >     zstyle -e ':completion:most-recent-*::::' completer \
} > 	'compprefuncs=(_expand_alias) reply=(_menu _complete _match)'
} 
} Ah, I understand how this is supposed to work; both your examples. Though,
} neither of them does work. I have to press ^Xm twice, first to expand my DL,
} and a second time to get a first file match.

I think you're never going to get precisely the behavior you want, because
aliases have to be entire words.  For example, if without using completion
at all you gave the command

	ls DL*

the DL would not expand, so you would not see a listing of the files in
the ~/dl/ directory.  Completion is going to have the same issue; the
alias has to expand as a word of its own before zsh can discover that it
is a directory that can contain files to match.

I think what you really want is a named directory, although you still
have to type a leading tilde and trailing slash (e.g. ~DL/) to refer to
files within one.  With a named directory, completion should "just work"
without having to first expand the abbreviation to the path to which it
refers.

    % hash -d DL=~/dl
    % ls ~DL/<TAB>

Of course if your directory is really named "dl" that's not saving you
very much.

If that won't do, then the way to get the closest to what you want is
to write a widget that modifies the words array and updates $PREFIX
before calling the _main_complete function.  You may be able to do this
by cribbing from _expand_alias.


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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-09  4:40           ` Bart Schaefer
@ 2013-01-09  7:29             ` Daniel
  2013-01-09 16:05               ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel @ 2013-01-09  7:29 UTC (permalink / raw)
  To: zsh-users

On 2013-01-09, Bart Schaefer <schaefer@brasslantern.com> wrote:
> } >     zstyle -e ':completion:most-recent-*::::' completer \
> } > 	'compprefuncs=(_expand_alias) reply=(_menu _complete _match)'
> } 
> } Ah, I understand how this is supposed to work; both your examples. Though,
> } neither of them does work. I have to press ^Xm twice, first to expand my DL,
> } and a second time to get a first file match.

> I think you're never going to get precisely the behavior you want, because
> aliases have to be entire words.  For example, if without using completion
> at all you gave the command

I hear you. I had this gut feeling about aliases and words.

But what was your _expand_alias_hack returning non-0 and attempt with
compprefunc() supposed to do then?  I though they would manage to have the alias
expanded and then continue with completion.  But as I said, they stop short of
actually completing.  But the expansion is done, and does NOT leave any trailing
space/word boundary...


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

* Re: completer that first expands global aliases  (Re: dsf)
  2013-01-09  7:29             ` Daniel
@ 2013-01-09 16:05               ` Bart Schaefer
  0 siblings, 0 replies; 10+ messages in thread
From: Bart Schaefer @ 2013-01-09 16:05 UTC (permalink / raw)
  To: zsh-users

On Jan 9,  7:29am, Daniel wrote:
}
} But what was your _expand_alias_hack returning non-0 and attempt with
} compprefunc() supposed to do then? I though they would manage to have
} the alias expanded and then continue with completion. But as I said,
} they stop short of actually completing. But the expansion is done, and
} does NOT leave any trailing space/word boundary...

_expand_alias is a completion function, so it is changing the result of
completion, not the input to completion.  This means that the next step
(_menu or _complete, for example) still see the original input "DL" and
find no completions for it.

All that my hacks accomplish is to tell the shell that the expansion
step is not in itself a successful completion, so that it won't append
the the auto-suffix and leaves you able to continue completing with the
expansion in place.  I thought beforehand that the the compprefuncs one
might do a bit more, but it doesn't.

To accomplish what you want, you need to expand the alias before the
completion is invoked.  You can't do this within a single "zle -C"
widget without mucking around the values of words[CURRENT] and PREFIX,
and it may not always work even then.


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

end of thread, other threads:[~2013-01-09 16:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-07 10:01 dsf Daniel
2013-01-08  9:41 ` completer that first expands global aliases (Re: dsf) Daniel
2013-01-08  9:58   ` Peter Stephenson
2013-01-08 13:06   ` Oliver Kiddle
2013-01-08 17:01     ` Daniel
2013-01-08 18:24       ` Bart Schaefer
2013-01-08 21:29         ` Daniel
2013-01-09  4:40           ` Bart Schaefer
2013-01-09  7:29             ` Daniel
2013-01-09 16:05               ` Bart Schaefer

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).