Repository: hrsh7th/cmp-nvim-lsp-document-symbol Branch: main Commit: f94f7ba948e3 Files: 3 Total size: 3.1 KB Directory structure: gitextract_njgrgwbc/ ├── README.md ├── after/ │ └── plugin/ │ └── cmp_nvim_lsp_document_symbol.lua └── lua/ └── cmp_nvim_lsp_document_symbol/ └── init.lua ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # cmp-nvim-lsp-document-symbol nvim-cmp source for textDocument/documentSymbol via nvim-lsp. The purpose is the demonstration customize `/` search by nvim-cmp. # Setup ```lua require'cmp'.setup.cmdline('/', { sources = cmp.config.sources({ { name = 'nvim_lsp_document_symbol' } }, { { name = 'buffer' } }) }) ``` ================================================ FILE: after/plugin/cmp_nvim_lsp_document_symbol.lua ================================================ require('cmp').register_source('nvim_lsp_document_symbol', require('cmp_nvim_lsp_document_symbol').new()) ================================================ FILE: lua/cmp_nvim_lsp_document_symbol/init.lua ================================================ local source = {} local SymbolKind = { [1] = 'File', [2] = 'Module', [3] = 'Namespace', [4] = 'Package', [5] = 'Class', [6] = 'Method', [7] = 'Property', [8] = 'Field', [9] = 'Constructor', [10] = 'Enum', [11] = 'Interface', [12] = 'Function', [13] = 'Variable', [14] = 'Constant', [15] = 'String', [16] = 'Number', [17] = 'Boolean', [18] = 'Array', [19] = 'Object', [20] = 'Key', [21] = 'Null', [22] = 'EnumMember', [23] = 'Struct', [24] = 'Event', [25] = 'Operator', [26] = 'TypeParameter', } source.new = function() return setmetatable({}, { __index = source }) end source.is_available = function(self) return self:_get_client() ~= nil end source.get_keyword_pattern = function() return [=[@.*]=] end source.get_trigger_characters = function() return { '@' } end source.complete = function(self, _, callback) local client = self:_get_client() client.request('textDocument/documentSymbol', { textDocument = vim.lsp.util.make_text_document_params() }, function(err, res) if err then return callback() end local items = {} local traverse traverse = function(nodes, level) level = level or 0 for _, node in ipairs(nodes) do local kind_name = SymbolKind[node.kind] if vim.tbl_contains({ 'Module', 'Namespace', 'Object', 'Class', 'Interface', 'Method', 'Function' }, kind_name) then -- node may be LSP DocumentSymbol or SymbolInformation (deprecated) local range = node.selectionRange or node.range or (node.location or {}).range if range ~= nil then local line = vim.api.nvim_buf_get_lines(0, range.start.line, range.start.line + 1, false)[1] or '' table.insert(items, { label = ('%s%s'):format(string.rep(' ', level), string.gsub(line, '^%s*', '')), insertText = ('\\%%%sl'):format(range.start.line + 1), filterText = '@' .. node.name, sortText = '' .. range.start.line, kind = node.kind, data = node, }) traverse(node.children or {}, level + 1) end end end end traverse(res or {}) callback(items) end) end source._get_client = function(self) for _, client in pairs(vim.lsp.get_clients({ bufnr = 0 })) do if self:_get(client.server_capabilities, { 'documentSymbolProvider' }) then return client end end return nil end source._get = function(_, root, paths) local c = root for _, path in ipairs(paths) do c = c[path] if not c then return nil end end return c end return source