zsh-users
 help / color / mirror / code / Atom feed
* widget special PREFIX variable and cursor position with complete_in_word
@ 2014-02-12 21:02 Yuri D'Elia
  2014-02-13  5:47 ` Bart Schaefer
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-12 21:02 UTC (permalink / raw)
  To: zsh-users

I was writing a zstyle widget, and wanted to use the variable PREFIX to
have the first part of the string before the cursor.

>From the docs:

      PREFIX Initially  this will be set to the part of the current word
from the beginning of the word
              up to the position of the cursor; it may be altered  to
give  a  common  prefix  for  all
              matches.

Without complete_in_word it works fine, PREFIX contains the word up to
the cursor indeed. However, with complete_in_word, the following:

$ ls //x<TAB>
dev/ etc/ lib/ sbin/

moves the cursor to the first slash (/):

$ ls //x
      ^
dev/ etc/ lib/ sbin/

In this case, PREFIX contains //x, and not '/' as I would expect.
Fine with that as long as I can know where the cursor is, but I was
looking into the $compstate hash and found nothing. I was hoping for
some offset.

Any help?


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-12 21:02 widget special PREFIX variable and cursor position with complete_in_word Yuri D'Elia
@ 2014-02-13  5:47 ` Bart Schaefer
  2014-02-13 13:38   ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Bart Schaefer @ 2014-02-13  5:47 UTC (permalink / raw)
  To: zsh-users

On Feb 12, 10:02pm, Yuri D'Elia wrote:
}
} I was writing a zstyle widget

I'm not understading what you mean by this.  Are you writing an actual
completion widget, or are you writing a function that will be used as
an argument to compdef, or are you writing a function whose name will
be used as the value of a zstyle?  If the last, which zstyle?

(By "an actual completion widget" I mean it's name will be the third
argument to a "zle -C" command.)

} Without complete_in_word it works fine, PREFIX contains the word up to
} the cursor indeed. However, with complete_in_word, the following:
} 
} $ ls //x<TAB>
} dev/ etc/ lib/ sbin/
} 
} moves the cursor to the first slash (/):
} 
} $ ls //x
}       ^
} dev/ etc/ lib/ sbin/
} 
} In this case, PREFIX contains //x, and not '/' as I would expect.

I'm going to guess that you mean you hit TAB a second time immediately
after the cursor is moved to that spot.

I believe you'll find that the behavior is different depending on
whether you have hit TAB twice in succession or whether you moved the
cursor there yourself before you hit TAB.

Whether what I'm about to describe is what happens may be changed by
some of the setopts and styles, but the default behavior is:

The first time you press TAB, if the result is ambiguous (in your
example, four possible results) a completion listing and the cursor
is moved to the first disambiguating location.  At this point you
have a choice:  Enter a character that will remove the ambiguity,
or hit TAB again to enter menu completion.

If you hit TAB again, the same completion that created the listing
is repeated in order to populate the menu.  If you were to replay it
in slow motion, you'd see the cursor return to the end of the word
before the completion is begun, and then jump back to the point of
disambiguation to insert the first choice from the menu.

Because the original completion is being repeated, PREFIX="//x" as
it was before.  You can detect this by examining $compstate[old_list].
The _oldlist completer takes explicit advantage of this behavior to
avoid calling all the other completers when a list has already been
created.

If instead you were to move the cursor yourself and press TAB, or
press TAB e TAB to explicitly select "etc", *then* the second tab
is beginning a brand new completion with a new PREFIX value.

} Fine with that as long as I can know where the cursor is, but I was
} looking into the $compstate hash and found nothing. I was hoping for
} some offset.

