"self" from dot "." in python snippet problematic #65

Open
schivmeister opened this Issue Oct 25, 2011 · 20 comments

Comments

Projects
None yet
8 participants

When used for eg. with SuperTab for context-based completion, everything is fine except for:

math. == mathself.
math. == mathselfself.

It would be better if the completion here could be context-aware, so for eg. in Python we want "." to expand to "self" only when there is nothing before it, so we could have "something." and not "somethingself."

I also encountered this issue.

I fixed it:
https://github.com/davidhalter/vim-snipmate

It's just one commit.
You have to put
let g:snipMateAllowMatchingDot = 0
into your vim config.

cheers!

Collaborator

MarcWeber commented Feb 10, 2012

A complete bug report always contains both: a) what do you get and b) what do you expect instead. I don't see b).

You're right. Here it is as best as I can explain, very simply:

".something" == "self.something"
"something.something" == "something.something" (no change)

Both should work. That's what I expect. Anyway I've actually just removed the snippet for ".", and as of this moment my python.snippets is full of ugly customisations, but I'm lovin' it ;)

Collaborator

MarcWeber commented Feb 10, 2012

I expect ".|something" expand to "self.something" where | is the cursor position. Did I get it?

Yes. You're right.
My "fix" is maybe not that good, because it probably not the right solution, because I'm not that much into vim scripts.
In my opinion, patterns should only work, if there is whitespace before the pattern (\n / \r are also whitespace).

Collaborator

MarcWeber commented Feb 11, 2012

See pull request 84. Works here. If you tell me which custom snippets you're using breaking it I can debug it.

Actually it's like schivmeister wrote:
"self." results in "selfself."
"test()." results in "test()self."

Another example is the "" snippet, which produces normally init
"test()
" results in test()init
But this behavior is not so much a problem, since I don't type an underline after brackets. However, typing a dot after brackets or a namespace is really normal and should definitely not result in another self.

I just tested python snippets, can't tell for others.
The snippets are not custom, they are just from the recommended snippets repo, here.
https://github.com/honza/snipmate-snippets

snippet .
self.
snippet _
${1:init}${2}

Collaborator

MarcWeber commented Feb 11, 2012

"self." results in "selfself."

What is the problem? That's how snippets work. They look at the left. They find a '.'

Collaborator

MarcWeber commented Feb 11, 2012

which should expand to self. - and that's what's happening. The main problem I have is that you don't talk about the cause. You're annoyed by something happening when typing self. (eg because you're using supertab or such - I have to guess your problems). So in the end it looks like you want context aware snippets which only appear in some cases. I was told that ultisnips has this build in - and snipmate provides a way to generate snippets "on the fly" - which could be used to implement the same feature. There is even a python example allowing to tab complete all functions defined in the same file for python.
Maybe we should allow multiple snippet sources - then one could be a function generating the ".self" snippet only when used at start of a line or behind ( [ + - etc. Again - I have to guess. And that's why you should think about improving your bug reports providing all context.

Crap, yes, you're absolutely right. I didn't look at it from the viewpoint of snipmate itself. The problem is actually just that - it should be "context aware".

Sorry, it's a little mess with those two issues (one being the pull request). This is my fault, sorry for that :-)

But in the pull request I wrote at the beginning, that I'm using supertab.

So, now that you understand what I want, I try to justify why I think this would be the right behavior.
Snippets don't look just to the left, they take the word to the left and look for a sníppet in that word.
e.g. with python snippets, "def" will expand to a full function, while "adef" will just generate a tab or start supertab. But this is not the same for the dot, as explained above.
So it's really up to the definition of a word. If you define a word as [^\s], my approach would be the right one, if a word is something more complicated, than the current implementation is the right one.
Since I knew, that some people would want the current behavior, I just wrote an option, which I think is the right thing to do here.

Collaborator

MarcWeber commented Feb 11, 2012

Summary: You need a "no match" in snipmate so that supertab continues with completion.

I"m thinking about whether adding an "applies: BEFORE_CURSOR="^\s*$"" like line would be a nicer fix. Then much more context sensitive implementations could be added. In the end the question is whether we want to duplicate work - or whether someone should just merge xptemplate and make it read snippets files - because xptemplate (or ultisnips) are both more advanced". In the end the community will benefit from "less solutions" - because they will be of higher quality then.

The alternative solution would be to allow many "sources" - and generate the snippets on the fly. Then each implementation can take care about cursor location itself.

Another quick fix would be using a key different from but I agree that its not what you want.

Actually it's not so much of a big deal anymore as it was when I first reported this. I simply add my own snippets where needed and all is good. If I don't want "." I use, say "s." to expand to "self". I say not to go forward with anything and close this bug or go with something simple, like david's change(s).

Collaborator

MarcWeber commented Feb 11, 2012

For PHP and most other languages I created a simple mapping:
inoremap $this-> or self. for pyhton etc.
That works pretty well for me :)
If you map t to in vim it also works in console.

You're right that it is used very often.

That's why snipmate is still used - it works good enough and is simple.

Yeah, we are on the same line now! You can decide for yourself, if you want to implement my solution (or something "context aware", which would probably be better)

I still think that snipmate is not that configurable (although it is very mature), which is a thing I really like in general about vim plugins.

It's really up to you, I have my own fork anyways, which is the good thing about github :-)

dbrgn commented Feb 11, 2013

I encountered the same issue (due to supertab). Using the fork by @davidhalter is a valid workaround for now, but it would be great if there were a config option in the original snipmate :)

+1 would love to see this option in original snipmate

dohsimpson added a commit to dohsimpson/vim-snipmate that referenced this issue Jun 1, 2015

Fixed python dot expansion
A following dot should not expand by itself. (issue #65 @garbas)

fvisin commented Oct 21, 2015

+1 I would also like this option implemented in the original snipmate.

My solution for the time being is to fork https://github.com/honza/vim-snippets and remove the . snippet. The best for me would be to have an configuration option in snipmate to ignore some snippets. Do you think it could be feasible?

Collaborator

ajzafar commented Oct 26, 2015

@fvisin I've moved your request to a new issue, #214.

timss added a commit to timss/vimconf that referenced this issue Feb 18, 2016

Set completion to use context and longest common match:
* Affects both native and supertab completion.
* A lot of edge cases at play here, but 'should' work fine
without any interventions.
* Rather different from defaults (for the better, for the most part).
* Overriding these variables can easily be done in $HOME/.vimrc.last
* Know issue: omnifunc and therefore context doesn't always play nice with
snippets, especially '.' => 'self' in Python. For more info:

garbas/vim-snipmate#65
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment