Skip to content
This repository was archived by the owner on Jan 27, 2022. It is now read-only.
elianiva edited this page Jan 31, 2021 · 17 revisions

Creating a source

With nvim-compe, creating a custom source is extremely easy and straight forward thanks to compe#source#vim_bridge#register('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
  • 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.

confirm (optional)

The confirm method gets executed when you confirm a completion item. Useful for snippets completion item. 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
  let l:keyword_pattern_offset = compe#pattern#get_keyword_pattern_offset(a:context)
  if l:keyword_pattern_offset > 0
    return {
    \   'keyword_pattern_offset': l:keyword_pattern_offset
    \ }
  endif
  return {}
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#source#vim_bridge#register('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_lua_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.

Clone this wiki locally