$CURSOR won't lie to you, but you'll find that it reflects what I
described above, i.e., that the cursor returns to the end of the word
before resuming the completion.


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-13  5:47 ` Bart Schaefer
@ 2014-02-13 13:38   ` Yuri D'Elia
  2014-02-13 17:25     ` Bart Schaefer
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-13 13:38 UTC (permalink / raw)
  To: zsh-users

On 02/13/2014 06:47 AM, Bart Schaefer wrote:
> I'm not understading what you mean by this.  Are you writing an actual
> completion widget, or are you writing a function that will be used as
> an argument to compdef, or are you writing a function whose name will
> be used as the value of a zstyle?  If the last, which zstyle?

I'm still refining the ability to highlight the first ambiguous character in a completion list, using the following styles:

hl_first_diff_color=4

hl-first-diff()
{
  reply=( "=(#b)${PREFIX:q}(?|)*==${hl_first_diff_color}" )
}

hl-first-diff-path()
{
  setopt local_options no_bad_pattern
  local expn="${PREFIX##*/}"
  reply=( "=(#b)${expn:q}(?|)*==${hl_first_diff_color}" )
}

zstyle -e ':completion:*' list-colors hl-first-diff
zstyle -e ':completion:*:all-files' list-colors hl-first-diff-path
zstyle -e ':completion:*:local-directories' list-colors hl-first diff-path
zstyle -e ':completion:*:directories' list-colors hl-first-diff-path
zstyle -e ':completion:*:commands' list-colors hl-first-diff-path

> The first time you press TAB, if the result is ambiguous (in your
> example, four possible results) a completion listing and the cursor
> is moved to the first disambiguating location.  At this point you

Yes, at this point I'm shown the completion list for the first ambiguous position, and I need to know the string up to the cursor location (not the entire argument), in order to match the ambiguous character in the list.

> $CURSOR won't lie to you, but you'll find that it reflects what I
> described above, i.e., that the cursor returns to the end of the word
> before resuming the completion.

Unfortunately :(



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-13 13:38   ` Yuri D'Elia
@ 2014-02-13 17:25     ` Bart Schaefer
  2014-02-13 18:12       ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Bart Schaefer @ 2014-02-13 17:25 UTC (permalink / raw)
  To: zsh-users

On Feb 13,  2:38pm, Yuri D'Elia wrote:
} Subject: Re: widget special PREFIX variable and cursor position with compl
}
} I'm still refining the ability to highlight the first ambiguous
} character in a completion list

Ah, thank you, that context is helpful.

} > The first time you press TAB, if the result is ambiguous (in your
} > example, four possible results) a completion listing and the cursor
} > is moved to the first disambiguating location.  At this point you
} 
} Yes, at this point I'm shown the completion list for the first
} ambiguous position, and I need to know the string up to the cursor
} location (not the entire argument), in order to match the ambiguous
} character in the list.

You want $compstate[unambiguous] and $compstate[unambiguous_cursor],
but you can't examine them until after the rest of completion is done
with its work -- perhaps by poking something into the $comppostfuncs
array (see the _all_matches completer for an example).

The string slice

   ${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}]}

should be the common prefix of all the entries in the listing but NOT
including any common characters that are SHOWN in the listing.  If you
want more details, ${(s/:/)compstate[unambiguous_positions]} gives
the offsets into $compstate[unambiguous] that divide it into segments
that would be kept unchanged when updating the command line.


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-13 17:25     ` Bart Schaefer
@ 2014-02-13 18:12       ` Yuri D'Elia
  2014-02-14  6:34         ` Bart Schaefer
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-13 18:12 UTC (permalink / raw)
  To: zsh-users

On 02/13/2014 06:25 PM, Bart Schaefer wrote:
> } Yes, at this point I'm shown the completion list for the first
> } ambiguous position, and I need to know the string up to the cursor
> } location (not the entire argument), in order to match the ambiguous
> } character in the list.
> 
> You want $compstate[unambiguous] and $compstate[unambiguous_cursor],
> but you can't examine them until after the rest of completion is done
> with its work -- perhaps by poking something into the $comppostfuncs
> array (see the _all_matches completer for an example).

Indeed, I was already looking at $compstate[unambiguous], but it's not
yet set for my purposes.

