roxma / nvim-completion-manager

:warning: PLEASE USE https://github.com/ncm2/ncm2 INSTEAD
MIT License
917 stars 49 forks source link

Trigger refresh after character #60

Closed SevereOverfl0w closed 7 years ago

SevereOverfl0w commented 7 years ago

The completion engine I'm using will generate more completions once you've added the namespace. I couldn't seem to figure out the correct setting so that typing:

clojure.core then / will trigger a refresh.

Also pressing . can do the same sort of thing.

I tried: cm_refresh_patterns=[r'/.*$'] but it didn't seem to have the behaviour I wanted.

roxma commented 7 years ago

I tried: cm_refresh_patterns=[r'/.*$'] but it didn't seem to have the behaviour I wanted.

I think the pattern should work,

If you mean something is wrong with NCM, you could provied the log file nvim.log_py3_cm_core, following the stpes in the trouble-shooting section of README.md.

I'm not sure what's wrong here, I would like to see more details, eg, a minimal vimrc and how you reproduce the undesired behavior.

SevereOverfl0w commented 7 years ago

I did some debugging at the time, and via logs I couldn't see my refresh function being called when hitting /. I did see it being called when I initially started typing though.

I'm not sure if it's an NCM bug or in my implementation of a source.

This is the source: https://github.com/clojure-vim/async-clj-omni/blob/master/pythonx/cm_sources/fireplace.py Anything that I'm obviously doing wrong?

roxma commented 7 years ago

I did see it being called when I initially started typing though.

This is a NCM feature for speed optimization, see :help NCM-early_cach. This does not affect the expected behavior.

I did some debugging at the time, and via logs I couldn't see my refresh function being called when hitting /.

I did see the cm_refresh being called with cm_refresh_patterns=[r'/$'], when / is typed.

# -*- coding: utf-8 -*-

import sys
import os

basedir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.normpath(os.path.join(basedir, "../../rplugin/python3/deoplete/sources/vim_nrepl_python_client")))
from async_clj_omni import fireplace

from cm import register_source, getLogger, Base
register_source(name='fireplace',
                abbreviation='🔥',
                scopes=['clojure'],
                cm_refresh_patterns=[r'/$'],
                word_pattern=r'[\w!$%&*+:<=>?@\^_~\-\.#]+',
                priority=9)

import re

class Source(Base):
    def __init__(self,nvim):
        super(Source,self).__init__(nvim)
        self._nvim = nvim
        self._cider_completion_manager = fireplace.CiderCompletionManager(getLogger(__name__), nvim)

    def cm_refresh(self,info,ctx):
        # matches = ['foo_bar','foo_baz', 'req$\'uire']
        getLogger(__name__).debug('Running a refresh…')
        # matches = self._cider_completion_manager.gather_candidates(re.search(info['word_pattern'], ctx['typed']).group(0))
        matches = ['abcdef']
        logger = getLogger(__name__)
        logger.info('matches: %s', matches)
        self._nvim.call('cm#complete', info['name'], ctx, ctx['startcol'], matches, async=True)

By the way, I saw the word_pattern=r'[\w!$%&*+/:<=>?@\^_~\-\.#]+', includes the / character. The word_pattern is used to calculate startcol, which means abc/ will have ctx['startcol'] as 1, and the completion candidate need to include the abc/ prefix. I'm not sure this is what you intended to do. (I had a hard time setting up fireplace completion engine)

roxma commented 7 years ago

One more thing, I would recommend putting the register_source in front of import sys, NCM uses a trick to prevent the loading of the whole python module before the source is activated, and it would allow faster startup for NCM.

# Please register source before executing any other code, this allow cm_core to
# read basic information about the source without loading the whole module, and
# modules required by this module
from cm import register_source, getLogger, Base
SevereOverfl0w commented 7 years ago

By the way, I saw the wordpattern=r'[\w!$%&*+/:<=>?@\^~-.#]+', includes the / character.

I need the / to be included for my completion, (the completion engine wants to see clojure.core/d). I just experimented with removing it. I observed that whilst typed is clojure.core/d, the insert position (startcol?) is after the / ( I guess because it's no longer matching the clojure.core ).

My intent might not be clear here, this is similar to accessing a module in python, but the engine only does the work after you type module/ then it will fetch results for inside module.

roxma commented 7 years ago

To make it clear, the word_pattern here does not affect the ctx['typed'], it affects ctx['base'] and ctx['startcol'].

With word_pattern=r'[\w!$%&*+/:<=>?@\^_~\-\.#]+', abc/ will have startcol as 1 and base as abc/

Without / in the pattern, abc/ will have startcol as 5, and base as ''.

ctx['typed'] is always abc/.

SevereOverfl0w commented 7 years ago

I see a refresh when word_pattern does NOT contain /. I do not see a refresh when it does contain /. Is this expected behaviour? I think this is where my confusion is founded.

With wordpattern=r'[\w!$%&*+/:<=>?@\^~-.#]+', abc/ will have startcol as 1 and base as abc/

This is the behaviour I want. I did not realise there was a 'base' key.

roxma commented 7 years ago

I see a refresh when word_pattern does NOT contain /. I do not see a refresh when it does contain /. Is this expected behaviour? I think this is where my confusion is founded.

When the pattern does not contain /, you're starting a new word after you typed /, NCM will trigger a new cm_refresh for the new word.

By default, the cm_refresh is triggered after the first character you typed matching the word pattern, and the result will be cached by NCM.

But the popup menu is displayed after certain amout ot characters being typed, or cm_refresh_patterns being matched.

SevereOverfl0w commented 7 years ago

ah! I understand the basic example now I believe. I had thought the refresh_pattern was for triggering a refresh mid-word. Is there any way to do such a thing? Or will I need to fall back on parsing the typed field to find the full string I wish to complete on?

roxma commented 7 years ago

Currently doesn't support triggering a refresh mid-word with the pattern.

But you could use refresh=1 when submitting the candidates with the cm#complete function (:help cm#complete()

roxma commented 7 years ago

I think the best solution is to remove the / character in the word_pattern for NCM, since NCM is caching the candidates by word.

You could feed a different word_pattern to the completion engine, and then calculate startcol on your own, which would be as simple as ctx['col'] - len(word).