Skip to content
This repository has been archived by the owner on Jan 27, 2022. It is now read-only.
cbarrete edited this page Feb 9, 2021 · 17 revisions

Creating a source

With nvim-compe, creating a custom source is extremely easy and straight forward thanks to compe#register_source('source name', dict) function. All you need to create your new custom source is a dict that defines three methods, namely:

  • get_metadata
  • determine
  • complete
  • resolve (optional)
  • documentation (optional)
  • confirm (optional)

Below is an overview of what is expected from each of those methods

Overview

get_metadata

get_metadata must return dict that defines the source's metadata.

The metadata can have one or all of the following fields ...

  • dup: 1 | 0 see :help complete-items
    • This field is used to specify whether to display other items with the same word.
  • menu: string see :help complete-items
  • priority: number
    • This field is important for nvim-compe's filtering mechanism, the higher the number for displaying top of pum.
  • sort: boolean
    • This uses nvim-compe's filtering implementation.
    • The items do not sort so the source should sort items manually.
  • filetypes: list | table
    • This field is useful for filetype specific sources.
    • If this field was specified, nvim-compe will completion on only specified filetypes.

determine

determine method must return { keyword_pattern_offset?: number, trigger_character_offset?: number } (it specifies the popup menu position).

If this method doesn't do anything, completion will not be triggered.

The keyword_pattern_offset means pum position. In PHP, When the line is $|, keyword_pattern_offset should 1 (it means it should includes $ as a keyword).

complete

The complete method should complete items and callback it.

documentation (optional)

The documentation method should complete items and call the callback and give it an argument of a list or table. See nvim_lsp source or snippets.nvim source for examples.

resolve (optional)

The resolve method can be used to resolve the current selected item. It will useful to you callback all items as quickly and provide documentation for them later.

confirm (optional)

The confirm method gets executed when you confirm a completion item. Useful for snippets completion item and LSP expansion. See vsnip source or snippets.nvim source for examples.

Examples

In Vim script

function! s:get_metadata(...) abort
  return {
  \   'priority': 10,
  \   'menu': '[MY CUSTOM SOURCE]',
  \ }
endfunction

function! s:determine(context) abort
  return compe#helper#determine(a:context)
endfunction

function! s:complete(context) abort
  call a:context.callback({
  \   'items': [
  \     { 'word': 'January' },
  \     { 'word': 'February' },
  \     { 'word': 'March' },
  \     { 'word': 'April' },
  \     { 'word': 'May' },
  \     { 'word': 'June' },
  \     { 'word': 'July' },
  \     { 'word': 'August' },
  \     { 'word': 'September' },
  \     { 'word': 'October' },
  \     { 'word': 'November' },
  \     { 'word': 'December' },
  \   ]
  \ })
endfunction

function! s:documentation(args) abort
  let l:doc = {
     'January': 'Documentation for January';
     'February': 'Documentation for February';
     'March': 'Documentation for March';
     'April': 'Documentation for April';
     'May': 'Documentation for May';
     'June': 'Documentation for June';
     'July': 'Documentation for July';
     'August': 'Documentation for August';
     'September': 'Documentation for September';
     'October': 'Documentation for October';
     'November': 'Documentation for November';
     'December': 'Documentation for December';
  }

  " will show the current selected item documentation
  context.callback([doc[a:args.completed_item.word]])
endfunction

function Source.confirm(self, args)
  -- to special stuff here like snippets expansion for example
end

let s:source = {
\   'get_metadata': function('s:get_metadata'),
\   'determine': function('s:determine'),
\   'complete': function('s:complete'),
\   'documentation': function('s:documentation'),
\   'confirm': function('s:confirm'),
\ }

" Register your custom source.
call compe#register_source('month', s:source)

In Lua

The most simple source can be created by the below example of codes.

local compe = require'compe'
local Source = {}

function Source.new()
  return setmetatable({}, { __index = Source })
end

function Source.get_metadata(self)
  return {
    priority = 10;
    menu = '[MY CUSTOM SOURCE]';
  }
end

function Source.determine(self, context)
  return compe.helper.determine(context)
end

function Source.complete(self, context)
  context.callback({
    items = {
      { word = 'January'; };
      { word = 'February'; };
      { word = 'March'; };
      { word = 'April'; };
      { word = 'May'; };
      { word = 'June'; };
      { word = 'July'; };
      { word = 'August'; };
      { word = 'September'; };
      { word = 'October'; };
      { word = 'November'; };
      { word = 'December'; };
    };
  })
end

function Source.documentation(self, context)
  local doc = {
     January = 'Documentation for January';
     February = 'Documentation for February';
     March = 'Documentation for March';
     April = 'Documentation for April';
     May = 'Documentation for May';
     June = 'Documentation for June';
     July = 'Documentation for July';
     August = 'Documentation for August';
     September = 'Documentation for September';
     October = 'Documentation for October';
     November = 'Documentation for November';
     December = 'Documentation for December';
  }

  -- will show the current selected item documentation
  context.callback({ doc[context.completed_item.word] })
end

function Source.confirm(self, context)
  -- to special stuff here like snippets expansion for example
end

-- Register your custom source.
compe.register_source('month', Source)

Examples:

Q/A

What are the use cases where determine, Should return an empty object?

  • E.g. in the different file type.
  • E.g. for invalid line.