Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-completion not working properly with special characters #13618

Open
emanuelelaface opened this issue Apr 1, 2022 · 0 comments
Open

Auto-completion not working properly with special characters #13618

emanuelelaface opened this issue Apr 1, 2022 · 0 comments

Comments

@emanuelelaface
Copy link

When there is a character that can be interpreted as an operator in Python the customized autocomplete fails to work as expected.
This is an example:

from IPython import get_ipython

def my_completer(ipython, event):
    word = event.line.strip().split()[-1]
        
    result = ['testaa','test_bb','test-cc','test*dd', 'test:ee']
    return result

ipython = get_ipython()
ipython.set_hook('complete_command', my_completer, re_key='test.*')

If one tries to complete testa it correctly gives testaa but if one tries to complete test:e it fails to complete to test:ee as expected.

After asking help to @Carreau he told me that the current API does not support such characters and he gave me a workaround as the following (in reality his example is more elegant in the way to detect the text but for this example I'd like to keep it less dependent by libraries, anyway the idea is the same).

from IPython.core.completer import IPCompleter, Completion
import types

def my_completer(self, full_text: str, offset: int, *, _timeout):    
    if full_text.count('"') == 0 and full_text.count("'") == 0:
        yield from original_method(self, full_text, offset, _timeout=_timeout)
        return

    start_position = 0
    end_position = len(full_text)
    
    for i in range(offset-1,-1,-1):
        if full_text[i] == "'" or full_text[i] == '"':
            start_position = i+1
            break
    for i in range(offset-1,len(full_text)):
        if full_text[i] == "'" or full_text[i] == '"':
            end_position = i
            break
    
    word=full_text[start_position:end_position]    
    search_list = ['testaa','test_bb','test-cc','test*dd', 'test:ee']
    
    for item in search_list:
        if word in item:
            yield Completion(start_position, end_position, item, type='string',  _origin='jedi', signature='')

    yield from original_method(self, full_text, offset, _timeout=_timeout)

if getattr(IPCompleter,'_patched', False) == False:
    original_method = IPCompleter._completions 
    IPCompleter._patched = True

IPCompleter._completions = my_completer

ipython = get_ipython()
ipython.Completer._completions = types.MethodType(my_completer, ipython.Completer)

I think it can be useful to have this working as in the first example in a further version of the code.
Thanks again to Matthias!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant