Skip to content

Conversation

roxma
Copy link
Member

@roxma roxma commented Jul 14, 2018

The key is

            \ 'matcher': {'name': 'combine',
            \           'matchers': [
            \               {'name': 'abbrfuzzy', 'key': 'menu'},
            \               {'name': 'prefix', 'key': 'word'},
            \           ]},

Demo:

rec

test files from #22 (comment)

minimal vimrc:

execute 'source ' . $WORKSPACE_DIR . '/plug.vim'

call plug#begin($WORKSPACE_DIR)

Plug 'roxma/nvim-yarp'
Plug 'ncm2/ncm2'
Plug 'lervag/vimtex'
Plug 'ncm2/ncm2-match-highlight'

call plug#end()

au BufEnter * call ncm2#enable_for_buffer()
au User Ncm2Plugin call ncm2#register_source({
            \ 'name' : 'vimtex',
            \ 'priority': 1,
            \ 'subscope_enable': 1,
            \ 'complete_length': 1,
            \ 'scope': ['tex'],
            \ 'matcher': {'name': 'combine',
            \           'matchers': [
            \               {'name': 'abbrfuzzy', 'key': 'menu'},
            \               {'name': 'prefix', 'key': 'word'},
            \           ]},
            \ 'mark': 'tex',
            \ 'word_pattern': '\w+',
            \ 'complete_pattern': g:vimtex#re#ncm,
            \ 'on_complete': ['ncm2#on_complete#omni', 'vimtex#complete#omnifunc'],
            \ })
set completeopt=noinsert,menuone,noselect

set noshowmode

Comments? @clason @balta2ar

@clason
Copy link

clason commented Jul 14, 2018

That's neat! Matching on the title seems to work quite nicely (although I think I personally would prefer substr over abbrfuzzy), but I'm having trouble matching some of the author names if there are multiple names in an entry such as

@article{A2,
  author = {Author, A. and Cuthor, C.},
  journal = {Very Good Journal},
  year = {2008},
  title = {Bravo},
}

This should match on Au, Cu, Br, but current only Br (and A, probably because of Bravo) works. (It's not quite consistent -- some work, some don't.)