Even after reading the _all_matches example, I'm not sure I follow you
about using comppostfuncs. It would still be called too late for my
purposes.



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-13 18:12       ` Yuri D'Elia
@ 2014-02-14  6:34         ` Bart Schaefer
  2014-02-14 11:56           ` Oliver Kiddle
  0 siblings, 1 reply; 25+ messages in thread
From: Bart Schaefer @ 2014-02-14  6:34 UTC (permalink / raw)
  To: zsh-users

On Feb 13,  7:12pm, Yuri D'Elia wrote:
}
} Even after reading the _all_matches example, I'm not sure I follow you
} about using comppostfuncs. It would still be called too late for my
} purposes.

Indeed, I forgot how early in the process _setup gets called, and that
is the only place the list-colors style is examined.

At the end of _complete, the color styles will all have been loaded
into the array $_comp_colors, and $compstate will have the values you
need.  So I think your best bet is to create a wrapper function that
calls _complete and then updates the $_comp_colors array, and finally
returns whatever the exit status _complete was.

To populate $_comp_colors you need to have SOME relevant list-colors
style set.  Perhaps the examples you gave except without the -e flag.

If you do that and you also have the recommended

    zstyle ':completion:*' group-name ''
    
style set, then each element of $_comp_colors will look like e.g.

    (argument-rest)hl-first-diff
or
    (all-files)hl-first-diff-path

where "(tag)" is missing for the defaults.  You'll need to walk over
the array, call each function, and substitute its $reply value into
the corresponding element.

_color_complete() {
  _complete
  local ret=$?
  # ... fix up $_comp_colors ...
  return ret
}

Or some similar creative hack of your own ...


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-14  6:34         ` Bart Schaefer
@ 2014-02-14 11:56           ` Oliver Kiddle
  2014-02-14 12:56             ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-14 11:56 UTC (permalink / raw)
  To: zsh-users

Bart wrote:
> Indeed, I forgot how early in the process _setup gets called, and that
> is the only place the list-colors style is examined.

_setup is too early for PREFIX/IPREFIX to have meaningful values. For
file completion (or for a simpler example, anything using _multi_parts),
the description is set once, not for each directory component.

list-colors is just stuffing things in ZLS_COLORS so I think it is
better to bypass it and set ZLS_COLORS ourself. To really get the right
prefixes, you need some trick overriding compadd but I think it is
easier to try to do things in a comppostfunc as you suggested before.

The pattern in ZLS_COLORS is matched against the display string. With
matching control etc, this really may not correspond to the actual
matches all that closely. So this is never going to be perfect.

The completer I've put below, turns an unambiguous string such as ./te
into (((.|)/|)t|)e and matches as much of that as possible on the
beginning of the match display string. So with file completion and a
file named test, the 'te' would match that pattern, ./ is missing from
the display string and the s gets underlined. You can easily contrive
ways to break that but the result seems to work reasonably in my very
limited testing.

You could include the last character (e in the example above) in the
pattern but it seems fairly pointless to highlight the first character
in matches. I've also not put any thought into the affect of various
configurable options, ZLS_COLORS being empty before the ..-end()
function, exactly where in the completer list it should go, etc. I
think ignored suffixes are harmless as we only match against the
beginning of the display string. There are also other options like using
zle_highlight to mark $compstate[insert_positions] on the command-line.

Oliver

#autoload

_show_ambiguity() {
  (( $comppostfuncs[(I)_show_ambiguity_end] )) ||
      comppostfuncs+=( _show_ambiguity_end )
  return 1
}

_show_ambiguity_end(){
  local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]}
  [[ -n $prefix ]] && \
    ZLS_COLORS+=":=${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/$MATCH:q|)}$prefix[-1](#b)(?|)*==4"
}

_show_ambiguity "$@"


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-14 11:56           ` Oliver Kiddle
@ 2014-02-14 12:56             ` Yuri D'Elia
  2014-02-14 14:39               ` Oliver Kiddle
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-14 12:56 UTC (permalink / raw)
  To: zsh-users

On 02/14/2014 12:56 PM, Oliver Kiddle wrote:
> The completer I've put below, turns an unambiguous string such as ./te
> into (((.|)/|)t|)e and matches as much of that as possible on the
> beginning of the match display string. So with file completion and a
> file named test, the 'te' would match that pattern, ./ is missing from
> the display string and the s gets underlined. You can easily contrive
> ways to break that but the result seems to work reasonably in my very
> limited testing.

Where would be the correct place to hook this completer to work for all
completitions (not only file names)?



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-14 12:56             ` Yuri D'Elia
@ 2014-02-14 14:39               ` Oliver Kiddle
  2014-02-14 15:38                 ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-14 14:39 UTC (permalink / raw)
  To: zsh-users

Yuri D'Elia wrote:
> Where would be the correct place to hook this completer to work for all
> completitions (not only file names)?

Include it in the 'completer' style:

zstyle ':completion:*::::' completer _show_ambiguity _complete

You'll have this style set already, probably with a long list of
functions such as _expand, _approximate, _prefix etc. It needs to appear
early in the list.

