diff --git a/README.md b/README.md index c40e101..95117a8 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,45 @@ vim.api.nvim_set_keymap("s", "", "v:lua.s_tab_complete()", {expr = true}) Use `compe#confirm()` mapping, as described in section [Mappings](#mappings). +## Advanced configuration + +If you want to customize how compe displays completion options, compe allows you +to run custom formatting code before the list get's displayed. +For this, use the `formatting_functions` configuration option. +Here you can functions for each provider to change the displayed data along the way. +Currently, there are two formatters you can set: + +- `results`: Change the list of completion results. +- `documentation`: Change the documentation text. + +For example, you could use a results formatter to show the type information +and other details in the completion list. +(Note that the `details` feature used here is not supported by many language servers.) + +```lua +formatting_functions = { + nvim_lsp = { + results = function(items) + local max_col_width = 0 + for _, item in ipairs(items) do + max_col_width = math.max(max_col_width, vim.fn.strwidth(item.abbr)) + end + for _, item in ipairs(items) do + local detail = item.user_data + and item.user_data.compe + and item.user_data.compe.completion_item + and item.user_data.compe.completion_item.detail + if detail then + local padding = string.rep(" ", max_col_width - vim.fn.strwidth(item.abbr) + 1) + item.abbr = item.abbr .. padding .. item.user_data.compe.completion_item.detail + end + end + return items + end + } +} +``` + ## Demo ### Auto Import diff --git a/doc/compe.txt b/doc/compe.txt index a8b82f1..14b5c4c 100644 --- a/doc/compe.txt +++ b/doc/compe.txt @@ -302,6 +302,40 @@ source ~ For dictionary, see |compe-source| for the list of source options. +formatting_functions ~ + Custom output formatting functions. Optional. + Type: |Dictionary| of: + Key: |String| + Source name. + For the list of builtin sources, see |compe-sources|. + Value: |Dictionary| of: + results ~ + This function get's called with the list of completion results + before displaying the list. + It takes and returns the list of completion results, + and may transform it. + Type: |Function| + Takes 1 argument: + completion_items: + Type: |Table| of completion items. + Returns: + The transformed list. + Type: |Table| of completion items. + + documentation ~ + This function get's called with the documentation of the + currently selected completion item, and may return the text + changed in any way. + Type: |Function| + Takes 1 argument: + document: + Type: |Table| of lines of the documentation text. + Returns: + The transformed documentation. + Type: |Table| of lines of the documentation text. + + + ------------------------------------------------------------------------------ HIGHLIGHT *compe-highlight* diff --git a/doc/tags b/doc/tags new file mode 100644 index 0000000..2827164 --- /dev/null +++ b/doc/tags @@ -0,0 +1,29 @@ +compe compe.txt /*compe* +compe#close() compe.txt /*compe#close()* +compe#complete() compe.txt /*compe#complete()* +compe#confirm() compe.txt /*compe#confirm()* +compe#helper compe.txt /*compe#helper* +compe#register_source() compe.txt /*compe#register_source()* +compe#setup() compe.txt /*compe#setup()* +compe#unregister_source() compe.txt /*compe#unregister_source()* +compe-concept compe.txt /*compe-concept* +compe-config compe.txt /*compe-config* +compe-custom-source compe.txt /*compe-custom-source* +compe-example compe.txt /*compe-example* +compe-features compe.txt /*compe-features* +compe-functions compe.txt /*compe-functions* +compe-highlight compe.txt /*compe-highlight* +compe-lua compe.txt /*compe-lua* +compe-options compe.txt /*compe-options* +compe-prerequisites compe.txt /*compe-prerequisites* +compe-quickstart compe.txt /*compe-quickstart* +compe-source compe.txt /*compe-source* +compe-sources compe.txt /*compe-sources* +compe-viml compe.txt /*compe-viml* +compe.helper compe.txt /*compe.helper* +compe.register_source() compe.txt /*compe.register_source()* +compe.setup() compe.txt /*compe.setup()* +compe.txt compe.txt /*compe.txt* +compe.unregister_source() compe.txt /*compe.unregister_source()* +g:compe compe.txt /*g:compe* +nvim-compe compe.txt /*nvim-compe* diff --git a/lua/compe/completion.lua b/lua/compe/completion.lua index 3f688bc..136d499 100644 --- a/lua/compe/completion.lua +++ b/lua/compe/completion.lua @@ -224,6 +224,12 @@ Completion._display = guard(function(context) for _, source in ipairs(sources) do if not has_triggered_by_character or source.is_triggered_by_character then local source_items = source:get_filtered_items(context) + + local formatter = Config.get_formatter(source.name, "results") + if formatter then + source_items = formatter(vim.deepcopy(source_items)) + end + if #source_items > 0 and start_offset == source:get_start_offset() then for _, item in ipairs(source_items) do if items_uniq[item.original_word] == nil or item.original_dup == 1 then diff --git a/lua/compe/config.lua b/lua/compe/config.lua index ca73816..7f563f3 100644 --- a/lua/compe/config.lua +++ b/lua/compe/config.lua @@ -32,6 +32,12 @@ Config.get = function() return Config._bufnrs[vim.api.nvim_get_current_buf()] or Config._config end +-- get_formatter +Config.get_formatter = function(source_name, subject) + local source_functions = Config.get().formatting_functions[source_name] + return source_functions and source_functions[subject] +end + --- get_metadata Config.get_metadata = function(source_name) return Config.get().source[source_name] @@ -60,6 +66,7 @@ Config._normalize = function(config) config.max_menu_width = config.max_menu_width or 100 config.autocomplete = Boolean.get(config.autocomplete, true) config.documentation = Boolean.get(config.documentation, true) + config.formatting_functions = config.formatting_functions or {} -- normalize source metadata if config.source then diff --git a/lua/compe/source.lua b/lua/compe/source.lua index 090c922..083e5f0 100644 --- a/lua/compe/source.lua +++ b/lua/compe/source.lua @@ -225,6 +225,11 @@ Source.documentation = function(self, completed_item) context = Context.new({}, {}); callback = Async.guard('Source.documentation#callback', vim.schedule_wrap(function(document) if document and #document ~= 0 then + + local formatter = Config.get_formatter(self.name, "documentation") + if formatter then + document = formatter(document) + end vim.call('compe#documentation#open', document) else vim.call('compe#documentation#close')