Or is it currently by design that only the last field is considered? I should add that this is also a great improvement for another omnifun completion in vimtex, \label{, which already work nicely -- probably because there's only one field in the menu.)

@roxma
Copy link
Member Author

roxma commented Jul 14, 2018

The author field passed by vimtex is in abbr field. This is kind of wired for me. But with this PR it's easy to filter the abbr field too.

{"word": "A1", "menu": "[tex] Alpha", "info": "", "kind": "", "abbr": "[a] Author (2001)"}

@clason
Copy link

clason commented Jul 14, 2018

Oh, I see! Then it makes sense. Using

       \ 'matcher': {'name': 'combine',
        \           'matchers': [
        \               {'name': 'substr', 'key': 'word'},
        \               {'name': 'substr', 'key': 'abbr'},
        \               {'name': 'substr', 'key': 'menu'},
        \           ]},

matches everything correctly (and a few things that are a nuisance like the [a], but that can't be helped). I'll check with @lervag for the abbr field.

Out of curiosity, how can I output the string in your last comment for other omnifun completions? Then I can check this for \label{ as well (which requires generated output files for completion, so a MWE would be a bit more tedious).

@roxma
Copy link
Member Author

roxma commented Jul 14, 2018

how can I output the string in your last comment for other omnifun completions? Then I can check this for \label{ as well (which requires generated output files for completion, so a MWE would be a bit more tedious).

After the item gets completed, press <esc> to go back normal mode, then execute the command :echo v:completed_item

@clason
Copy link

clason commented Jul 14, 2018

Thanks, that's helpful. For the record, here's an example of omnifun's \label{ completion:

{'word': 'sec:introduction', 'menu': '[tex]     (1) [p. 1]', 'user_data': '{"source": "vimtex", "ncm
2": 1, "is_snippet": 0, "snippet": "", "match_key": "word", "match_highlight": [[0, 16]]}', 'info':
'', 'kind': '', 'abbr': 'sec:introduction'}

and an example for command completion:

{'word': 'cite', 'menu': '[tex] [cmd: default] ', 'user_data': '{"source": "vimtex", "ncm2": 1, "is_
snippet": 0, "snippet": "", "match_highlight": [[0, 4]], "match_key": "word"}', 'info': '', 'kind':
'', 'abbr': 'cite'}

This explains why I didn't have problems with those earlier, since they do contain a user_data field (any idea why the other one might not have?); (sorry, just noticed that it's in fact there and you just did not copy it to your comment) It also seems that if it's possible to get vimtex to fill the kind field appropriately, one could have different behaviours (e.g., prefix for commands vs. substring for labels and bibitems vs. abbrvfuzzy for paths) depending on what is completed? That could be really useful!

EDIT By the way, I looked at :h complete-items -- the difference is that abbrv is shown instead of word, while menu is shown in addition to word. Since for BibTeX, the word is an arbitrary (unique) alphanumeric key, the author list (abbrv) is indeed more helpful for selecting (and key, author list, and title would likely be too long to display). So the way vimtex handles this does make sense.

@clason
Copy link

clason commented Jul 14, 2018

A question: How are the matches sorted if multiple matchers match (heh)? I.e., if I have

  \ 'matcher': {'name': 'combine',
        \           'matchers': [
        \               {'name': 'prefix', 'key': 'word'},
        \               {'name': 'substr', 'key': 'abbr'},
        \               {'name': 'abbrvfuzzy', 'key': 'menu'},
        \           ]},

there are three items with

{'word': 'Alpha', ...}
{'abbr': 'Balpha',...}
{'menu': 'Because all perfect horses are',...}

and I try to match alpha (assuming all of the not shown fields are irrelevant), in what order will the matches be shown in the popup menu? prefix before substr before abbrvfuzzy? or in the order I listed the matchers in the combine list? or sorted in some other way? (Either of the first two would be best for me, I think, with the second one more general.)

@roxma
Copy link
Member Author

roxma commented Jul 14, 2018

: How are the matches sorted if multiple matchers match (heh)?

This is kind of hard to solve.

But current abbrfuzzy sorter implementation do perfers prefix match over substr, and then over general abbrfuzzy.

See https://github.com/ncm2/ncm2/blob/master/pythonx/ncm2_sorter/abbrfuzzy.py#L25

The sort priority is

  1. peices of match
  2. the position of the first match character
  3. the length of the match span
  4. alphanum

@clason
Copy link

clason commented Jul 14, 2018

So the combine matcher combines all matches in a single list, which is then sorted with a single sorter (abbrvfuzzy by default)? That's perfectly OK, although it might be useful to take into account which key is matched (word before abbr before menu) -- if this is possible; multi-criteria ranking is indeed hard...

But even in its current form, this is already a big improvement in functionality for me, and I'd be happy to see it merged!

@clason
Copy link

clason commented Jul 14, 2018

Regarding different configurations for different kind fields: Is this in principle possible (e.g., by registering different sources with a filter on kind)? Then I would open a different issue for this feature request. (Asking here first to avoid spamming the issue tracker...)

@roxma
Copy link
Member Author

roxma commented Jul 14, 2018

@clason

I'm not sure what you want. You should open an issue and elaborate the expecting behavior.

@clason
Copy link

clason commented Jul 14, 2018

@roxma Sorry, I should have been clearer. Briefly, depending on the context, vimtex's omnifun can return different completed items such as

{'word': 'sec:introduction', 'menu': '[tex]     (1) [p. 1]', 'user_data': '{"source": "vimtex", "ncm2": 1, "is_snippet": 0, "snippet": "", "match_key": "word", "match_highlight": [[0, 16]]}', 'info': '', 'kind': 'label', 'abbr': 'sec:introduction'}

and

{'word': 'Allaire2004}', 'menu': 'Structural optimization using sensitivity analysis and a level-set method', 'user_data': '{"source": "vimtex", "ncm2": 1, "is_snippet": 0, "snippet": "", "match_key": "word", "match_highlight": [[0, 1]]}','info': '', 'kind': 'bib', 'abbr': '[a]   Allaire et al. (2004)'}

(note the different 'kind' fields). I would like to (for simplicity say) match the former substr on word and menu, while I only want to match the latter prefix on word and abbrvfuzzy on menu.

But I think I can get most of what I want by modifying things on the vimtex side; if that's not enough (or you think that it might be useful for others), I'll open a new issue. From my side, this PR is good as is.

@lervag
Copy link

lervag commented Jul 18, 2018

I just want to add that I like how this is progressing. I will definately look closer into ncm2 and might swap out deoplete if I'm properly convinced!

@roxma roxma mentioned this pull request Jul 28, 2018
@clason
Copy link

clason commented Aug 5, 2018

Since this issue is linked from the wiki, here's the full ncm2-vimtex config as in :help vimtex-complete-ncm2 for reference:

 au InsertEnter * call ncm2#enable_for_buffer()
    au Filetype tex call ncm2#register_source({
        \ 'name' : 'vimtex-cmds',
        \ 'priority': 8, 
        \ 'complete_length': -1,
        \ 'scope': ['tex'],
        \ 'matcher': {'name': 'prefix', 'key': 'word'},
        \ 'word_pattern': '\w+',
        \ 'complete_pattern': g:vimtex#re#ncm2#cmds,
        \ 'on_complete': ['ncm2#on_complete#omni', 'vimtex#complete#omnifunc'],
        \ })
    au Filetype tex call ncm2#register_source({
        \ 'name' : 'vimtex-labels',
        \ 'priority': 8, 
        \ 'complete_length': -1,
        \ 'scope': ['tex'],
        \ 'matcher': {'name': 'combine',
        \             'matchers': [
        \               {'name': 'substr', 'key': 'word'},
        \               {'name': 'substr', 'key': 'menu'},
        \             ]},
        \ 'word_pattern': '\w+',
        \ 'complete_pattern': g:vimtex#re#ncm2#labels,
        \ 'on_complete': ['ncm2#on_complete#omni', 'vimtex#complete#omnifunc'],
        \ })
    au Filetype tex call ncm2#register_source({
        \ 'name' : 'vimtex-files',
        \ 'priority': 8, 
        \ 'complete_length': -1,
        \ 'scope': ['tex'],
        \ 'matcher': {'name': 'combine',
        \             'matchers': [
        \               {'name': 'abbrfuzzy', 'key': 'word'},
        \               {'name': 'abbrfuzzy', 'key': 'abbr'},
        \             ]},
        \ 'word_pattern': '\w+',
        \ 'complete_pattern': g:vimtex#re#ncm2#files,
        \ 'on_complete': ['ncm2#on_complete#omni', 'vimtex#complete#omnifunc'],
        \ })
    au Filetype tex call ncm2#register_source({
        \ 'name' : 'bibtex',
        \ 'priority': 8, 
        \ 'complete_length': -1,
        \ 'scope': ['tex'],
        \ 'matcher': {'name': 'combine',
        \             'matchers': [
        \               {'name': 'prefix', 'key': 'word'},
        \               {'name': 'abbrfuzzy', 'key': 'abbr'},
        \               {'name': 'abbrfuzzy', 'key': 'menu'},
        \             ]},
        \ 'word_pattern': '\w+',
        \ 'complete_pattern': g:vimtex#re#ncm2#bibtex,
        \ 'on_complete': ['ncm2#on_complete#omni', 'vimtex#complete#omnifunc'],
        \ })

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

Successfully merging this pull request may close these issues.

3 participants