Oliver


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-14 14:39               ` Oliver Kiddle
@ 2014-02-14 15:38                 ` Yuri D'Elia
  2014-02-14 21:36                   ` Oliver Kiddle
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-14 15:38 UTC (permalink / raw)
  To: zsh-users

On 02/14/2014 03:39 PM, Oliver Kiddle wrote:
> Yuri D'Elia wrote:
>> Where would be the correct place to hook this completer to work for all
>> completitions (not only file names)?
> 
> Include it in the 'completer' style:
> 
> zstyle ':completion:*::::' completer _show_ambiguity _complete
> 
> You'll have this style set already, probably with a long list of
> functions such as _expand, _approximate, _prefix etc. It needs to appear
> early in the list.

I wasn't sure before, but it doesn't seem to work for me.
I see the function being called and ZLS_COLORS being set, but no
colorization happens.



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-14 15:38                 ` Yuri D'Elia
@ 2014-02-14 21:36                   ` Oliver Kiddle
  2014-02-17 11:10                     ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-14 21:36 UTC (permalink / raw)
  To: zsh-users

Yuri D'Elia wrote:
> I wasn't sure before, but it doesn't seem to work for me.
> I see the function being called and ZLS_COLORS being set, but no
> colorization happens.

That's odd. Perhaps something in your setup conflicts with it. It'd be
interesting to know what.

I've just tried and it works for me starting from zsh -f:
  zsh -f
  zmodload zsh/complist
  autoload -U compinit
  fpath+=( /path/where/you've/put/the/function )
  zstyle ':completion:*::::' completer _show_ambiguity _complete
  compinit

  setopt noh<tab>

Do those steps work for you?

It isn't going to help if it doesn't work but I forgot the :q for
the last character of the prefix and it seems to be worth making the
pattern case-insensitive with (#i) as case-insensitive completion
matching is common:
ZLS_COLORS+=":=(#i)${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/$MATCH:q|)}${prefix[-1]:q}(#b)(?|)*==4"

Oliver


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-14 21:36                   ` Oliver Kiddle
@ 2014-02-17 11:10                     ` Yuri D'Elia
  2014-02-17 13:28                       ` Yuri D'Elia
  2014-02-17 16:50                       ` Oliver Kiddle
  0 siblings, 2 replies; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-17 11:10 UTC (permalink / raw)
  To: zsh-users

On 02/14/2014 10:36 PM, Oliver Kiddle wrote:
> That's odd. Perhaps something in your setup conflicts with it. It'd be
> interesting to know what.

Ah yes, I was missing zsh/complist (setting the list-colors style was loading it automatically perhaps?)

I've refined a bit the _show_ambiguity_end function with what I already had:

_show_ambiguity_end()
{
  local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]:Q}
  if [ -n $prefix ]
  then
    [ "$curtag" = "all-files" ] && prefix=${prefix##*/} 
    ZLS_COLORS+=":=(#b)${prefix:q}(?|)*==4"
  fi
}

By also unquoting and checking for the 'all-files' tag, I can correctly match completions for (path)/files and quoted arguments.

I don't think the complex recursive match is needed at all.
I couldn't find any case that would require that. Do you have an example?

By stripping the directory, It now also works correctly for ambiguous matches such as:

$ ls //x

as I initially wanted.

Ahhh, lovely!!



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-17 11:10                     ` Yuri D'Elia
@ 2014-02-17 13:28                       ` Yuri D'Elia
  2014-02-17 16:50                       ` Oliver Kiddle
  1 sibling, 0 replies; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-17 13:28 UTC (permalink / raw)
  To: zsh-users

On 02/17/2014 12:10 PM, Yuri D'Elia wrote:
> On 02/14/2014 10:36 PM, Oliver Kiddle wrote:
>> That's odd. Perhaps something in your setup conflicts with it. It'd be
>> interesting to know what.
> 
> Ah yes, I was missing zsh/complist (setting the list-colors style was loading it automatically perhaps?)
> 
> I've refined a bit the _show_ambiguity_end function with what I already had:
> 
> _show_ambiguity_end()
> {
>   local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]:Q}
>   if [ -n $prefix ]
>   then
>     [ "$curtag" = "all-files" ] && prefix=${prefix##*/} 
>     ZLS_COLORS+=":=(#b)${prefix:q}(?|)*==4"
>   fi
> }

This is even more robust:

_show_ambiguity_end()
{
  local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]}
  if [ -n $prefix ]
  then
    [ ${compstate[quoting]} ] && prefix=${prefix[2,-1]} || prefix=${prefix:Q}
    [ "$curtag" = "all-files" ] && prefix=${prefix##*/}
    [ ${compstate[quoting]} ] || prefix=${prefix:q}
    ZLS_COLORS+=":=(#b)${prefix//?/?}(?|)*==4"
  fi
}

It actually works by matching the string length instead.
The quoting/unquoting is performed only to correctly strip the directory name.



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-17 11:10                     ` Yuri D'Elia
  2014-02-17 13:28                       ` Yuri D'Elia
@ 2014-02-17 16:50                       ` Oliver Kiddle
  2014-02-17 17:54                         ` Yuri D'Elia
  1 sibling, 1 reply; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-17 16:50 UTC (permalink / raw)
  To: zsh-users

