list_snippets does not show potential regex defined snippet

Bug #1171276 reported by Zhao Cai
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
UltiSnips
Confirmed
Low
Unassigned

Bug Description

For example, if I have the following snippet. type `u` and hit `<C-tab>` will not show the following snippet as possible match.
---------
global !p
def upper_right(inp):
    return (75 - 2 * len(inp))*' ' + inp.upper()
endglobal

snippet /upper_right|ur/ "text ... TEXT" r
${1:Text}`!p snip.rv = upper_right(t[1])`
$0
endsnippet

Revision history for this message
SirVer (sirver) wrote :

this is a known bug - it should even be reported here already. The problem is that 'partially matching' regular expression is not well defined. But there is agreement that a full match should be reported in the list. If you provide a patch, please also write a test for this :).

Changed in ultisnips:
status: New → Confirmed
importance: Undecided → Low
Revision history for this message
Zhao Cai (caizhaoff) wrote :

Do you know any regex library supporting 'partially matching'? I checked that "regex" and "re2" do not have this feature implemented.

Revision history for this message
SirVer (sirver) wrote :

no, this is a nonsensical feature. a regular expression either matches, or it doesn't.

.*blah

always matches. Should it be always listed?

Revision history for this message
Zhao Cai (caizhaoff) wrote :

No, it is "a" feature.

you can check

PCRE - Perl-compatible regular expressions

http://www.pcre.org/pcre.txt
pcrepartial details of the partial matching facility

I know java has the implemented too.

Revision history for this message
Zhao Cai (caizhaoff) wrote :

http://regexkit.sourceforge.net/Documentation/pcre/pcrepartial.html :

Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example might be a date in the form ddmmmyy, defined by this pattern:

  ^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$
If the application sees the user's keystrokes one by one, and can check that what has been typed so far is potentially valid,

Revision history for this message
SirVer (sirver) wrote :

interesting - well, python's regular expressions do not support that. So we are kinda out of luck - shipping another re engine just for that use case is overkill.

Revision history for this message
Zhao Cai (caizhaoff) wrote :

I have managed to achieve this by using boost regex engine. The code is embedded in the YouComplete code: [QueryPartialMatch]( https://gist.github.com/6983945 ).

Now I have two proposals:

1. add snippet syntax to tell what to complete for the completion engine like YouComplete.

For example, I have a snippet:

```snippet
snippet "(\S+)\.Del(ete)?_?if" ".delete_if { |<key>,<value>| <block> }" r
`!p snip.rv=match.group(1)`.delete_if { |${1:key},${2:value}| ${3:# TODO} }
endsnippet
```

I would like to have a way to tell the completion engine to complete `Delete` instead of `(\S+)\.Del(ete)?_?if`.

2. Do you want to include the code in ultisnip? That means extra compliation for installation.

Revision history for this message
SirVer (sirver) wrote :

That is super cool! I am glad that you figured a way out.

1. Do you have a syntax proposal? I think we have to move away from the old snippet fromat to a more descriptive one - the more configuartion we add the more this is needed.

2. No. While I would love to have this feature inside of UltiSnips, compilation is a nogo - it would basically shy away 80% of the users. If this could be a python only feature, I would reconsider :/.

Revision history for this message
SirVer (sirver) wrote :

Did I mention that Valoric's work always keeps me in awe? He is such a smart guy!

Revision history for this message
Zhao Cai (caizhaoff) wrote :

I think UltiSnips is top of the class too.

I think we can add extra () after r in the 4th column for the completion word. How do you think?

```snippet
snippet "(\S+)\.Del(ete)?_?if" ".delete_if { |<key>,<value>| <block> }" r(Delete)
`!p snip.rv=match.group(1)`.delete_if { |${1:key},${2:value}| ${3:# TODO} }
endsnippet
```

Revision history for this message
Zhao Cai (caizhaoff) wrote :

Compilation is actually not that hard. But anyway, in Ultisnips you can optionally check if the user has ycm loaded and call the corresponding functions.

```py

try:
  import ycm_core

  USE_YCM_XXXXXX = True
except ImportError:
  USE_YCM_XXXXXX = False
```

Revision history for this message
Zhao Cai (caizhaoff) wrote :

The other syntax format I would like to suggest is to add extra optional lines before snippet keyword

description .delete_if { |<key>,<value>| <block> }
completion Delete
snippet "(\S+)\.Del(ete)?_?if" r

....

endsnippet

Revision history for this message
SirVer (sirver) wrote :

reasonable suggestions - though it would be nice to have this feature for everybody available. Is there no pure python regular expression library that supports partial matches?

Revision history for this message
Zhao Cai (caizhaoff) wrote :

 I checked "regex" and "re2". I also did web search. I do not see any option for pure python.

As a matter of fact, I do not really think compilation is that scary since the code only depends on Boost library which is easy to install in all major platforms. Or you can just include the boost library in like what YouCompleteMe did.

Another option is to distribute pre-compiled dynamic lib for different platforms.

Revision history for this message
SirVer (sirver) wrote :

You seems firmly routed in the unix world - all this would be easier there. Unfortunately, many users of Ultisnips are on windows - and there distributing binaries is much harder. I think I cannot really include this feature in UltiSnips - it would be super nice, but it will be more trouble than it's worth for most users.

Revision history for this message
Zhao Cai (caizhaoff) wrote :

I would not argue if you think so. Can you help with the syntax? add something like `... r(complete_to)` does not change anything existed.

Revision history for this message
SirVer (sirver) wrote :

I think we should actually use this opportunity and move to the global snippet definitions that you suggested:

description ".delete_if { |<key>,<value>| <block> }"
completion "Delete"
options "r"
trigger "(\S+)\.Del(ete)?_?if"
snippet
....
endsnippet

I think the rules should be like this:

- no blank lines are allowed
- all fields that were optional, stay optional
- order does not matter
- all strings are quoted
- if a global state is used, the snippet line must not contain any other option.
- this deprecates the old way of defining snippets.
- some keywords can be repeated (i.e. having multiple triggers for one snippet).

What do you think?

Revision history for this message
Zhao Cai (caizhaoff) wrote :

I second this syntax. It is clear, easy to parse, and expand for future features.

Maybe the only hiccup is that an converter need to be written to convert existing snippets to the new syntax.

I also like the idea of having multiple triggers for one snippet. Maybe you can use `alias` as keyword for that.

Revision history for this message
SirVer (sirver) wrote :

We can keep the old syntax for existing snippets - updating is then a little more work.

I am not a huge fan of alias, because it seems to be more useful after the fact - i.e. if a shipped snippet has a weird trigger you want to define an alias that just defers to it. But I think this could be easily solved by allowing a snippet to reference other snippets (i.e. explicitly chain snippets.).

Revision history for this message
Zhao Cai (caizhaoff) wrote :

Chained snippets would be nice. I like the idea.

I cannot think of any more comments now. It is good to go.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.