Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sublime Text autocomplete window closes when scrolling off the list

When scrolling the autocomplete list with up or down, if you go too far in either direction (e.g. there are no more suggestions), the list will close.

The behavior I want is to have the list wrap when reaching the end instead of close.

This is easy to fix with downward scrolling by assigning this hotkey:

{ "keys": ["down"], "command": "auto_complete", "context":
    [ { "key": "auto_complete_visible" } ]
},

That's because the auto_complete command has built-in functionality to scroll downward each time it's invoked, which is why the hotkey works.

...But upward scrolling is different. I've tried about 20 different hotkey and macro combinations with no success.

I'm almost certain the only way to achieve this behavior is with a plugin, but unfortunately my Python skill level is nil.

If it matters, I'm manually invoking autocomplete with ctrl+space (the automatic popup is disabled).

I'm using Sublime Text 2.

like image 290
Jeff Avatar asked Aug 12 '14 12:08

Jeff


1 Answers

Best solution: use auto_complete_cycle settings (added 26 March 2015):

Please use this new simple solution and not the python plugin

Sublime Text new version relased on 24 March 2015 has a new setting called auto_complete_cycle that implement this behaviour. Set it to true to iterate through the autocomplete results.

"auto_complete_cycle": true

Worst old solution: this custom plugin

I have just made this plugin that works well on Sublime Text 3 in Linux Mint. I have not tested it in Sublime Text 2 but think the plugin system it's the same, so, it should work on that version too. The workaround used it's not too pretty but works.

import sublime, sublime_plugin

class UpArrowInAutoCompleteCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.settings().set('autoCompleteFlag',True)
        self.view.settings().set('initialPoint', self.view.sel()[0].begin())

        """ Move one line up """
        self.view.run_command('move', {"by": "lines", "forward": False});
        """ Auto-complete was opened and up arrow was pressed, so if the cursor changes
        (on_selection_modified will be triggered) we have gone outside the list. 
        If we were not in the first element on_selection_modified will not be triggered, so
        we turn of the flag"""
        sublime.set_timeout(lambda: self.view.settings().set('autoCompleteFlag', False),300)


class AutoCompleteSelectionModifiedTriggerCommand(sublime_plugin.EventListener):
    def on_selection_modified(self, view):
        if view.settings().get('autoCompleteFlag'):
            """ If the up arrow was pressed and on_selection_modified 
            has been triggered, then we know that we were in the first element
            of the list and we hitted the up arrow"""
            view.settings().set('autoCompleteFlag', False)
            initialPoint = view.settings().get('initialPoint')

            """ We don't know how many words the auto_complete has, so, 
            in order to calculate that number, we move down in the list
            till we get outside the list. After that we make the list appear
            again and move down n-1 times to go (and stay) to the last line """
            view.sel().clear()
            view.sel().add(initialPoint)
            view.run_command('auto_complete')

            numLines = 0
            while view.sel()[0].begin() == initialPoint:
                view.run_command('move', {"by": "lines", "forward": True})
                numLines += 1
                if numLines == 401:
                    return

            if numLines == 0:
                return

            view.sel().clear()
            view.sel().add(initialPoint)
            view.run_command('auto_complete')

            numLine = 0
            while numLine < (numLines-1):
                view.run_command('move', {"by": "lines", "forward": True})
                numLine += 1

To make the plugin use Tools>new Plugin and paste the code. Then save it in Packages/User folder. You can use Preferences>Browse Packages to find the Packages floder, inside which the User folder is located.

To make it work I added to my user key-bindings file this bindings (the second it's your own binding):

{
    "keys": ["up"],
    "command": "up_arrow_in_auto_complete",
    "context": [{
        "key": "auto_complete_visible",
        "operator": "equal",
        "operand": true
    }]
}, {
    "keys": ["down"],
    "command": "auto_complete",
    "context": [{
        "key": "auto_complete_visible"
    }]
}

Edit: this is an example result:

Result

like image 176
sergioFC Avatar answered Sep 21 '22 20:09

sergioFC