Yuri D'Elia wrote:
> By also unquoting and checking for the 'all-files' tag, I can correctly match completions for (path)/files and quoted arguments.

Have you got an example for that?

> I don't think the complex recursive match is needed at all.
> I couldn't find any case that would require that. Do you have an example?

It isn't actually recursive. The intention with it was to cope with all
situations where a shell word is completed in steps. What you have is
hard coding / as a separator which is fine for paths/filenames. Try
completion after, for example, ssh user@host.

Oliver


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-17 16:50                       ` Oliver Kiddle
@ 2014-02-17 17:54                         ` Yuri D'Elia
  2014-02-18 15:23                           ` Oliver Kiddle
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-17 17:54 UTC (permalink / raw)
  To: zsh-users

On 02/17/2014 05:50 PM, Oliver Kiddle wrote:
>> By also unquoting and checking for the 'all-files' tag, I can
>> correctly match completions for (path)/files and quoted arguments.
> 
> Have you got an example for that?

$ touch file fjle

$ ls f<TAB>
$ ls ./f<TAB>
$ ls $PWD/t<TAB>

or

$ touch file 'file a' 'file b'

$ ls file<TAB>
$ ls file\ <TAB>
$ ls "file<TAB>

also try with:

$ touch 'file*' 'file *' 'file(' 'file\' 'file\\'

for some fancy ways to break the completion in awesome ways (the last
three fail for me with and without the quote).

> It isn't actually recursive. The intention with it was to cope with
> all situations where a shell word is completed in steps. What you
> have is hard coding / as a separator which is fine for
> paths/filenames. Try completion after, for example, ssh user@host.

The problem is that you don't know exacly what the completer is going to
display. This is why I check $curtag. I'm not sure there's a better way
to handle the situation then this:

    case $curtag in
    all-files) prefix=${prefix##*/} ;;
    hosts) prefix=${prefix#*@} ;;
    esac

Now it works for me, since the ssh <TAB> will first complete for
<users|hosts>, then just a second hosts fragment, then probably a path
(which should be in all-files again). Maybe there's some smarter way to
extract the separator?



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-17 17:54                         ` Yuri D'Elia
@ 2014-02-18 15:23                           ` Oliver Kiddle
  2014-02-18 16:07                             ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-18 15:23 UTC (permalink / raw)
  To: zsh-users

Yuri D'Elia wrote:
> also try with:
> 
> $ touch 'file*' 'file *' 'file(' 'file\' 'file\\'
> 
> for some fancy ways to break the completion in awesome ways (the last
> three fail for me with and without the quote).

That's puzzling because all your examples work for me, at least
according to my expectations. That is both completion in general and the
_show_ambiguity function I posted. The files are added as matches with
backslash quoting for special characters. It isn't ideal if you use ' or
" in the middle of the word rather than the beginning or for completion
immediately after \ in the default configuration.

> The problem is that you don't know exacly what the completer is going to
> display. This is why I check $curtag. I'm not sure there's a better way
> to handle the situation then this:

Again, I'm puzzled because the pattern I posted works for me in either
case without having to guess the separator based on $curtag. There are
other approaches but it seems like you've got it working in a way that
is at least fairly satisfactory anyway.

Oliver


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-18 15:23                           ` Oliver Kiddle
@ 2014-02-18 16:07                             ` Yuri D'Elia
  2014-02-18 18:07                               ` Oliver Kiddle
  0 siblings, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-18 16:07 UTC (permalink / raw)
  To: zsh-users

On 02/18/2014 04:23 PM, Oliver Kiddle wrote:
> That's puzzling because all your examples work for me, at least
> according to my expectations. That is both completion in general and the
> _show_ambiguity function I posted. The files are added as matches with
> backslash quoting for special characters. It isn't ideal if you use ' or
> " in the middle of the word rather than the beginning or for completion
> immediately after \ in the default configuration.

Yes, but in the following case:

mkdir x
touch x/y x/z
ls x/<TAB>

the completion list for me is:

y z

while your original reply string will be:

:=(#i)(x|)/(#b)(?|)*==4

this won't highlight anything in (y z) since you're matching a full path
that starts with x/.

Because if that works for you, I'm eager to understand how :P



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-18 16:07                             ` Yuri D'Elia
@ 2014-02-18 18:07                               ` Oliver Kiddle
  2014-02-18 19:45                                 ` Yuri D'Elia
  0 siblings, 1 reply; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-18 18:07 UTC (permalink / raw)
  To: zsh-users

Yuri D'Elia wrote:
> Yes, but in the following case:
> 
> mkdir x
> touch x/y x/z
> ls x/<TAB>
> 
> the completion list for me is:
> 
> y z

I intentionally prevented it from highlighting the first (or only)
character. As I said in the first message, it seems fairly pointless.
The underlining doesn't make the completion list easier to read quickly
so it needs to be useful. It also isn't ideal when you get an underlined
space as that looks like an underscore.

You can get it back with:
    ZLS_COLORS+=":=(#i)${prefix//?/(}${prefix//(#m)?/$MATCH:q|)}(#b)(?|)*==4"
And remove the [[ -n $prefix ]] test.

Oliver


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-18 18:07                               ` Oliver Kiddle
@ 2014-02-18 19:45                                 ` Yuri D'Elia
  2014-02-25 14:07                                   ` Jesper Nygårds
  2014-02-25 20:41                                   ` Oliver Kiddle
  0 siblings, 2 replies; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-18 19:45 UTC (permalink / raw)
  To: zsh-users

On 02/18/2014 07:07 PM, Oliver Kiddle wrote:
> I intentionally prevented it from highlighting the first (or only)
> character. As I said in the first message, it seems fairly pointless.
> The underlining doesn't make the completion list easier to read quickly
> so it needs to be useful. It also isn't ideal when you get an underlined
> space as that looks like an underscore.

Sorry, now the expression clicked for me.
It was failing for the following:

touch 'file a'
touch 'file b'
ls file\ <TAB>

which made me disregard it too quickly. Interestingly it fails due to
the fact that $MATCH:q is translating ' ' to '\ ' (which should be
literal in this context). Same for the quotes.

I'm not sure whether it would be more feasible to manually escape a
selected set of characters, or do something like the following:

local lit=' \''"'
ZLS_COLORS+=":=${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/${${MATCH:q}//\\[$lit]/$MATCH}|)}${${prefix[-1]:q}//\\[$lit]/$prefix[-1]}(#b)(?|)*==4"

which will simply unescape what's needed.

The choice of underscore is arbitrary. I was using bold before, but the
font I'm currently using has almost the same weight, which was difficult
to distinguish. Underline/underscore are different enough for me.



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-18 19:45                                 ` Yuri D'Elia
@ 2014-02-25 14:07                                   ` Jesper Nygårds
  2014-02-25 14:33                                     ` Yuri D'Elia
  2014-02-25 20:41                                   ` Oliver Kiddle
  1 sibling, 1 reply; 25+ messages in thread
From: Jesper Nygårds @ 2014-02-25 14:07 UTC (permalink / raw)
  To: zsh-users

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

Yuri, Oliver,

This thread has been very interesting, but also a bit hard to follow. Would
any one of you care to share the final version of your solution, in a more
concise form? The functionality seems very useful to me.


On Tue, Feb 18, 2014 at 8:45 PM, Yuri D'Elia <wavexx@thregr.org> wrote:

> On 02/18/2014 07:07 PM, Oliver Kiddle wrote:
> > I intentionally prevented it from highlighting the first (or only)
> > character. As I said in the first message, it seems fairly pointless.
> > The underlining doesn't make the completion list easier to read quickly
> > so it needs to be useful. It also isn't ideal when you get an underlined
> > space as that looks like an underscore.
>
> Sorry, now the expression clicked for me.
> It was failing for the following:
>
> touch 'file a'
> touch 'file b'
> ls file\ <TAB>
>
> which made me disregard it too quickly. Interestingly it fails due to
> the fact that $MATCH:q is translating ' ' to '\ ' (which should be
> literal in this context). Same for the quotes.
>
> I'm not sure whether it would be more feasible to manually escape a
> selected set of characters, or do something like the following:
>
> local lit=' \''"'
>
> ZLS_COLORS+=":=${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/${${MATCH:q}//\\[$lit]/$MATCH}|)}${${prefix[-1]:q}//\\[$lit]/$prefix[-1]}(#b)(?|)*==4"
>
> which will simply unescape what's needed.
>
> The choice of underscore is arbitrary. I was using bold before, but the
> font I'm currently using has almost the same weight, which was difficult
> to distinguish. Underline/underscore are different enough for me.
>
>
>

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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-25 14:07                                   ` Jesper Nygårds
@ 2014-02-25 14:33                                     ` Yuri D'Elia
  0 siblings, 0 replies; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-25 14:33 UTC (permalink / raw)
  To: zsh-users

On 02/25/2014 03:07 PM, Jesper Nygårds wrote:
> Yuri, Oliver,
> 
> This thread has been very interesting, but also a bit hard to follow. Would
> any one of you care to share the final version of your solution, in a more
> concise form? The functionality seems very useful to me.

My current setup:

[zshrc]

fpath+=( $ZDOTDIR/.zfunc )
zmodload zsh/complist
compinit -u

zstyle ':completion:*' completer _show_ambiguity _complete

[$ZDOTDIR/.zfunc/_show_ambiguity]

#autoload

_show_ambiguity()
{
  (( $comppostfuncs[(I)_show_ambiguity_end] )) || comppostfuncs+=(
_show_ambiguity_end )
  return 1
}

_show_ambiguity_end()
{
  local
prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]}
  local unesc=' \''"'
  [ -n "$prefix" ] &&
ZLS_COLORS+=":=${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/${${MATCH:q}//\\[$unesc]/$MATCH}|)}${${prefix[-1]:q}//\\[$unesc]/$prefix[-1]}(#b)(?|)*==4"
  ZLS_COLORS+=":=*=0"
}

_show_ambiguity "$@"

EOF

As an additional note, I finally decided not to highlight the first
character in a full list, as Oliver said it's mostly redundant (although
Emacs does it anyway).

The partial match seems to work fine, and with the fixed escaping it
matches all cases correctly.

I also use a final ":=*=0" color spec to disable any built-in coloring
rules when the ambiguity match fails (I like my completions to be
colorless).

To be honest, I often work with directories with large lists of files,
and showing the ambiguity like emacs started to do a while ago is a
godsend since I do not use menu completition.


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-18 19:45                                 ` Yuri D'Elia
  2014-02-25 14:07                                   ` Jesper Nygårds
@ 2014-02-25 20:41                                   ` Oliver Kiddle
  2014-02-26  8:15                                     ` Yuri D'Elia
  2014-02-26  8:16                                     ` Yuri D'Elia
  1 sibling, 2 replies; 25+ messages in thread
From: Oliver Kiddle @ 2014-02-25 20:41 UTC (permalink / raw)
  To: zsh-users

On 18 Feb, Yuri D'Elia wrote:
> It was failing for the following:
> 
> touch 'file a'
> touch 'file b'
> ls file\ <TAB>
> 
> which made me disregard it too quickly. Interestingly it fails due to
> the fact that $MATCH:q is translating ' ' to '\ ' (which should be
> literal in this context). Same for the quotes.

I'd really have expected superfluous quoting like that to be ignored.
Normally it is:

% b=xyz
% [[ $b = *\y* ]] && echo yup
yup
% a='\y'
% [[ $b = *$~a* ]] && echo yup

With your change it seems to work in single quotes but not for backslash
quotes.

I think it is perhaps better to explicitly quote characters that are
special in patterns rather than reverting the quoting for spaces and
quotes. I've included what I now have in full below to make it easier
for anyone following this.

Having used this for a little while now, I've found it is sometimes
vaguely useful. Is it worth adding to git? I'm inclined to think it
should be included in _main_complete as a zstyle option rather than as a
completer.

This is working for many things that need quoting like | and *. I can't
work out how to cope with an initial = mainly because I can't get the
pattern to match it.

A bug I found while looking at this is the following:

% zsh -f
% autoload -U compinit; compinit
% : ${PS\1<tab>
  -> ${PPS1}

Oliver

#autoload

_show_ambiguity() {
  (( $comppostfuncs[(I)_show_ambiguity_end] )) ||
      comppostfuncs+=( _show_ambiguity_end )
  return 1
}

_show_ambiguity_end() {
  local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]}
  local toquote='[\(\)\|~^?*[\]#]'
  [[ -n $prefix ]] &&
    ZLS_COLORS+=":=(#i)${prefix[1,-2]//?/(}${prefix[1,-2]//(#m)?/${MATCH/$~toquote/\\$MATCH}|)}${prefix[-1]//(#m)$~toquote/\\$MATCH}(#b)(?|)*==4"
}

