zsh-users
 help / color / mirror / code / Atom feed
* java class names completion widget
@ 2006-06-05 18:40 Konstantin Sobolev
  2006-06-07 10:47 ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Konstantin Sobolev @ 2006-06-05 18:40 UTC (permalink / raw)
  To: zsh-users

Hi,

I'd like to mimic IDEA's (one of Java IDEs) classes searching in zsh. It 
allows to find classes specifying only their names with some lower case 
letters ommitted. For instance, "MDCl" will match "org.bar.MyDumbClass".
More strictly, each capital letter means "this letter followed by any number 
of lower-case letters".

I've made a simple function which generates a regexp by such abbreviations:

function makeClassRegexp {
    word=$1
    res=""
    for (( i=1; $i<=${#word}; i++ )) {
        char=$word[$i]
        if [[ $char == *[[:upper:]]* ]] {
            res=${res}"([[:lower:]]*)"
        }
        res=${res}${char}
    }
    echo $res"(.*)\.java$"
}

Now I can easily find classes under the current dir:

fcl() {
    regexp=`makeClassRegexp $1`
    find . -type f | GREPP $regexp
}

(where GREPP is aliased to 'grep -P' or pcregrep on different distros).

kos@kos ~/work/jrs/src $ fcl SHMa
./org/kos/jrs/SoftHashMap.java

Now I want to convert it into a completion widget. What is the easiest way to 
do it?

Thanks

-- 
/KoS
* Walk softly and carry a fully charged PHASER!			      


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

* Re: java class names completion widget
  2006-06-05 18:40 java class names completion widget Konstantin Sobolev
@ 2006-06-07 10:47 ` Peter Stephenson
  2006-06-15 15:38   ` Konstantin Sobolev
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2006-06-07 10:47 UTC (permalink / raw)
  To: zsh-users

Konstantin Sobolev wrote:
> kos@kos ~/work/jrs/src $ fcl SHMa
> ./org/kos/jrs/SoftHashMap.java
> 
> Now I want to convert it into a completion widget. What is the easiest way to
> do it?

(I'm going to assume you're already using the new completion system,
which seems to be the case.)

You can actually do the case matching element within zsh without any new
code; the difficult bit is the combination of completion and finding
files, but that's difficult to hook in to completion regardless of
whether the expansion is done inside or outside the shell.  Here's how
you do the basic completion (given the problems this probably isn't what
you want, so I'll look at another method later).  The following adds the
smash case completion to the context after javac:

zstyle ':completion:*:javac:*' matcher 'r:|[A-Z]=* r:|=*'

This means roughly "allow all capital letters on the command line to be
followed immediately on the right by any pattern in trial completions,
and allow the end of the string on the command line to be followed by
any pattern in trial completions".  More complicated variants are
possible and are described for this very case in the zshcompwid manual
page (under MATCHING CONTROL).

You can also change the context where this is applied; this is described
under COMPLETION SYSTEM CONFIGURATION in the zshcompsys manual page.

This allows "javac SHMa" to complete to "javac SoftHashMap.java", but it
doesn't handle path searching.  You can, however, do

javac ./o/k/j/SHMa<TAB>

since path elements are completed, but you can't do a general search
that I know of.


So let's concentrate on the search element.  This is more difficult,
because zsh usually separates expansion and completion.  So if you have
the _expand completer in use,

javac **/*.java

would expand to all .java files in subdirectories, but

javac **/SHMa

wouldn't do anything, because the matching control isn't applied to
expansions.


So instead let's hijack the _expand completer and provide a front end.
The trouble with making this the normal contextual completer in place of
_java is that you'll lose all the features of that and need to merge
together what you want.  Hence what I suggest you do is use a separate
completion when you want the special behaviour.  Then you'll have to
remember to type a different key sequence for this, say C-x j.

Here's the full code; put it in a file (say _expand_java_path) in your
function path:

#compdef -k complete-word ^xj
local MATCH MBEGIN MEND
# Turn the start of the string on the line into **/ followed
# by the original prefix with upper case letters followed
# by [^[:upper:]]# which matches any number of consecutive
# non-upper-case characters.  This relies on the fact that
# the completion system uses the EXTENDED_GLOB option.
PREFIX="**/${PREFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}"
# Replace the end of the string similarly, adding *.java to
# the pattern
SUFFIX="${SUFFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}*.java"
# Now we've got a zsh recursive matching pattern; for example
#   SHMa
# has turned into
#   **/S[^[:upper:]]#H[^[:upper:]]#M[^[:upper:]]#a*.java
# Let the normal _expand completer get to work.
_expand "$@"

(Four lines of active code for the whole thing!)

Those are the basics; there are many, many possible bells and whistles
since all the features of the completion system are available for
offering you matches, and actually the _expand completer does a bit to
much work for us; we just want the globbing effect.

In particular, the behaviour with ambiguous expansions could be better
configured.  _expand turns on menu completion when inserting.  Currently
it will cycle through possible expansions, then all expansions, then the
original pattern (though it's not the original, it's the hacked version
from _expand_java_path so isn't much use).  You can use the tag-order
style to help.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


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

* Re: java class names completion widget
  2006-06-07 10:47 ` Peter Stephenson
@ 2006-06-15 15:38   ` Konstantin Sobolev
  2006-06-15 16:19     ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Konstantin Sobolev @ 2006-06-15 15:38 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-users

Hi Peter

On Wednesday 07 June 2006 14:47, Peter Stephenson wrote:
> (I'm going to assume you're already using the new completion system,
> which seems to be the case.)
yes

> You can actually do the case matching element within zsh without any new
> code; the difficult bit is the combination of completion and finding
> files, but that's difficult to hook in to completion regardless of
> whether the expansion is done inside or outside the shell.  Here's how
> you do the basic completion (given the problems this probably isn't what
> you want, so I'll look at another method later).  The following adds the
> smash case completion to the context after javac:
>
> zstyle ':completion:*:javac:*' matcher 'r:|[A-Z]=* r:|=*'

[skip]
Yeah, I've already played with this stuff. As you point out below, it doesn't 
search thru the nested folders, which is a very desired behaviour.
[skip]

> So instead let's hijack the _expand completer and provide a front end.
> The trouble with making this the normal contextual completer in place of
> _java is that you'll lose all the features of that and need to merge
> together what you want.  Hence what I suggest you do is use a separate
> completion when you want the special behaviour.  Then you'll have to
> remember to type a different key sequence for this, say C-x j.
>
> Here's the full code; put it in a file (say _expand_java_path) in your
> function path:
>
> #compdef -k complete-word ^xj
> local MATCH MBEGIN MEND
> # Turn the start of the string on the line into **/ followed
> # by the original prefix with upper case letters followed
> # by [^[:upper:]]# which matches any number of consecutive
> # non-upper-case characters.  This relies on the fact that
> # the completion system uses the EXTENDED_GLOB option.
> PREFIX="**/${PREFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}"
> # Replace the end of the string similarly, adding *.java to
> # the pattern
> SUFFIX="${SUFFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}*.java"
> # Now we've got a zsh recursive matching pattern; for example
> #   SHMa
> # has turned into
> #   **/S[^[:upper:]]#H[^[:upper:]]#M[^[:upper:]]#a*.java
> # Let the normal _expand completer get to work.
> _expand "$@"
>
> (Four lines of active code for the whole thing!)
>
> Those are the basics; there are many, many possible bells and whistles
> since all the features of the completion system are available for
> offering you matches, and actually the _expand completer does a bit to
> much work for us; we just want the globbing effect.
>
> In particular, the behaviour with ambiguous expansions could be better
> configured.  _expand turns on menu completion when inserting.  Currently
> it will cycle through possible expansions, then all expansions, then the
> original pattern (though it's not the original, it's the hacked version
> from _expand_java_path so isn't much use).  You can use the tag-order
> style to help.

Cool, this is what I've expected to get :)
It works, but how can I force it to use menu completion instead of cycling? 
Playing with 
zstyle ':completion:*' menu select
gives a bit weird effect:
(with descriptions turned on)

kos@kos ~/work/jrs $ S<^xj>
kos@kos ~/work/jrs $ src/org/kos/jrs/ShowCommand.java
---- expansions
src/org/kos/jrs/ShowCommand.java                                               
tests/org/kos/jrs/SubscriptionManagerMock.java
src/org/kos/jrs/SoftHashMap.java                                               
tests/org/kos/jrs/SubscriptionManagerTest.java
src/org/kos/jrs/SubscriptionManagerImpl.java                                   
whack/trunk/source/java/org/jivesoftware/whack/container/ServerContainer.java
src/org/kos/jrs/SubscriptionManager.java                                       
whack/trunk/source/java/org/jivesoftware/whack/SocketReadThread.java
src/org/kos/jrs/swap/SwapFileWritingContainer.java                             
whack/trunk/source/java/org/jivesoftware/whack/util/StringUtils.java
src/org/kos/jrs/swap/SwappableObjectContainer.java                             
whack/trunk/source/java/org/xmpp/packet/StreamError.java
src/org/kos/jrs/swap/SwappingMap.java
---- all expansions
---- original
src/org/kos/jrs/ShowCommand.java src/org/kos/jrs/SoftHashMap.java 
src/org/kos/jrs/SubscriptionManagerImpl.java 
src/org/kos/jrs/SubscriptionManager.java sr ...
**/S[^[:upper:]]#*.java
kos@kos ~/work/jrs $ src/org/kos/jrs/ShowCommand.java

As I understand it tries to show the menu but by some reason fallbacks to 
cycling.

Thanks a lot :)

-- 
/KoS
* Is this the party to who I am typing to?			      


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

* Re: java class names completion widget
  2006-06-15 15:38   ` Konstantin Sobolev
@ 2006-06-15 16:19     ` Peter Stephenson
  2006-06-15 18:41       ` Konstantin Sobolev
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2006-06-15 16:19 UTC (permalink / raw)
  To: Zsh users list

Konstantin Sobolev wrote:
> It works, but how can I force it to use menu completion instead of cycling? 
> Playing with 
> zstyle ':completion:*' menu select
> gives a bit weird effect:
> (with descriptions turned on)

I was hoping you weren't going to ask that...

I think a change of tack is the easiest way.  Instead of hacking the
_expand completer, which has some odd settings, the following goes
through the normal completer; the trick with _generic is to allow us
to use a widget bound to a key but still use the normal completion
logic.  Then we simply do the expansion by hand and add the results
unconditionally, i.e. without additional matching (compadd -U).  This
may have side effects but it seems basically OK.

_expand_java_path now contains:

  #autoload
  local MATCH MBEGIN MEND pref suf

  pref="**/${PREFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}"
  suf="${SUFFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}*.java"

  local expl
  local -a exp
  exp=(${~pref}${~suf}(N))
  if (( ${#exp} )); then
    _wanted java-files expl 'java source file (search)' \
      compadd -U -a exp
  else
    return 1
  fi

and .zshrc now requires the following setup:

  zle -C expand-java-path complete-word _generic
  zstyle ':completion:expand-java-path:*' completer _expand_java_path
  bindkey '^xj' expand-java-path

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


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

* Re: java class names completion widget
  2006-06-15 16:19     ` Peter Stephenson
@ 2006-06-15 18:41       ` Konstantin Sobolev
  0 siblings, 0 replies; 5+ messages in thread
From: Konstantin Sobolev @ 2006-06-15 18:41 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh users list

On Thursday 15 June 2006 20:19, Peter Stephenson wrote:

> _expand_java_path now contains:
>
>   #autoload
>   local MATCH MBEGIN MEND pref suf
>
>   pref="**/${PREFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}"
>   suf="${SUFFIX//(#m)[[:upper:]]/${MATCH}[^[:upper:]]#}*.java"
>
>   local expl
>   local -a exp
>   exp=(${~pref}${~suf}(N))
>   if (( ${#exp} )); then
>     _wanted java-files expl 'java source file (search)' \
>       compadd -U -a exp
>   else
>     return 1
>   fi
>

Great!
It took me around 2 hours to understand how these 12 lines work, and I'm still 
a bit confused by the magic happening behind _wanted :)

Many thanks

-- 
/KoS
* I Print on Steel with an Industrial Laser			      


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

end of thread, other threads:[~2006-06-15 18:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-05 18:40 java class names completion widget Konstantin Sobolev
2006-06-07 10:47 ` Peter Stephenson
2006-06-15 15:38   ` Konstantin Sobolev
2006-06-15 16:19     ` Peter Stephenson
2006-06-15 18:41       ` Konstantin Sobolev

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