├── LICENSE ├── README.md ├── after └── plugin │ └── cmp_vsnip.lua └── lua └── cmp_vsnip └── init.lua /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 hrsh7th 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cmp-vsnip 2 | 3 | nvim-cmp source for [vim-vsnip](https://github.com/hrsh7th/vim-vsnip) 4 | 5 | # Setup 6 | 7 | ```lua 8 | require'cmp'.setup { 9 | sources = { 10 | { name = 'vsnip' } 11 | } 12 | } 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /after/plugin/cmp_vsnip.lua: -------------------------------------------------------------------------------- 1 | require('cmp').register_source('vsnip', require('cmp_vsnip').new()) 2 | -------------------------------------------------------------------------------- /lua/cmp_vsnip/init.lua: -------------------------------------------------------------------------------- 1 | local cmp = require('cmp') 2 | 3 | local source = {} 4 | 5 | source.new = function() 6 | return setmetatable({}, { __index = source }) 7 | end 8 | 9 | source.is_available = function() 10 | return vim.g.loaded_vsnip 11 | end 12 | 13 | source.get_position_encoding_kind = function() 14 | return 'utf-8' 15 | end 16 | 17 | source.get_keyword_pattern = function() 18 | return '.' 19 | end 20 | 21 | source.complete = function(self, params, callback) 22 | local completion_items = {} 23 | 24 | for _, item in ipairs(vim.fn['vsnip#get_complete_items'](vim.api.nvim_get_current_buf())) do 25 | local completion_item = {} 26 | local user_data = vim.fn.json_decode(item.user_data) 27 | local text_edit = self:_get_text_edit(params, item.word, user_data.vsnip) 28 | if text_edit then 29 | completion_item.label = item.abbr 30 | completion_item.filterText = item.word 31 | completion_item.insertTextFormat = cmp.lsp.InsertTextFormat.Snippet 32 | completion_item.textEdit = text_edit 33 | completion_item.kind = cmp.lsp.CompletionItemKind.Snippet 34 | completion_item.data = { 35 | filetype = params.context.filetype, 36 | snippet = user_data.vsnip.snippet, 37 | } 38 | table.insert(completion_items, completion_item) 39 | end 40 | end 41 | 42 | callback(completion_items) 43 | end 44 | 45 | source.resolve = function(_, completion_item, callback) 46 | local documentation = {} 47 | table.insert(documentation, string.format('```%s', completion_item.data.filetype)) 48 | for _, line in ipairs(vim.split(vim.fn['vsnip#to_string'](completion_item.data.snippet), '\n')) do 49 | table.insert(documentation, line) 50 | end 51 | table.insert(documentation, '```') 52 | 53 | completion_item.documentation = { 54 | kind = cmp.lsp.MarkupKind.Markdown, 55 | value = table.concat(documentation, '\n'), 56 | } 57 | callback(completion_item) 58 | end 59 | 60 | source._get_text_edit = function(_, params, prefix, snippet) 61 | local chars = vim.fn.split(vim.fn.escape(prefix, [[\/?]]), [[\zs]]) 62 | local chars_pattern = [[\%(\V]] .. table.concat(chars, [[\m\|\V]]) .. [[\m\)]] 63 | local separator = chars[1]:match('%a') and [[\<]] or '' 64 | local whole_pattern = ([[%s\V%s\m%s*$]]):format(separator, chars[1], chars_pattern) 65 | local regex = vim.regex(whole_pattern) 66 | local s, e = regex:match_str(params.context.cursor_before_line) 67 | if not s then 68 | return 69 | end 70 | return { 71 | newText = table.concat(snippet.snippet, '\n'), 72 | range = { 73 | start = { 74 | line = params.context.cursor.line, 75 | character = s, 76 | }, 77 | ['end'] = { 78 | line = params.context.cursor.line, 79 | character = e, 80 | }, 81 | }, 82 | } 83 | end 84 | 85 | return source 86 | --------------------------------------------------------------------------------