_show_ambiguity "$@"


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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-25 20:41                                   ` Oliver Kiddle
@ 2014-02-26  8:15                                     ` Yuri D'Elia
  2014-02-26 15:03                                       ` Yuri D'Elia
  2014-02-26  8:16                                     ` Yuri D'Elia
  1 sibling, 1 reply; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-26  8:15 UTC (permalink / raw)
  To: zsh-users

On 02/25/2014 09:41 PM, Oliver Kiddle wrote:
>> which made me disregard it too quickly. Interestingly it fails due to
>> the fact that $MATCH:q is translating ' ' to '\ ' (which should be
>> literal in this context). Same for the quotes.
> 
> I'd really have expected superfluous quoting like that to be ignored.

Me too, actually.

> With your change it seems to work in single quotes but not for backslash
> quotes.

> 
> I think it is perhaps better to explicitly quote characters that are
> special in patterns rather than reverting the quoting for spaces and
> quotes. I've included what I now have in full below to make it easier
> for anyone following this.
> 
> Having used this for a little while now, I've found it is sometimes
> vaguely useful. Is it worth adding to git? I'm inclined to think it
> should be included in _main_complete as a zstyle option rather than as a
> completer.
> 
> This is working for many things that need quoting like | and *. I can't
> work out how to cope with an initial = mainly because I can't get the
> pattern to match it.

