Sublime Forum

Completion priority

#1

I am sure this has been asked before but not lately and not always answered.

I took the time to write my own completion package mostly because I wanted it across buffer, and sorted by current buffer, and then other buffers in most recently used order. Also because some syntaxes weren’t written properly and that was not something I could fix.

However, my goal of specifying the priority has failed because as far as I can tell, the ordering I provide is completely ignored. I assume that’s because multiple plugins can all get in on the “add to the completions list” bandwagon, and therefore, something needs to arbitrary between all those sources?

Still - I have one plugin providing completions and I am really sad that, for example, when I type “wokitdr” and right above me is work_item_drawables, but that item is third in the popup window, rather than first where I’d like it to be. In fact, it’s going with a completion from another file!

Am I missing something. Is it possible to prioritize today and I just don’t know how to do it?

0 Likes

#2

my guess is that is isn’t possible to control the ordering of completions - most likely ST has an implementation detail of using a set to store results so that duplicates don’t appear in the list, and that doesn’t keep the order of items.

i.e.

import sublime
import sublime_plugin


class TestListener(sublime_plugin.EventListener):
    def on_query_completions(self, view, positions, prefix):
        return ["hello_world", "HelloWorld", "hello_world_test", "hello_world_test"]

type he and get results:

  • hello_world
  • hello_world_test
  • HelloWorld
0 Likes

#3

I would check the modules in the Default package to see if one of those is responsible for the pop up. I had a similar problem not too long ago with the order of things that show up in Go To Definition where the desired behavior was to list the local definitions before listing definition found in other files. Tweaking some of the code in Default fixed that problem.

0 Likes

#4

Okay, this is NOT the answer to your question, but it sounds like it’s in a similar vein so might spark some investigation on how to get the priority behavior you want. For this particular problem, the code for the priority and populating the definition list was in symbol.py. Maybe you can find the code for populating the completions list nearby?

0 Likes

#5

I think that the symbol code’s main difference is that it shows a quick panel itself, up at the top of the screen, with it’s own ordering.

I am not sure there’s the same (or indeed, any) control to show a completion panel at the cursor.

Is there? Can I disable completion and implement my own? Not that I want to …

0 Likes

#6

Not entirely sure. It’s part of something I’ve never played with. However there are ways to modify completions I believe. There’s an option in Emacs Pro Essentials about fixing auto-complete:

  /* a built-in version of all auto-complete that fixes some bugs and improves performance */
  "sbp_use_internal_complete_all_buffers": false,

I think I turned that on once, but didn’t like the way it worked. However it does suggest there’s a way to either override it, or enhance the completions suggestions.

0 Likes

#7

I wrote Emacs Pro Essentials and created that option :wink:

It’s the one I am trying to fix.

But do you remember what you didn’t like about it? I am curious.

1 Like

#8

Oh! Hehe, I thought I recognized your username, but I couldn’t place why.

Offhand I don’t recall. It might have been that it offered too much. Normally when I’m writing code, the completions I want are entirely local to the file, so if it’s suggesting everything from the entire project area, it’s actually less useful for offering more. However I couldn’t say for sure that was the reason since it’s been too long for me to be sure.

Honestly if I had a fix for completion, I’d like it to work a smidgen more like Emacs tab completion where hitting tab repeatedly would cycle through the list, though I’ve adapted to ST’s method too. Emacs is just a little bit more lazy friendly :slight_smile:

0 Likes

#9

Giving the most-recently used completions/variable names a higher score sounds quite neet to me in some situations, but the normal fuzzy match algorithm usually gets me what I want with a very minimal number of keystrokes. I love this feature in chat clients, though. Never want to miss it again.

0 Likes

#10

Personally I’d prefer autocompletion to work like:

normal/autotriggered completion -> from buffer only
alternate hotkey -> from other buffers (but not current one)

This way you could have two different autocompletion lists. I think generally one knows if what he’s looking for is in the current buffer or in another one.

0 Likes

#11

You could also try to add dynamically a prefix to the trigger, depending if it originates from other buffers, so that fuzzy search would not prioritize it. Maybe an Unicode symbol, that tells you that the word belongs to another buffer, and that can’t be typed accidentally on its own.

From the example above, transformed:

    class TestListener(sublime_plugin.EventListener):
        def on_query_completions(self, view, positions, prefix):
            return [["hello_world\t[HERE]", "hello_world"], ["HelloWorld\t[HERE]", "HelloWorld"], ["⇄ hello_world_test\tOther Buffer", "hello_world_test"]]

Completion would respect the order:

hello_world
HelloWorld
hello_world_test

At that point, you should need to rebuild the completion lists in an on_activated listener, so that prefixes are removed/added back where necessary.

0 Likes

#12

If sublime defined a third parameter which is priority, and then set the default priority to a well-known value, we could have our cake and eat it.

We could specify all items above the cursor at one level, all items below, all items from other buffers at an Nth level depending on the order they were last accessed.

Everything would work the same with no changes, but the experience could be enhanced if people take the time to prioritize. If you do that, you could decided whether you want your stuff to be in general lower or higher priority than “normal”.

I might like words in my current buffer to be highest, completions due to my syntax to come next, and then things from other buffers.

We could define our code so that it’s a setting, so rather than the package builder deciding, the package user could.

Um - yeah, I have no idea if this is a good idea or a future source of chaos. Certainly more control would be nice.

0 Likes

#13

Since completions from a different view are provided by a plugin anyway, you could actually offer different completions based on the key pressed (and command run), but this is slightly fragile because you need to keep track of the visibility of the panel yourself and the command to close it isn’t always run.

0 Likes

#14

From what I can see, ST already prioritizes completions based on proximity. If you have

|
abacus
abandon

ab triggers abacus, but if you have

abacus
abandon
|

ab triggers abandon.

Then, fuzzy search decides for more complex patterns, and you can’t decide it yourself. In the example at #2, hello_world_test comes before HelloWorld because of the capital letter in the latter, but if you put a prefix before it as I did it in my example, you trick the fuzzy search and you can prioritize the non-prefixed completion.

I made another test with:

class TestListener(sublime_plugin.EventListener):
    def on_query_completions(self, view, positions, prefix):
        return [["HELLO_WORLD\t[HERE]", "hello_world"], ["ƒ hello_world\tSymbol from buffer", "hello_world"], ["⇄ hello_world\tOther Buffer", "hello_world"]]

In this case, if you type he, it triggers HELLO_WORLD first, then ƒ hello_world, then the other one. If you invert the last two, you invert also their order in the autocomplete list.

The point is that when a precise match isn’t found, the order you give is respected. Add to this, that proximity order is also respected, you have that adding this kind of symbols you could get what you want (words first, symbols from buffer next, words from other buffers last).

It depends on whether you want these symbols appearing in the autocomplete list or not, but from the small test I made, it can work. The problem is that If there are other plugins that add their own completions, it can be chaotic indeed.

A command that toggles autocomplete for all buffers (and optionally disables it automatically after completion) would also work for that, maybe in a simpler way(no need to hide the panel and call it again).

3 Likes