Sublime Forum

View.extract_completions completely fails for some syntaxes

#1

I’ve been using the All Auto Complete package for a while and I finally noticed that it limits you to 20 views before it stops looking. That is problematic for me, so I decided to write my own which (1) searches the buffers in order of last access, and (2) tries to be more efficient about the whole thing.

Meanwhile, there was all this code in all autocomplete to deal with a nasty bug with Sublime’s view.extract_completions method, but I thought, Naaa, that can’t be right!. But sure enough, there appears to be quite a nasty issue.

And the issue is, In some file types (e.g., syntax setting) the extract_completions code just plain old misses some matches or returns matches minus the last character.

Here’s an example. I have the following line in the middle of one of my coffeescript files:

vm.becomeUserAllowed = @UserService.current_user.isAdmin && @UserService.current_user.id != @user.id

When I run the following code in coffee script syntax:

view.extract_completions("becom")

I get

>>> window.active_view().extract_completions("becom")
['becomeUser', 'becomeUse']

the ‘becomeUser’ function exists later in the file. So it found that, but I am not sure why it also found ‘becomeUse’ because that doesn’t exist by itself anywhere in the file. But why did it miss ‘becomeUserAllowed’?

Moving along, now if I change the syntax of the view to JavaScript (which messes up the look of the file, obviously) and perform the same call to extract completions, I get this instead:

>>> window.active_view().extract_completions("becom")
['becomeUser', 'becomeUserAllowed']

This is exactly the right answer and the only difference, of course, is the syntax.

I am hoping this will be considered a bug and just fixed? The work-around is pretty nasty and involves doing a find myself, just like the All AutoComplete plugin does (although … it seems to only deal with the missing one character and not the entirely missing words itself).

Here’s some more information that boggles my mind:

  1. plain syntax also doesn’t work
  2. neither does Pascal
  3. or Java

In fact, so far, the only one that seems to work (ironically the one I first tested) is JavaScript!!

Wait, no, in addition to JavaScript, the following also work:

  1. C++
  2. C
  3. C#
  4. Go
  5. Objective-C
  6. … probably more

OK - I am officially w/out a clue on this one.

Any thoughts?

1 Like

#2

Well - I’ve written my own all autocomplete plugin using view.find_all and it’s about 10ms instead of 2ms so it’s not bad.

But it works reliably and consistently, so that’s a good thing.

I would prefer view.extract_completions worked properly though since it’s faster.

0 Likes

#3

Have you checked the scopes on that code to see if it is being tokenized into multiple tokens? That would be my first guess.

If you post the link to the CoffeeScript syntax you are using, that may help others in investigating.

1 Like

#4

Thanks for getting back!

I am using Better Coffeescript package.

I want to remind you, though, that it also happens (although slightly different outcome) with Plain syntax as well.

I checked the scope of the

vm.becomeUserAllowed

statement, and it looks like the same scope the whole thing across:

22 bytes: source.coffee variable.assignment.coffee variable.assignment.coffee 

Here’s a complete (fragment) of my coffeescript file:

foo: () ->
    if @mode == 'edit'
          vm.becomeUserAllowed = @UserService.current_user.isAdmin && @UserService.current_user.id != @user.id

becomeUser: () ->
    @Service.becomeUser(@$scope, @user)
    return

Here’s the result in CoffeeScript syntax:

>>> window.active_view().extract_completions("bec")
['becomeUser', 'becomeUse']

Here it is with Plain Text syntax:

>>> window.active_view().extract_completions("bec")
['becomeUser']

And now the correct output with JavaScript syntax:

>>> window.active_view().extract_completions("bec")
['becomeUser', 'becomeUserAllowed']
0 Likes

#5

You can get a sense of how things are being tokenized by turning on word wrap and making the window very narrow. With Plain Text, you’ll see that becomeUserAllowed is part of the token vm.becomeUserAllowed.

window.active_view().extract_completions("vm")

You’ll notice this brings up vm.becomeUserAllowed with both Plain Text and CoffeeScript. The issue is that Better CoffeeScript isn’t properly tokenizing the code. The JavaScript syntax is.

0 Likes

#6

Thanks for the education!

Do you have an explanation for the missing letter at the end of the token?

0 Likes

#7

My guess would be a repeated capture is grabbing one character of function name at a time, causing the final match to be made into a token, but no separate scope is being applied to it.

0 Likes