I also noticed so far that it fails for = like you said, and # too.
Though I'm not sure how to handle it correctly at this point, since it's
not clear what are the rules anymore. Maybe there is some unquoting
going on in ZLS_COLORS? Because the generated pattern looks legitimate
to me.

I've also tried (with no luck) to expand to ([${MATCH}]|) instead, but
it fails for a different set of characters.

> _show_ambiguity_end() {
>   local prefix=${${compstate[unambiguous]}[1,${compstate[unambiguous_cursor]}-1]}
>   local toquote='[\(\)\|~^?*[\]#]'

What about <>?



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-25 20:41                                   ` Oliver Kiddle
  2014-02-26  8:15                                     ` Yuri D'Elia
@ 2014-02-26  8:16                                     ` Yuri D'Elia
  1 sibling, 0 replies; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-26  8:16 UTC (permalink / raw)
  To: zsh-users

On 02/25/2014 09:41 PM, Oliver Kiddle wrote:
> Having used this for a little while now, I've found it is sometimes
> vaguely useful. Is it worth adding to git? I'm inclined to think it
> should be included in _main_complete as a zstyle option rather than as a
> completer.

I would definitely like this as a general addition to the main completer.

It just needs a customizable color for the match.



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

* Re: widget special PREFIX variable and cursor position with complete_in_word
  2014-02-26  8:15                                     ` Yuri D'Elia
@ 2014-02-26 15:03                                       ` Yuri D'Elia
  0 siblings, 0 replies; 25+ messages in thread
From: Yuri D'Elia @ 2014-02-26 15:03 UTC (permalink / raw)
  To: zsh-users

On 02/26/2014 09:15 AM, Yuri D'Elia wrote:
> I also noticed so far that it fails for = like you said, and # too.
> Though I'm not sure how to handle it correctly at this point, since it's
> not clear what are the rules anymore. Maybe there is some unquoting
> going on in ZLS_COLORS? Because the generated pattern looks legitimate
> to me.

It occurred to me that maybe = is incorrectly used literally for tokenization inside complist.
Could somebody look if the string is tokenized correctly?



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

end of thread, other threads:[~2014-02-26 15:24 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-12 21:02 widget special PREFIX variable and cursor position with complete_in_word Yuri D'Elia
2014-02-13  5:47 ` Bart Schaefer
2014-02-13 13:38   ` Yuri D'Elia
2014-02-13 17:25     ` Bart Schaefer
2014-02-13 18:12       ` Yuri D'Elia
2014-02-14  6:34         ` Bart Schaefer
2014-02-14 11:56           ` Oliver Kiddle
2014-02-14 12:56             ` Yuri D'Elia
2014-02-14 14:39               ` Oliver Kiddle
2014-02-14 15:38                 ` Yuri D'Elia
2014-02-14 21:36                   ` Oliver Kiddle
2014-02-17 11:10                     ` Yuri D'Elia
2014-02-17 13:28                       ` Yuri D'Elia
2014-02-17 16:50                       ` Oliver Kiddle
2014-02-17 17:54                         ` Yuri D'Elia
2014-02-18 15:23                           ` Oliver Kiddle
2014-02-18 16:07                             ` Yuri D'Elia
2014-02-18 18:07                               ` Oliver Kiddle
2014-02-18 19:45                                 ` Yuri D'Elia
2014-02-25 14:07                                   ` Jesper Nygårds
2014-02-25 14:33                                     ` Yuri D'Elia
2014-02-25 20:41                                   ` Oliver Kiddle
2014-02-26  8:15                                     ` Yuri D'Elia
2014-02-26 15:03                                       ` Yuri D'Elia
2014-02-26  8:16                                     ` Yuri D'Elia

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