diff --git a/autoload/SpaceVim/layers/autocomplete.vim b/autoload/SpaceVim/layers/autocomplete.vim index 6700abbaf..3301c5fdc 100644 --- a/autoload/SpaceVim/layers/autocomplete.vim +++ b/autoload/SpaceVim/layers/autocomplete.vim @@ -107,6 +107,10 @@ function! SpaceVim#layers#autocomplete#plugins() abort \ 'merged' : 0, \ 'loadconf' : 1, \ }]) + call add(plugins, [g:_spacevim_root_dir . 'bundle/cmp-dictionary', { + \ 'merged' : 0, + \ 'loadconf' : 1, + \ }]) if g:spacevim_snippet_engine ==# 'neosnippet' call add(plugins, [g:_spacevim_root_dir . 'bundle/cmp-neosnippet', { \ 'merged' : 0, diff --git a/bundle/cmp-dictionary/.github/workflows/test.yml b/bundle/cmp-dictionary/.github/workflows/test.yml new file mode 100644 index 000000000..e665e445e --- /dev/null +++ b/bundle/cmp-dictionary/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: test + +on: + push: + branchs: + - main + paths: + - '**.lua' + +jobs: + integration: + runs-on: ubuntu-latest + steps: + + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup neovim + uses: rhysd/action-setup-vim@v1 + with: + version: nightly + neovim: true + + - name: Setup lua + uses: leafo/gh-actions-lua@v8 + with: + luaVersion: luajit-2.1.0-beta3 + + - name: Setup luarocks + uses: leafo/gh-actions-luarocks@v4 + + - name: Setup tools + shell: bash + run: | + luarocks --lua-version=5.1 install luacheck + luarocks --lua-version=5.1 install vusted + + - name: Run test + shell: bash + run: make diff --git a/bundle/cmp-dictionary/.gitignore b/bundle/cmp-dictionary/.gitignore new file mode 100644 index 000000000..0a56e3fc5 --- /dev/null +++ b/bundle/cmp-dictionary/.gitignore @@ -0,0 +1 @@ +/doc/tags diff --git a/bundle/cmp-dictionary/.luacheckrc b/bundle/cmp-dictionary/.luacheckrc new file mode 100644 index 000000000..84d0f03db --- /dev/null +++ b/bundle/cmp-dictionary/.luacheckrc @@ -0,0 +1,2 @@ +globals = { 'vim', 'describe', 'it', 'assert', 'before_each' } +max_line_length = false diff --git a/bundle/cmp-dictionary/LICENSE b/bundle/cmp-dictionary/LICENSE new file mode 100644 index 000000000..58475b533 --- /dev/null +++ b/bundle/cmp-dictionary/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 uga-rosa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bundle/cmp-dictionary/Makefile b/bundle/cmp-dictionary/Makefile new file mode 100644 index 000000000..911324f3f --- /dev/null +++ b/bundle/cmp-dictionary/Makefile @@ -0,0 +1,12 @@ +.PHONY: test vusted luacheck format + +test: luacheck vusted + +vusted: + vusted lua/ + +luacheck: + luacheck lua/ + +format: + stylua ./lua -g '!**/kit/**' diff --git a/bundle/cmp-dictionary/README.md b/bundle/cmp-dictionary/README.md new file mode 100644 index 000000000..5c54e585e --- /dev/null +++ b/bundle/cmp-dictionary/README.md @@ -0,0 +1,64 @@ +# cmp-dictionary + +A dictionary completion source for [nvim-cmp](https://github.com/hrsh7th/nvim-cmp). + +This plugin provides one of the easiest way to add desired completion candidates to nvim-cmp. + +![image](https://user-images.githubusercontent.com/82267684/145278036-afa56b20-a365-4165-822f-98db5d7f11b1.png) + +# Requirements + +- neovim >= 0.7 +- nvim-cmp +- [plenary.nvim](https://github.com/nvim-lua/plenary.nvim) (only document feature) +- [sqlite.lua](https://github.com/kkharji/sqlite.lua) (only if sqlite option is enabled) + +# Setting + +```lua +require("cmp").setup({ + -- other settings + sources = { + -- other sources + { + name = "dictionary", + keyword_length = 2, + }, + } +}) + +local dict = require("cmp_dictionary") + +dict.setup({ + -- The following are default values. + exact = 2, + first_case_insensitive = false, + document = false, + document_command = "wn %s -over", + async = false, + sqlite = false, + max_items = -1, + capacity = 5, + debug = false, +}) + +dict.switcher({ + filetype = { + lua = "/path/to/lua.dict", + javascript = { "/path/to/js.dict", "/path/to/js2.dict" }, + }, + filepath = { + [".*xmake.lua"] = { "/path/to/xmake.dict", "/path/to/lua.dict" }, + ["%.tmux.*%.conf"] = { "/path/to/js.dict", "/path/to/js2.dict" }, + }, + spelllang = { + en = "/path/to/english.dict", + }, +}) +``` + +See help for details. + +# Examples of usage + +See [wiki](https://github.com/uga-rosa/cmp-dictionary/wiki/Examples-of-usage) diff --git a/bundle/cmp-dictionary/after/plugin/cmp_dictionary.lua b/bundle/cmp-dictionary/after/plugin/cmp_dictionary.lua new file mode 100644 index 000000000..6fbb8bf9c --- /dev/null +++ b/bundle/cmp-dictionary/after/plugin/cmp_dictionary.lua @@ -0,0 +1,18 @@ +if vim.g.loaded_cmp_dictionary then + return +end +vim.g.loaded_cmp_dictionary = true + +require("cmp").register_source("dictionary", require("cmp_dictionary.source").new()) + +local update = require("cmp_dictionary").update + +vim.api.nvim_create_user_command("CmpDictionaryUpdate", update, {}) + +vim.api.nvim_create_autocmd("OptionSet", { + group = vim.api.nvim_create_augroup("cmp_dictionary_auto_update", {}), + pattern = "dictionary", + callback = update, +}) + +update() diff --git a/bundle/cmp-dictionary/doc/cmp-dictionary.txt b/bundle/cmp-dictionary/doc/cmp-dictionary.txt new file mode 100644 index 000000000..bea517675 --- /dev/null +++ b/bundle/cmp-dictionary/doc/cmp-dictionary.txt @@ -0,0 +1,276 @@ +*cmp-dictionary.txt* Dictionary completion source for nvim-cmp + +============================================================================== +Contents *cmp-dictionary-contents* + +Introduction |cmp-dictionary-introduction| +Commands |cmp-dictionary-commands| +Setting |cmp-dictionary-setting| +Option |cmp-dictionary-option| +Find dictionaries |cmp-dictionary-find-dictionaries| +Create dictionaries |cmp-dictionary-create-dictionaries| +Lazy loading |cmp-dictionary-lazy-loading| + +============================================================================== +Introduction *cmp-dictionary-introduction* + + *cmp-dictionary* +cmp-dictionary ~ + +A dictionary completion source for nvim-cmp. + + +This plugins refers to the value of |'dictionary'| to load dictionaries and +provide words in them as a completion candidates to nvim-cmp. The +|'dictionary'| has global and buffer local values, but this plugin uses both. +It is recommended to register basic dictionaries that you always want to use +globally, and do dictionaries that are only used in special cases locally. +See also |cmp-dictionary-switcher|. + + +Requirements +- neovim >= 0.7 +- nvim-cmp + - https://github.com/hrsh7th/nvim-cmp +- plenary.nvim (only document feature) + - https://github.com/nvim-lua/plenary.nvim + + +============================================================================== +Commands *cmp-dictionary-commands* + + *CmpDictionaryUpdate* +:CmpDictionaryUpdate ~ + In lua, `require("cmp_dictionary").update()` + + Updates the dictionary. It is basically not necessary for the user to + use it directly, as it is executed automatically by hooking into the + updating of the |'dictionary'|. + + +============================================================================== +Setting *cmp-dictionary-setting* + +Example setting. +If you use the default settings, this plugin will work without calling setup. + +> + require("cmp").setup({ + -- other settings + sources = { + -- other sources + { + name = "dictionary", + keyword_length = 2, + }, + } + }) + + require("cmp_dictionary").setup({ + -- Default settings + exact = 2, + first_case_insensitive = false, + document = false, + document_command = "wn %s -over", + async = false, + sqlite = false, + max_items = 1000, + capacity = 5, + debug = false, + }) +< + + +============================================================================== +Option *cmp-dictionary-option* + + *cmp-dictionary-iskeyword* +iskeyword ~ + + This plugin looks at |iskeyword| in vim. If you use a dictionary that + contains special characters, please configure it appropriately. For + example, if you want to complete the word `\word`, you would need to + add `set iskeyword+=\` to your configuration file. + + + *cmp-dictionary-exact* +exact ~ + integer (default: 2) + + It decides how many characters at the beginning are used as the exact + match. If -1, only candidates with an exact prefix match will be + returns. + Candidate refinement by this source is only prefix match using this + value (Fuzzy matching is left to the nvim-cmp body). + + + *cmp-dictionary-first_case_insensitive* +first_case_insensitive ~ + boolean (default: false) + + If true, it will ignore the case of the first character. For example, + if you have "Example" and "excuse" in your dictionary, typing "Ex" + will bring up "Example" and "Excuse" as candidates, while typing "ex" + will bring up "example" and "excuse". + + + *cmp-dictionary-document* +document ~ + boolean (default: false) + + plenary.nvim (https://github.com/nvim-lua/plenary.nvim) is required. + If true, activate document using external command. See + |cmp-dictionary-document-command| + + + *cmp-dictionary-document_command* +document_command ~ + string or list-like table (default: 'wn %s -over') + + This command is used above document feature. The '%s' will contain the + candidate word. The default `wn` command is wordnet. + + + If a string, the arguments are recognized by separating it with a + space character. If you don’t want that, use a table. + + If a table, the first element is the command and the second and + subsequent are the arguments. For example, the default setting would + be '{"wn", "%s", "-over"}'. + + + *cmp-dictionary-sqlite* +sqlite ~ + boolean (default: false) + + If true, use sqlite3 database to manage items. Basically, false is + faster. If you have a huge dictionary and it takes a long time to + initialize, you may want to try it. You will need the following. + + - kkharji/sqlite.lua (https://github.com/kkharji/sqlite.lua) + - sqlite (https://sqlite.org/index.html) + + The database path is `stdpath('data') . '/cmp-dictionary.sqlite3'` + + + *cmp-dictionary-max_items* +max_items ~ + integer (default: -1) + + This is the maximum number of candidates that this source will return + to the nvim-cmp body. -1 means no limit. Using a very large dictionary + and returning tens of thousands of candidates, completion becomes very + laggy. This is an option to avoid that. + If you experience lag, setting this option and `exact` appropriately + may help. + + + *cmp-dictionary-capacity* +capacity ~ + integer (default: 5) + + Determines the maximum number of dictionaries to be cached. This will + prevent duplicate reads when you switch dictionaries with the settings + described above. + + + *cmp-dictionary-debug* +debug ~ + boolean (default: false) + + If true, debug messages are output. + + +============================================================================== +Utilities *cmp-dictionary-utilities* + + *cmp-dictionary-utilities-switcher* +switcher({opts}) ~ + {opts}: table> + Automatically set locally a option |'dictionary'|, and loads + dictionaries. + - The `filetype` of {opts} has keys are compared to |'filetype'|. + - The `filepath` of {opts} has keys of Lua patterns, which are + compared to `expand("%:p")`. + - The `spelllang` of {opts} has keys are compared to |'spelllang'|. + + Usage example: +> + local dict = require("cmp_dictionary") + dict.switcher({ + filetype = { + lua = "/path/to/lua.dict", + javascript = { "/path/to/js.dict", "/path/to/js2.dict" }, + }, + filepath = { + [".*xmake.lua"] = { "/path/to/xmake.dict", "/path/to/lua.dict" }, + ["%.tmux.*%.conf"] = { "/path/to/js.dict", "/path/to/js2.dict" }, + }, + spelllang = { + en = "/path/to/english.dict", + }, + }) +< + +============================================================================== +Find dictionaries *cmp-dictionary-find-dictionaries* + +You can download dic from aspell.net or installing by package manager, xbps +extract to + + +> + $ ls /usr/share/dict/ + american-english british-english words +< + +After installing aspell and dictionary you want, run following command to get +dic for this plugin (plain text). + +> + aspell -d dump master | aspell -l expand > my.dict +< + + +============================================================================== +Create dictionaries *cmp-dictionary-create-dictionaries* + +The dictionary is recognized as a list delimited by '%s'. '%s' is a space, +','',', or '. For example, if you use the following file as a dictionary, the +source to be added is'{"hello", "world", "!"}’. + +> + hello + world ! +< + + +============================================================================== +Lazy loading *cmp-dictionary-lazy-loading* + +By default, reading dictionaries are fired by `BufEnter`. So if this plugin +loading is set to `InsertEnter` or something, the dictionary will not load and +no candidates will appear. The workaround is to fire this update yourself when +the plugin is loaded (after setup). + +For example, if you use packer.nvim, you can use + +> + use({ + "hrsh7th/nvim-cmp", + event = "InsertEnter", + -- other setting + }) + use({ + "uga-rosa/cmp-dictionary", + after = "nvim-cmp", + config = function() + require("cmp_dictionary").update() -- THIS + -- OR + -- vim.cmd("CmpDictionaryUpdate") + end + }) +< + + +vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/caches.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/caches.lua new file mode 100644 index 000000000..b8e7547c1 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/caches.lua @@ -0,0 +1,147 @@ +local util = require("cmp_dictionary.util") +local lfu = require("cmp_dictionary.lfu") +local config = require("cmp_dictionary.config") +local utf8 = require("cmp_dictionary.lib.utf8") +local Async = require("cmp_dictionary.kit.Async") +local Worker = require("cmp_dictionary.kit.Thread.Worker") + +---@class DictionaryData +---@field items lsp.CompletionItem[] +---@field mtime integer +---@field path string + +local Caches = { + ---@type DictionaryData[] + valid = {}, +} + +local just_updated = false +local dictCache = lfu.init(config.get("capacity")) + +---Filter to keep only dictionaries that have been updated or have not yet been cached. +---@return {path: string, mtime: integer}[] +local function need_to_load() + local dictionaries = util.get_dictionaries() + local updated_or_new = {} + for _, dict in ipairs(dictionaries) do + local path = vim.fn.expand(dict) + if util.bool_fn.filereadable(path) then + local mtime = vim.fn.getftime(path) + local cache = dictCache:get(path) + if cache and cache.mtime == mtime then + table.insert(Caches.valid, cache) + else + table.insert(updated_or_new, { path = path, mtime = mtime }) + end + end + end + return updated_or_new +end + +---Create dictionary data from buffers +---@param path string +---@param name string +---@return lsp.CompletionItem[] items +local read_items = Worker.new(function(path, name) + local buffer = require("cmp_dictionary.util").read_file_sync(path) + + local items = {} + local detail = ("belong to `%s`"):format(name) + for w in vim.gsplit(buffer, "%s+") do + if w ~= "" then + table.insert(items, { label = w, detail = detail }) + end + end + table.sort(items, function(item1, item2) + return item1.label < item2.label + end) + + return items +end) + +---@param path string +---@param mtime integer +---@return cmp_dictionary.kit.Async.AsyncTask +local function cache_update(path, mtime) + local name = vim.fn.fnamemodify(path, ":t") + return read_items(path, name):next(function(items) + local cache = { + items = items, + mtime = mtime, + path = path, + } + dictCache:set(path, cache) + table.insert(Caches.valid, cache) + end) +end + +local function update() + local buftype = vim.api.nvim_buf_get_option(0, "buftype") + if buftype ~= "" then + return + end + + Caches.valid = {} + + Async.all(vim.tbl_map(function(n) + return cache_update(n.path, n.mtime) + end, need_to_load())):next(function() + just_updated = true + end) +end + +function Caches.update() + util.debounce("update", update, 100) +end + +---@param req string +---@param isIncomplete boolean +---@return lsp.CompletionItem[] items +---@return boolean isIncomplete +function Caches.request(req, isIncomplete) + local items = {} + isIncomplete = isIncomplete or false + + local ok, offset, codepoint + ok, offset = pcall(utf8.offset, req, -1) + if not ok then + return items, isIncomplete + end + ok, codepoint = pcall(utf8.codepoint, req, offset) + if not ok then + return items, isIncomplete + end + + local req_next = req:sub(1, offset - 1) .. utf8.char(codepoint + 1) + + local max_items = config.get("max_items") + for _, cache in pairs(Caches.valid) do + local start = util.binary_search(cache.items, req, function(vector, index, key) + return vector[index].label >= key + end) + local last = util.binary_search(cache.items, req_next, function(vector, index, key) + return vector[index].label >= key + end) - 1 + if start > 0 and last > 0 and start <= last then + if max_items > 0 and last >= start + max_items then + last = start + max_items + isIncomplete = true + end + for i = start, last do + local item = cache.items[i] + table.insert(items, item) + end + end + end + return items, isIncomplete +end + +function Caches.is_just_updated() + if just_updated then + just_updated = false + return true + end + return false +end + +return Caches diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/config.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/config.lua new file mode 100644 index 000000000..50f322190 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/config.lua @@ -0,0 +1,38 @@ +local M = {} + +M.config = { + exact = 2, + first_case_insensitive = false, + document = false, + document_command = "wn %s -over", + sqlite = false, + max_items = -1, + capacity = 5, + debug = false, +} + +---@param opt table +function M.setup(opt) + vim.validate({ opt = { opt, "table" } }) + + M.config = vim.tbl_extend("keep", opt, M.config) + + local c = assert(M.config) + vim.validate({ + exact = { c.exact, "n" }, + first_case_insensitive = { c.first_case_insensitive, "b" }, + document = { c.document, "b" }, + document_command = { c.document_command, { "s", "t" } }, + max_items = { c.max_items, "n" }, + capacity = { c.capacity, "n" }, + debug = { c.debug, "b" }, + }) +end + +---@param name string +---@return unknown +function M.get(name) + return M.config[name] +end + +return M diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/db.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/db.lua new file mode 100644 index 000000000..3321d65f1 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/db.lua @@ -0,0 +1,194 @@ +local util = require("cmp_dictionary.util") +local config = require("cmp_dictionary.config") +local Async = require("cmp_dictionary.kit.Async") +local Worker = require("cmp_dictionary.kit.Thread.Worker") + +local SQLite = {} + +local just_updated = false + +---@return table db +function SQLite:open() + if self.db then + return self.db + end + + local ok, sqlite = pcall(require, "sqlite") + if not ok or sqlite == nil then + error("[cmp-dictionary] sqlite.lua is not installed!") + end + + local db_path = vim.fn.stdpath("data") .. "/cmp-dictionary.sqlite3" + self.db = sqlite:open(db_path) + if not self.db then + error("[cmp-dictionary] Error in opening DB") + end + + if not self.db:exists("dictionary") then + self.db:create("dictionary", { + filepath = { "text", primary = true }, + mtime = { "integer", required = true }, + valid = { "integer", default = 1 }, + }) + end + + if not self.db:exists("items") then + self.db:create("items", { + label = { "text", required = true }, + detail = { "text", required = true }, + filepath = { "text", required = true }, + documentation = "text", + }) + end + + vim.api.nvim_create_autocmd("VimLeave", { + group = vim.api.nvim_create_augroup("cmp-dictionary-database", {}), + callback = function() + self.db:close() + end, + }) + + return self.db +end + +function SQLite:exists_index(name) + self:open() + -- Can't use db:select() for sqlite_master. + local result = self.db:eval("SELECT * FROM sqlite_master WHERE type = 'index' AND name = ?", name) + return type(result) == "table" and #result == 1 +end + +function SQLite:index(tbl_name, column) + local name = column .. "index" + if SQLite:exists_index(name) then + self.db:execute("DROP INDEX " .. name) + end + self.db:execute(("CREATE INDEX %s ON %s(%s)"):format(name, tbl_name, column)) +end + +local function need_to_load(db) + local dictionaries = util.get_dictionaries() + local updated_or_new = {} + for _, dictionary in ipairs(dictionaries) do + local path = vim.fn.expand(dictionary) + if util.bool_fn.filereadable(path) then + local mtime = vim.fn.getftime(path) + local mtime_cache = db:select("dictionary", { select = "mtime", where = { filepath = path } }) + if mtime_cache[1] and mtime_cache[1].mtime == mtime then + db:update("dictionary", { + set = { valid = 1 }, + where = { filepath = path }, + }) + else + table.insert(updated_or_new, { path = path, mtime = mtime }) + end + end + end + return updated_or_new +end + +local read_items = Worker.new(function(path, name) + local buffer = require("cmp_dictionary.util").read_file_sync(path) + + local detail = string.format("belong to `%s`", name) + local items = {} + for w in vim.gsplit(buffer, "%s+") do + if w ~= "" then + table.insert(items, { label = w, detail = detail, filepath = path }) + end + end + return items +end) + +local function update(db) + local buftype = vim.api.nvim_buf_get_option(0, "buftype") + if buftype ~= "" then + return + end + + db:update("dictionary", { set = { valid = 0 } }) + + Async.all(vim.tbl_map(function(n) + local path, mtime = n.path, n.mtime + local name = vim.fn.fnamemodify(path, ":t") + return read_items(path, name):next(function(items) + db:delete("items", { where = { filepath = path } }) + db:insert("items", items) + + -- Index for fast search + SQLite:index("items", "label") + SQLite:index("items", "filepath") + + -- If there is no data matching where, it automatically switches to insert. + db:update("dictionary", { + set = { mtime = mtime, valid = 1 }, + where = { filepath = path }, + }) + end) + end, need_to_load(db))):next(function() + just_updated = true + end) +end + +local DB = {} + +function DB.update() + local db = SQLite:open() + util.debounce("update_db", function() + update(db) + end, 100) +end + +---@param req string +---@return lsp.CompletionItem[] items +---@return boolean isIncomplete +function DB.request(req, _) + local db = SQLite:open() + local max_items = config.get("max_items") + local items = db:eval( + [[ + SELECT label, detail, documentation FROM items + WHERE filepath IN (SELECT filepath FROM dictionary WHERE valid = 1) + AND label GLOB :a + LIMIT :b + ]], + { a = req .. "*", b = max_items } + ) + if type(items) == "table" then + return items, #items == max_items + else + return {}, false + end +end + +function DB.is_just_updated() + if just_updated then + just_updated = false + return true + end + return false +end + +---@param completion_item lsp.CompletionItem +---@param callback fun(completion_item: lsp.CompletionItem|nil) +function DB.document(completion_item, callback) + if completion_item.documentation then + callback(completion_item) + return + end + + local db = SQLite:open() + local label = completion_item.label + require("cmp_dictionary.document")(completion_item, function(completion_item_) + if completion_item_ and completion_item_.documentation then + -- By first_case_insensitive, the case of the label is ambiguous. + db:eval( + "UPDATE items SET documentation = :a WHERE label like :b", + { a = completion_item_.documentation, b = label } + ) + end + callback(completion_item_) + end) +end + +return DB diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/document.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/document.lua new file mode 100644 index 000000000..7a39e087f --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/document.lua @@ -0,0 +1,76 @@ +local config = require("cmp_dictionary.config") + +local document_cache = require("cmp_dictionary.lfu").init(100) + +---@param word string +---@return string +---@return string[] +local function get_command(word) + local command = config.get("document_command") + + local args + if type(command) == "table" then + -- copy + args = {} + for i, v in ipairs(command) do + args[i] = v + end + elseif type(command) == "string" then + args = vim.split(command, " ") + end + + local cmd = table.remove(args, 1) + for i, arg in ipairs(args) do + if arg:find("%s", 1, true) then + args[i] = arg:format(word) + end + end + + return cmd, args +end + +---@param completion_item lsp.CompletionItem +---@param callback fun(completion_item: lsp.CompletionItem|nil) +local function get_document(completion_item, callback) + local ok, Job = pcall(require, "plenary.job") + if not ok then + vim.notify("[cmp-dictionary] document feature requires plenary.nvim") + return + end + + local word = completion_item.label + local command, args = get_command(word) + if not command then + callback(completion_item) + return + end + + Job:new({ + command = command, + args = args, + on_exit = vim.schedule_wrap(function(j) + local result = table.concat(j:result(), "\n") + document_cache:set(word, result) + completion_item.documentation = result + callback(completion_item) + end), + }):start() +end + +---@param completion_item lsp.CompletionItem +---@param callback fun(completion_item: lsp.CompletionItem|nil) +local function resolve(completion_item, callback) + if config.get("document") then + local cached = document_cache:get(completion_item.label) + if cached then + completion_item.documentation = cached + callback(completion_item) + else + get_document(completion_item, callback) + end + else + callback(completion_item) + end +end + +return resolve diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/init.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/init.lua new file mode 100644 index 000000000..157d72d20 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/init.lua @@ -0,0 +1,87 @@ +local config = require("cmp_dictionary.config") + +local M = {} + +function M.setup(opt) + require("cmp_dictionary.config").setup(opt) +end + +function M.update() + if config.get("sqlite") then + require("cmp_dictionary.db").update() + else + require("cmp_dictionary.caches").update() + end +end + +---@alias dictionaries table +---#key is a pattern, value is a value of option 'dictionary'. + +---@param opt { filetype: dictionaries, filepath: dictionaries, spelllang: dictionaries } +--- Usage: +--- require("cmp_dictionary").switcher({ +--- filetype = { +--- lua = "/path/to/lua.dict", +--- javascript = { "/path/to/js.dict", "/path/to/js2.dict" }, +--- }, +--- filepath = { +--- ["*xmake.lua"] = { "/path/to/xmake.dict", "/path/to/lua.dict" } +--- [".tmux*.conf"] = { "/path/to/js.dict", "/path/to/js2.dict" }, +--- }, +--- spelllang = { +--- en = "/path/to/english.dict", +--- }, +-- }) +function M.switcher(opt) + vim.validate({ opt = { opt, "table" } }) + + local id = vim.api.nvim_create_augroup("cmp_dictionary", {}) + + local function callback() + vim.opt_local.dictionary = {} + if opt.filetype then + vim.opt_local.dictionary:append(opt.filetype[vim.bo.filetype] or "") + end + if opt.filepath then + local fullpath = vim.fn.expand("%:p") + for path, dict in pairs(opt.filepath) do + if fullpath:find(path) then + vim.opt_local.dictionary:append(dict) + end + end + end + if opt.spelllang then + for _, sl in ipairs(vim.opt.spelllang:get()) do + vim.opt_local.dictionary:append(opt.spelllang[sl] or "") + end + end + M.update() + end + + if opt.filetype then + vim.api.nvim_create_autocmd("FileType", { + group = id, + pattern = vim.tbl_keys(opt.filetype), + callback = callback, + }) + end + + if opt.filepath then + vim.api.nvim_create_autocmd("BufEnter", { + group = id, + callback = callback, + }) + end + + if opt.spelllang then + vim.api.nvim_create_autocmd("OptionSet", { + group = id, + pattern = "spelllang", + callback = callback, + }) + end + + callback() +end + +return M diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/init_spec.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/init_spec.lua new file mode 100644 index 000000000..15e5e2a66 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/init_spec.lua @@ -0,0 +1,34 @@ +local main = require("cmp_dictionary") + +local function dictionary() + return vim.opt_local.dictionary:get() +end + +describe("Test for init.lua", function() + before_each(function() + vim.opt_local.dictionary = {} + end) + + describe("switcher", function() + describe("filetype", function() + it("single dictionary", function() + main.switcher({ + filetype = { + lua = "/path/to/lua.dict", + }, + }) + vim.opt.filetype = "lua" + assert.are.same({ "/path/to/lua.dict" }, dictionary()) + end) + it("multi dictionaries", function() + main.switcher({ + filetype = { + javascript = { "/path/to/js.dict", "/path/to/js2.dict" }, + }, + }) + vim.opt.filetype = "javascript" + assert.are.same({ "/path/to/js.dict", "/path/to/js2.dict" }, dictionary()) + end) + end) + end) +end) diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Cache.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Cache.lua new file mode 100644 index 000000000..05ec1ad83 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Cache.lua @@ -0,0 +1,70 @@ +---Create cache key. +---@private +---@param key string[]|string +---@return string +local function _key(key) + if type(key) == 'table' then + return table.concat(key, ':') + end + return key +end + +---@class cmp_dictionary.kit.App.Cache +---@field private keys table +---@field private entries table +local Cache = {} +Cache.__index = Cache + +---Create new cache instance. +function Cache.new() + local self = setmetatable({}, Cache) + self.keys = {} + self.entries = {} + return self +end + +---Get cache entry. +---@param key string[]|string +---@return any +function Cache:get(key) + return self.entries[_key(key)] +end + +---Set cache entry. +---@param key string[]|string +---@param val any +function Cache:set(key, val) + key = _key(key) + self.keys[key] = true + self.entries[key] = val +end + +---Delete cache entry. +---@param key string[]|string +function Cache:del(key) + key = _key(key) + self.keys[key] = nil + self.entries[key] = nil +end + +---Return this cache has the key entry or not. +---@param key string[]|string +---@return boolean +function Cache:has(key) + key = _key(key) + return not not self.keys[key] +end + +---Ensure cache entry. +---@generic T +---@param key string[]|string +---@param callback function(): T +---@return T +function Cache:ensure(key, callback) + if not self:has(key) then + self:set(key, callback()) + end + return self:get(key) +end + +return Cache diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Character.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Character.lua new file mode 100644 index 000000000..1d0d3a95b --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Character.lua @@ -0,0 +1,58 @@ +---@diagnostic disable: discard-returns + +local Character = {} + +---@type table +Character.alpha = {} +string.gsub('abcdefghijklmnopqrstuvwxyz', '.', function(char) + Character.alpha[string.byte(char)] = char +end) + +---@type table +Character.digit = {} +string.gsub('1234567890', '.', function(char) + Character.digit[string.byte(char)] = char +end) + +---@type table +Character.white = {} +string.gsub(' \t\n', '.', function(char) + Character.white[string.byte(char)] = char +end) + +---Return specified byte is alpha or not. +---@param byte integer +---@return boolean +function Character.is_alpha(byte) + return Character.alpha[byte] ~= nil or Character.alpha[byte + 32] ~= nil +end + +---Return specified byte is digit or not. +---@param byte integer +---@return boolean +function Character.is_digit(byte) + return Character.digit[byte] ~= nil +end + +---Return specified byte is alpha or not. +---@param byte integer +---@return boolean +function Character.is_alnum(byte) + return Character.is_alpha(byte) or Character.is_digit(byte) +end + +---Return specified byte is white or not. +---@param byte integer +---@return boolean +function Character.is_white(byte) + return Character.white[byte] ~= nil +end + +---Return specified byte is symbol or not. +---@param byte integer +---@return boolean +function Character.is_symbol(byte) + return not Character.is_alnum(byte) and not Character.is_white(byte) +end + +return Character diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Config.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Config.lua new file mode 100644 index 000000000..eea7fc775 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Config.lua @@ -0,0 +1,99 @@ +local kit = require('cmp_dictionary.kit') +local Cache = require('cmp_dictionary.kit.App.Cache') + +---@class cmp_dictionary.kit.App.Config.Schema + +---@alias cmp_dictionary.kit.App.Config.SchemaInternal cmp_dictionary.kit.App.Config.Schema|{ revision: integer } + +---@class cmp_dictionary.kit.App.Config +---@field private _cache cmp_dictionary.kit.App.Cache +---@field private _default cmp_dictionary.kit.App.Config.SchemaInternal +---@field private _global cmp_dictionary.kit.App.Config.SchemaInternal +---@field private _filetype table +---@field private _buffer table +local Config = {} +Config.__index = Config + +---Create new config instance. +---@param default cmp_dictionary.kit.App.Config.Schema +function Config.new(default) + local self = setmetatable({}, Config) + self._cache = Cache.new() + self._default = default + self._global = {} + self._filetype = {} + self._buffer = {} + return self +end + +---Update global config. +---@param config cmp_dictionary.kit.App.Config.Schema +function Config:global(config) + local revision = (self._global.revision or 1) + 1 + self._global = config or {} + self._global.revision = revision +end + +---Update filetype config. +---@param filetypes string|string[] +---@param config cmp_dictionary.kit.App.Config.Schema +function Config:filetype(filetypes, config) + for _, filetype in ipairs(kit.to_array(filetypes)) do + local revision = ((self._filetype[filetype] or {}).revision or 1) + 1 + self._filetype[filetype] = config or {} + self._filetype[filetype].revision = revision + end +end + +---Update filetype config. +---@param bufnr integer +---@param config cmp_dictionary.kit.App.Config.Schema +function Config:buffer(bufnr, config) + bufnr = bufnr == 0 and vim.api.nvim_get_current_buf() or bufnr + local revision = ((self._buffer[bufnr] or {}).revision or 1) + 1 + self._buffer[bufnr] = config or {} + self._buffer[bufnr].revision = revision +end + +---Get current configuration. +---@return cmp_dictionary.kit.App.Config.Schema +function Config:get() + local filetype = vim.api.nvim_buf_get_option(0, 'filetype') + local bufnr = vim.api.nvim_get_current_buf() + return self._cache:ensure({ + tostring(self._global.revision or 0), + tostring((self._buffer[bufnr] or {}).revision or 0), + tostring((self._filetype[filetype] or {}).revision or 0), + }, function() + local config = self._default + config = kit.merge(self._global, config) + config = kit.merge(self._filetype[filetype] or {}, config) + config = kit.merge(self._buffer[bufnr] or {}, config) + config.revision = nil + return config + end) +end + +---Create setup interface. +---@return fun(config: cmp_dictionary.kit.App.Config.Schema)|{ filetype: fun(filetypes: string|string[], config: cmp_dictionary.kit.App.Config.Schema), buffer: fun(bufnr: integer, config: cmp_dictionary.kit.App.Config.Schema) } +function Config:create_setup_interface() + return setmetatable({ + ---@param filetypes string|string[] + ---@param config cmp_dictionary.kit.App.Config.Schema + filetype = function(filetypes, config) + self:filetype(filetypes, config) + end, + ---@param bufnr integer + ---@param config cmp_dictionary.kit.App.Config.Schema + buffer = function(bufnr, config) + self:buffer(bufnr, config) + end, + }, { + ---@param config cmp_dictionary.kit.App.Config.Schema + __call = function(_, config) + self:global(config) + end, + }) +end + +return Config diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Event.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Event.lua new file mode 100644 index 000000000..af2b11fb9 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/App/Event.lua @@ -0,0 +1,77 @@ +---@class cmp_dictionary.kit.App.Event +---@field private _events table +local Event = {} +Event.__index = Event + +---Create new Event. +function Event.new() + local self = setmetatable({}, Event) + self._events = {} + return self +end + +---Register listener. +---@param name string +---@param listener function +---@return function +function Event:on(name, listener) + self._events[name] = self._events[name] or {} + table.insert(self._events[name], listener) + return function() + self:off(name, listener) + end +end + +---Register once listener. +---@param name string +---@param listener function +function Event:once(name, listener) + local off + off = self:on(name, function(...) + listener(...) + off() + end) +end + +---Off specified listener from event. +---@param name string +---@param listener function +function Event:off(name, listener) + self._events[name] = self._events[name] or {} + if not listener then + self._events[name] = nil + else + for i = #self._events[name], 1, -1 do + if self._events[name][i] == listener then + table.remove(self._events[name], i) + break + end + end + end +end + +---Return if the listener is registered. +---@param name string +---@param listener? function +---@return boolean +function Event:has(name, listener) + self._events[name] = self._events[name] or {} + for _, v in ipairs(self._events[name]) do + if v == listener then + return true + end + end + return false +end + +---Emit event. +---@param name string +---@vararg any +function Event:emit(name, ...) + self._events[name] = self._events[name] or {} + for _, v in ipairs(self._events[name]) do + v(...) + end +end + +return Event diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Async/AsyncTask.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Async/AsyncTask.lua new file mode 100644 index 000000000..110585d28 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Async/AsyncTask.lua @@ -0,0 +1,241 @@ +---@diagnostic disable: invisible +local uv = require('luv') +local kit = require('cmp_dictionary.kit') + +local is_thread = vim.is_thread() + +---@class cmp_dictionary.kit.Async.AsyncTask +---@field private value any +---@field private status cmp_dictionary.kit.Async.AsyncTask.Status +---@field private synced boolean +---@field private chained boolean +---@field private children (fun(): any)[] +local AsyncTask = {} +AsyncTask.__index = AsyncTask + +---Settle the specified task. +---@param task cmp_dictionary.kit.Async.AsyncTask +---@param status cmp_dictionary.kit.Async.AsyncTask.Status +---@param value any +local function settle(task, status, value) + task.status = status + task.value = value + for _, c in ipairs(task.children) do + c() + end + + if status == AsyncTask.Status.Rejected then + if not task.chained and not task.synced then + local timer = uv.new_timer() + timer:start( + 0, + 0, + kit.safe_schedule_wrap(function() + timer:stop() + timer:close() + if not task.chained and not task.synced then + AsyncTask.on_unhandled_rejection(value) + end + end) + ) + end + end +end + +---@enum cmp_dictionary.kit.Async.AsyncTask.Status +AsyncTask.Status = { + Pending = 0, + Fulfilled = 1, + Rejected = 2, +} + +---Handle unhandled rejection. +---@param err any +function AsyncTask.on_unhandled_rejection(err) + error('AsyncTask.on_unhandled_rejection: ' .. tostring(err)) +end + +---Return the value is AsyncTask or not. +---@param value any +---@return boolean +function AsyncTask.is(value) + return getmetatable(value) == AsyncTask +end + +---Resolve all tasks. +---@param tasks any[] +---@return cmp_dictionary.kit.Async.AsyncTask +function AsyncTask.all(tasks) + return AsyncTask.new(function(resolve, reject) + local values = {} + local count = 0 + for i, task in ipairs(tasks) do + task:dispatch(function(value) + values[i] = value + count = count + 1 + if #tasks == count then + resolve(values) + end + end, reject) + end + end) +end + +---Resolve first resolved task. +---@param tasks any[] +---@return cmp_dictionary.kit.Async.AsyncTask +function AsyncTask.race(tasks) + return AsyncTask.new(function(resolve, reject) + for _, task in ipairs(tasks) do + task:dispatch(resolve, reject) + end + end) +end + +---Create resolved AsyncTask. +---@param v any +---@return cmp_dictionary.kit.Async.AsyncTask +function AsyncTask.resolve(v) + if AsyncTask.is(v) then + return v + end + return AsyncTask.new(function(resolve) + resolve(v) + end) +end + +---Create new AsyncTask. +---@NOET: The AsyncTask has similar interface to JavaScript Promise but the AsyncTask can be worked as synchronous. +---@param v any +---@return cmp_dictionary.kit.Async.AsyncTask +function AsyncTask.reject(v) + if AsyncTask.is(v) then + return v + end + return AsyncTask.new(function(_, reject) + reject(v) + end) +end + +---Create new async task object. +---@param runner fun(resolve?: fun(value: any?), reject?: fun(err: any?)) +function AsyncTask.new(runner) + local self = setmetatable({}, AsyncTask) + + self.value = nil + self.status = AsyncTask.Status.Pending + self.synced = false + self.chained = false + self.children = {} + local ok, err = pcall(runner, function(res) + if self.status == AsyncTask.Status.Pending then + settle(self, AsyncTask.Status.Fulfilled, res) + end + end, function(err) + if self.status == AsyncTask.Status.Pending then + settle(self, AsyncTask.Status.Rejected, err) + end + end) + if not ok then + settle(self, AsyncTask.Status.Rejected, err) + end + return self +end + +---Sync async task. +---@NOTE: This method uses `vim.wait` so that this can't wait the typeahead to be empty. +---@param timeout? number +---@return any +function AsyncTask:sync(timeout) + self.synced = true + + if is_thread then + while true do + if self.status ~= AsyncTask.Status.Pending then + break + end + uv.run('once') + end + else + vim.wait(timeout or 24 * 60 * 60 * 1000, function() + return self.status ~= AsyncTask.Status.Pending + end, 1, false) + end + if self.status == AsyncTask.Status.Rejected then + error(self.value, 2) + end + if self.status ~= AsyncTask.Status.Fulfilled then + error('AsyncTask:sync is timeout.', 2) + end + return self.value +end + +---Await async task. +---@param schedule? boolean +---@return any +function AsyncTask:await(schedule) + local Async = require('cmp_dictionary.kit.Async') + local ok, res = pcall(Async.await, self) + if not ok then + error(res, 2) + end + if schedule then + Async.await(Async.schedule()) + end + return res +end + +---Return current state of task. +---@return { status: cmp_dictionary.kit.Async.AsyncTask.Status, value: any } +function AsyncTask:state() + return { + status = self.status, + value = self.value, + } +end + +---Register next step. +---@param on_fulfilled fun(value: any): any +function AsyncTask:next(on_fulfilled) + return self:dispatch(on_fulfilled, function(err) + error(err, 2) + end) +end + +---Register catch step. +---@param on_rejected fun(value: any): any +---@return cmp_dictionary.kit.Async.AsyncTask +function AsyncTask:catch(on_rejected) + return self:dispatch(function(value) + return value + end, on_rejected) +end + +---Dispatch task state. +---@param on_fulfilled fun(value: any): any +---@param on_rejected fun(err: any): any +---@return cmp_dictionary.kit.Async.AsyncTask +function AsyncTask:dispatch(on_fulfilled, on_rejected) + self.chained = true + + local function dispatch(resolve, reject) + local on_next = self.status == AsyncTask.Status.Fulfilled and on_fulfilled or on_rejected + local res = on_next(self.value) + if AsyncTask.is(res) then + res:dispatch(resolve, reject) + else + resolve(res) + end + end + + if self.status == AsyncTask.Status.Pending then + return AsyncTask.new(function(resolve, reject) + table.insert(self.children, function() + dispatch(resolve, reject) + end) + end) + end + return AsyncTask.new(dispatch) +end + +return AsyncTask diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Async/init.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Async/init.lua new file mode 100644 index 000000000..9600b14ab --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Async/init.lua @@ -0,0 +1,161 @@ +local AsyncTask = require('cmp_dictionary.kit.Async.AsyncTask') + +local Async = {} + +---@type table +Async.___threads___ = {} + +---Alias of AsyncTask.all. +---@param tasks cmp_dictionary.kit.Async.AsyncTask[] +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.all(tasks) + return AsyncTask.all(tasks) +end + +---Alias of AsyncTask.race. +---@param tasks cmp_dictionary.kit.Async.AsyncTask[] +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.race(tasks) + return AsyncTask.race(tasks) +end + +---Alias of AsyncTask.resolve(v). +---@param v any +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.resolve(v) + return AsyncTask.resolve(v) +end + +---Alias of AsyncTask.reject(v). +---@param v any +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.reject(v) + return AsyncTask.reject(v) +end + +---Alias of AsyncTask.new(...). +---@param runner fun(resolve: fun(value: any), reject: fun(err: any)) +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.new(runner) + return AsyncTask.new(runner) +end + +---Run async function immediately. +---@generic T: fun(): cmp_dictionary.kit.Async.AsyncTask +---@param runner T +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.run(runner) + return Async.async(runner)() +end + +---Return current context is async coroutine or not. +---@return boolean +function Async.in_context() + return Async.___threads___[coroutine.running()] ~= nil +end + +---Create async function. +---@generic T: fun(...): cmp_dictionary.kit.Async.AsyncTask +---@param runner T +---@return T +function Async.async(runner) + return function(...) + local args = { ... } + + local thread = coroutine.create(runner) + return AsyncTask.new(function(resolve, reject) + Async.___threads___[thread] = 1 + + local function next_step(ok, v) + if coroutine.status(thread) == 'dead' then + Async.___threads___[thread] = nil + if AsyncTask.is(v) then + v:dispatch(resolve, reject) + else + if ok then + resolve(v) + else + reject(v) + end + end + return + end + + v:dispatch(function(...) + next_step(coroutine.resume(thread, true, ...)) + end, function(...) + next_step(coroutine.resume(thread, false, ...)) + end) + end + + next_step(coroutine.resume(thread, unpack(args))) + end) + end +end + +---Await async task. +---@param task cmp_dictionary.kit.Async.AsyncTask +---@return any +function Async.await(task) + if not Async.___threads___[coroutine.running()] then + error('`Async.await` must be called in async context.') + end + if not AsyncTask.is(task) then + error('`Async.await` must be called with AsyncTask.') + end + + local ok, res = coroutine.yield(task) + if not ok then + error(res, 2) + end + return res +end + +---Create vim.schedule task. +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.schedule() + return AsyncTask.new(function(resolve) + vim.schedule(resolve) + end) +end + +---Create vim.defer_fn task. +---@param timeout integer +---@return cmp_dictionary.kit.Async.AsyncTask +function Async.timeout(timeout) + return AsyncTask.new(function(resolve) + vim.defer_fn(resolve, timeout) + end) +end + +---Create async function from callback function. +---@generic T: ... +---@param runner fun(...: T) +---@param option? { schedule?: boolean, callback?: integer } +---@return fun(...: T): cmp_dictionary.kit.Async.AsyncTask +function Async.promisify(runner, option) + option = option or {} + option.schedule = not vim.is_thread() and (option.schedule or false) + option.callback = option.callback or nil + return function(...) + local args = { ... } + return AsyncTask.new(function(resolve, reject) + local max = #args + 1 + local pos = math.min(option.callback or max, max) + table.insert(args, pos, function(err, ...) + if option.schedule and vim.in_fast_event() then + resolve = vim.schedule_wrap(resolve) + reject = vim.schedule_wrap(reject) + end + if err then + reject(err) + else + resolve(...) + end + end) + runner(unpack(args)) + end) + end +end + +return Async diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/IO/init.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/IO/init.lua new file mode 100644 index 000000000..34fac0ecd --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/IO/init.lua @@ -0,0 +1,448 @@ +local uv = require('luv') +local Async = require('cmp_dictionary.kit.Async') + +local is_windows = uv.os_uname().sysname:lower() == 'windows' + +---@see https://github.com/luvit/luvit/blob/master/deps/fs.lua +local IO = {} + +---@class cmp_dictionary.kit.IO.UV.Stat +---@field public dev integer +---@field public mode integer +---@field public nlink integer +---@field public uid integer +---@field public gid integer +---@field public rdev integer +---@field public ino integer +---@field public size integer +---@field public blksize integer +---@field public blocks integer +---@field public flags integer +---@field public gen integer +---@field public atime { sec: integer, nsec: integer } +---@field public mtime { sec: integer, nsec: integer } +---@field public ctime { sec: integer, nsec: integer } +---@field public birthtime { sec: integer, nsec: integer } +---@field public type string + +---@enum cmp_dictionary.kit.IO.UV.AccessMode +IO.AccessMode = { + r = 'r', + rs = 'rs', + sr = 'sr', + ['r+'] = 'r+', + ['rs+'] = 'rs+', + ['sr+'] = 'sr+', + w = 'w', + wx = 'wx', + xw = 'xw', + ['w+'] = 'w+', + ['wx+'] = 'wx+', + ['xw+'] = 'xw+', + a = 'a', + ax = 'ax', + xa = 'xa', + ['a+'] = 'a+', + ['ax+'] = 'ax+', + ['xa+'] = 'xa+', +} + +---@enum cmp_dictionary.kit.IO.WalkStatus +IO.WalkStatus = { + SkipDir = 1, + Break = 2, +} + +---@type fun(path: string): cmp_dictionary.kit.Async.AsyncTask +IO.fs_stat = Async.promisify(uv.fs_stat) + +---@type fun(path: string): cmp_dictionary.kit.Async.AsyncTask +IO.fs_unlink = Async.promisify(uv.fs_unlink) + +---@type fun(path: string): cmp_dictionary.kit.Async.AsyncTask +IO.fs_rmdir = Async.promisify(uv.fs_rmdir) + +---@type fun(path: string, mode: integer): cmp_dictionary.kit.Async.AsyncTask +IO.fs_mkdir = Async.promisify(uv.fs_mkdir) + +---@type fun(from: string, to: string, option?: { excl?: boolean, ficlone?: boolean, ficlone_force?: boolean }): cmp_dictionary.kit.Async.AsyncTask +IO.fs_copyfile = Async.promisify(uv.fs_copyfile) + +---@type fun(path: string, flags: cmp_dictionary.kit.IO.UV.AccessMode, mode: integer): cmp_dictionary.kit.Async.AsyncTask +IO.fs_open = Async.promisify(uv.fs_open) + +---@type fun(fd: userdata): cmp_dictionary.kit.Async.AsyncTask +IO.fs_close = Async.promisify(uv.fs_close) + +---@type fun(fd: userdata, chunk_size: integer, offset?: integer): cmp_dictionary.kit.Async.AsyncTask +IO.fs_read = Async.promisify(uv.fs_read) + +---@type fun(fd: userdata, content: string, offset?: integer): cmp_dictionary.kit.Async.AsyncTask +IO.fs_write = Async.promisify(uv.fs_write) + +---@type fun(fd: userdata, offset: integer): cmp_dictionary.kit.Async.AsyncTask +IO.fs_ftruncate = Async.promisify(uv.fs_ftruncate) + +---@type fun(path: string, chunk_size?: integer): cmp_dictionary.kit.Async.AsyncTask +IO.fs_opendir = Async.promisify(uv.fs_opendir, { callback = 2 }) + +---@type fun(fd: userdata): cmp_dictionary.kit.Async.AsyncTask +IO.fs_closedir = Async.promisify(uv.fs_closedir) + +---@type fun(fd: userdata): cmp_dictionary.kit.Async.AsyncTask +IO.fs_readdir = Async.promisify(uv.fs_readdir) + +---@type fun(path: string): cmp_dictionary.kit.Async.AsyncTask +IO.fs_scandir = Async.promisify(uv.fs_scandir) + +---@type fun(path: string): cmp_dictionary.kit.Async.AsyncTask +IO.fs_realpath = Async.promisify(uv.fs_realpath) + +---Return if the path is directory. +---@param path string +---@return cmp_dictionary.kit.Async.AsyncTask +function IO.is_directory(path) + path = IO.normalize(path) + return Async.run(function() + return IO.fs_stat(path):catch(function() + return {} + end):await().type == 'directory' + end) +end + +---Read file. +---@param path string +---@param chunk_size? integer +---@return cmp_dictionary.kit.Async.AsyncTask +function IO.read_file(path, chunk_size) + chunk_size = chunk_size or 1024 + return Async.run(function() + local stat = IO.fs_stat(path):await() + local fd = IO.fs_open(path, IO.AccessMode.r, tonumber('755', 8)):await() + local ok, res = pcall(function() + local chunks = {} + local offset = 0 + while offset < stat.size do + local chunk = IO.fs_read(fd, math.min(chunk_size, stat.size - offset), offset):await() + if not chunk then + break + end + table.insert(chunks, chunk) + offset = offset + #chunk + end + return table.concat(chunks, ''):sub(1, stat.size - 1) -- remove EOF. + end) + IO.fs_close(fd):await() + if not ok then + error(res) + end + return res + end) +end + +---Write file. +---@param path string +---@param content string +---@param chunk_size? integer +function IO.write_file(path, content, chunk_size) + chunk_size = chunk_size or 1024 + content = content .. '\n' -- add EOF. + return Async.run(function() + local fd = IO.fs_open(path, IO.AccessMode.w, tonumber('755', 8)):await() + local ok, err = pcall(function() + local offset = 0 + while offset < #content do + local chunk = content:sub(offset + 1, offset + chunk_size) + offset = offset + IO.fs_write(fd, chunk, offset):await() + end + IO.fs_ftruncate(fd, offset):await() + end) + IO.fs_close(fd):await() + if not ok then + error(err) + end + end) +end + +---Create directory. +---@param path string +---@param mode integer +---@param option? { recursive?: boolean } +function IO.mkdir(path, mode, option) + path = IO.normalize(path) + option = option or {} + option.recursive = option.recursive or false + return Async.run(function() + if not option.recursive then + IO.fs_mkdir(path, mode):await() + else + local not_exists = {} + local current = path + while current ~= '/' do + local stat = IO.fs_stat(current):catch(function() end):await() + if stat then + break + end + table.insert(not_exists, 1, current) + current = IO.dirname(current) + end + for _, dir in ipairs(not_exists) do + IO.fs_mkdir(dir, mode):await() + end + end + end) +end + +---Remove file or directory. +---@param start_path string +---@param option? { recursive?: boolean } +function IO.rm(start_path, option) + start_path = IO.normalize(start_path) + option = option or {} + option.recursive = option.recursive or false + return Async.run(function() + local stat = IO.fs_stat(start_path):await() + if stat.type == 'directory' then + local children = IO.scandir(start_path):await() + if not option.recursive and #children > 0 then + error(('IO.rm: `%s` is a directory and not empty.'):format(start_path)) + end + IO.walk(start_path, function(err, entry) + if err then + error('IO.rm: ' .. tostring(err)) + end + if entry.type == 'directory' then + IO.fs_rmdir(entry.path):await() + else + IO.fs_unlink(entry.path):await() + end + end, { postorder = true }):await() + else + IO.fs_unlink(start_path):await() + end + end) +end + +---Copy file or directory. +---@param from any +---@param to any +---@param option? { recursive?: boolean } +---@return cmp_dictionary.kit.Async.AsyncTask +function IO.cp(from, to, option) + from = IO.normalize(from) + to = IO.normalize(to) + option = option or {} + option.recursive = option.recursive or false + return Async.run(function() + local stat = IO.fs_stat(from):await() + if stat.type == 'directory' then + if not option.recursive then + error(('IO.cp: `%s` is a directory.'):format(from)) + end + IO.walk(from, function(err, entry) + if err then + error('IO.cp: ' .. tostring(err)) + end + local new_path = entry.path:gsub(vim.pesc(from), to) + if entry.type == 'directory' then + IO.mkdir(new_path, tonumber(stat.mode, 10), { recursive = true }):await() + else + IO.fs_copyfile(entry.path, new_path):await() + end + end):await() + else + IO.fs_copyfile(from, to):await() + end + end) +end + +---Walk directory entries recursively. +---@param start_path string +---@param callback fun(err: string|nil, entry: { path: string, type: string }): cmp_dictionary.kit.IO.WalkStatus? +---@param option? { postorder?: boolean } +function IO.walk(start_path, callback, option) + start_path = IO.normalize(start_path) + option = option or {} + option.postorder = option.postorder or false + return Async.run(function() + local function walk_pre(dir) + local ok, iter_entries = pcall(function() + return IO.iter_scandir(dir.path):await() + end) + if not ok then + return callback(iter_entries, dir) + end + local status = callback(nil, dir) + if status == IO.WalkStatus.SkipDir then + return + elseif status == IO.WalkStatus.Break then + return status + end + for entry in iter_entries do + if entry.type == 'directory' then + if walk_pre(entry) == IO.WalkStatus.Break then + return IO.WalkStatus.Break + end + else + if callback(nil, entry) == IO.WalkStatus.Break then + return IO.WalkStatus.Break + end + end + end + end + + local function walk_post(dir) + local ok, iter_entries = pcall(function() + return IO.iter_scandir(dir.path):await() + end) + if not ok then + return callback(iter_entries, dir) + end + for entry in iter_entries do + if entry.type == 'directory' then + if walk_post(entry) == IO.WalkStatus.Break then + return IO.WalkStatus.Break + end + else + if callback(nil, entry) == IO.WalkStatus.Break then + return IO.WalkStatus.Break + end + end + end + return callback(nil, dir) + end + + if not IO.is_directory(start_path) then + error(('IO.walk: `%s` is not a directory.'):format(start_path)) + end + if option.postorder then + walk_post({ path = start_path, type = 'directory' }) + else + walk_pre({ path = start_path, type = 'directory' }) + end + end) +end + +---Scan directory entries. +---@param path string +---@return cmp_dictionary.kit.Async.AsyncTask +function IO.scandir(path) + path = IO.normalize(path) + return Async.run(function() + local fd = IO.fs_scandir(path):await() + local entries = {} + while true do + local name, type = uv.fs_scandir_next(fd) + if not name then + break + end + table.insert(entries, { + type = type, + path = IO.join(path, name), + }) + end + return entries + end) +end + +---Scan directory entries. +---@param path any +---@return cmp_dictionary.kit.Async.AsyncTask +function IO.iter_scandir(path) + path = IO.normalize(path) + return Async.run(function() + local fd = IO.fs_scandir(path):await() + return function() + local name, type = uv.fs_scandir_next(fd) + if name then + return { + type = type, + path = IO.join(path, name), + } + end + end + end) +end + +---Return normalized path. +---@param path string +---@return string +function IO.normalize(path) + if is_windows then + path = path:gsub('\\', '/') + end + + -- remove trailing slash. + if path:sub(-1) == '/' then + path = path:sub(1, -2) + end + + -- skip if the path already absolute. + if IO.is_absolute(path) then + return path + end + + -- homedir. + if path:sub(1, 1) == '~' then + path = IO.join(uv.os_homedir(), path:sub(2)) + end + + -- absolute. + if path:sub(1, 1) == '/' then + return path:sub(-1) == '/' and path:sub(1, -2) or path + end + + -- resolve relative path. + local up = uv.cwd() + up = up:sub(-1) == '/' and up:sub(1, -2) or up + while true do + if path:sub(1, 3) == '../' then + path = path:sub(4) + up = IO.dirname(up) + elseif path:sub(1, 2) == './' then + path = path:sub(3) + else + break + end + end + return IO.join(up, path) +end + +---Join the paths. +---@param base string +---@param path string +---@return string +function IO.join(base, path) + if base:sub(-1) == '/' then + base = base:sub(1, -2) + end + return base .. '/' .. path +end + +---Return the path of the current working directory. +---@param path string +---@return string +function IO.dirname(path) + if path:sub(-1) == '/' then + path = path:sub(1, -2) + end + return (path:gsub('/[^/]+$', '')) +end + +if is_windows then + ---Return the path is absolute or not. + ---@param path string + ---@return boolean + function IO.is_absolute(path) + return path:sub(1, 1) == '/' or path:match('^%a://') + end +else + ---Return the path is absolute or not. + ---@param path string + ---@return boolean + function IO.is_absolute(path) + return path:sub(1, 1) == '/' + end +end + +return IO diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Client.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Client.lua new file mode 100644 index 000000000..1f2f889b7 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Client.lua @@ -0,0 +1,1300 @@ +local LSP = require('cmp_dictionary.kit.LSP') +local AsyncTask = require('cmp_dictionary.kit.Async.AsyncTask') + +---@class cmp_dictionary.kit.LSP.Client +---@field public client table +local Client = {} +Client.__index = Client + +---Create LSP Client wrapper. +---@param client table +---@return cmp_dictionary.kit.LSP.Client +function Client.new(client) + local self = setmetatable({}, Client) + self.client = client + return self +end + +---@param params cmp_dictionary.kit.LSP.ImplementationParams +function Client:textDocument_implementation(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/implementation', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.TypeDefinitionParams +function Client:textDocument_typeDefinition(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/typeDefinition', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:workspace_workspaceFolders(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/workspaceFolders', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@class cmp_dictionary.kit.LSP.IntersectionType01 : cmp_dictionary.kit.LSP.ConfigurationParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@param params cmp_dictionary.kit.LSP.IntersectionType01 +function Client:workspace_configuration(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/configuration', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentColorParams +function Client:textDocument_documentColor(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/documentColor', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.ColorPresentationParams +function Client:textDocument_colorPresentation(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/colorPresentation', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.FoldingRangeParams +function Client:textDocument_foldingRange(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/foldingRange', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DeclarationParams +function Client:textDocument_declaration(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/declaration', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.SelectionRangeParams +function Client:textDocument_selectionRange(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/selectionRange', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.WorkDoneProgressCreateParams +function Client:window_workDoneProgress_create(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('window/workDoneProgress/create', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CallHierarchyPrepareParams +function Client:textDocument_prepareCallHierarchy(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/prepareCallHierarchy', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CallHierarchyIncomingCallsParams +function Client:callHierarchy_incomingCalls(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('callHierarchy/incomingCalls', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CallHierarchyOutgoingCallsParams +function Client:callHierarchy_outgoingCalls(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('callHierarchy/outgoingCalls', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.SemanticTokensParams +function Client:textDocument_semanticTokens_full(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/semanticTokens/full', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.SemanticTokensDeltaParams +function Client:textDocument_semanticTokens_full_delta(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/semanticTokens/full/delta', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.SemanticTokensRangeParams +function Client:textDocument_semanticTokens_range(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/semanticTokens/range', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:workspace_semanticTokens_refresh(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/semanticTokens/refresh', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.ShowDocumentParams +function Client:window_showDocument(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('window/showDocument', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.LinkedEditingRangeParams +function Client:textDocument_linkedEditingRange(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/linkedEditingRange', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CreateFilesParams +function Client:workspace_willCreateFiles(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/willCreateFiles', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.RenameFilesParams +function Client:workspace_willRenameFiles(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/willRenameFiles', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DeleteFilesParams +function Client:workspace_willDeleteFiles(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/willDeleteFiles', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.MonikerParams +function Client:textDocument_moniker(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/moniker', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.TypeHierarchyPrepareParams +function Client:textDocument_prepareTypeHierarchy(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/prepareTypeHierarchy', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.TypeHierarchySupertypesParams +function Client:typeHierarchy_supertypes(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('typeHierarchy/supertypes', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.TypeHierarchySubtypesParams +function Client:typeHierarchy_subtypes(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('typeHierarchy/subtypes', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.InlineValueParams +function Client:textDocument_inlineValue(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/inlineValue', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:workspace_inlineValue_refresh(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/inlineValue/refresh', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.InlayHintParams +function Client:textDocument_inlayHint(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/inlayHint', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.InlayHint +function Client:inlayHint_resolve(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('inlayHint/resolve', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:workspace_inlayHint_refresh(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/inlayHint/refresh', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentDiagnosticParams +function Client:textDocument_diagnostic(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/diagnostic', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.WorkspaceDiagnosticParams +function Client:workspace_diagnostic(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/diagnostic', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:workspace_diagnostic_refresh(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/diagnostic/refresh', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.RegistrationParams +function Client:client_registerCapability(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('client/registerCapability', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.UnregistrationParams +function Client:client_unregisterCapability(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('client/unregisterCapability', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.InitializeParams +function Client:initialize(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('initialize', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:shutdown(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('shutdown', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.ShowMessageRequestParams +function Client:window_showMessageRequest(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('window/showMessageRequest', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.WillSaveTextDocumentParams +function Client:textDocument_willSaveWaitUntil(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/willSaveWaitUntil', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CompletionParams +function Client:textDocument_completion(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/completion', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CompletionItem +function Client:completionItem_resolve(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('completionItem/resolve', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.HoverParams +function Client:textDocument_hover(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/hover', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.SignatureHelpParams +function Client:textDocument_signatureHelp(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/signatureHelp', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DefinitionParams +function Client:textDocument_definition(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/definition', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.ReferenceParams +function Client:textDocument_references(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/references', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentHighlightParams +function Client:textDocument_documentHighlight(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/documentHighlight', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentSymbolParams +function Client:textDocument_documentSymbol(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/documentSymbol', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CodeActionParams +function Client:textDocument_codeAction(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/codeAction', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CodeAction +function Client:codeAction_resolve(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('codeAction/resolve', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.WorkspaceSymbolParams +function Client:workspace_symbol(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/symbol', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.WorkspaceSymbol +function Client:workspaceSymbol_resolve(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspaceSymbol/resolve', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CodeLensParams +function Client:textDocument_codeLens(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/codeLens', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.CodeLens +function Client:codeLens_resolve(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('codeLens/resolve', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params nil +function Client:workspace_codeLens_refresh(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/codeLens/refresh', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentLinkParams +function Client:textDocument_documentLink(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/documentLink', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentLink +function Client:documentLink_resolve(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('documentLink/resolve', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentFormattingParams +function Client:textDocument_formatting(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/formatting', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentRangeFormattingParams +function Client:textDocument_rangeFormatting(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/rangeFormatting', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.DocumentOnTypeFormattingParams +function Client:textDocument_onTypeFormatting(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/onTypeFormatting', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.RenameParams +function Client:textDocument_rename(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/rename', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.PrepareRenameParams +function Client:textDocument_prepareRename(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('textDocument/prepareRename', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.ExecuteCommandParams +function Client:workspace_executeCommand(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/executeCommand', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +---@param params cmp_dictionary.kit.LSP.ApplyWorkspaceEditParams +function Client:workspace_applyEdit(params) + local that, request_id, reject_ = self, nil, nil + local task = AsyncTask.new(function(resolve, reject) + request_id = self.client.request('workspace/applyEdit', params, function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + reject_ = reject + end) + function task.cancel() + that.client.cancel_request(request_id) + reject_(LSP.ErrorCodes.RequestCancelled) + end + return task +end + +return Client diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Position.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Position.lua new file mode 100644 index 000000000..5ac1dbb02 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Position.lua @@ -0,0 +1,103 @@ +local LSP = require('cmp_dictionary.kit.LSP') + +local Position = {} + +---Return the value is position or not. +---@param v any +---@return boolean +function Position.is(v) + local is = true + is = is and (type(v) == 'table' and type(v.line) == 'number' and type(v.character) == 'number') + return is +end + +---Create a cursor position. +---@param encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +function Position.cursor(encoding) + local r, c = unpack(vim.api.nvim_win_get_cursor(0)) + local utf8 = { line = r - 1, character = c } + if encoding == LSP.PositionEncodingKind.UTF8 then + return utf8 + else + local text = vim.api.nvim_get_current_line() + if encoding == LSP.PositionEncodingKind.UTF32 then + return Position.to(text, utf8, LSP.PositionEncodingKind.UTF8, LSP.PositionEncodingKind.UTF32) + end + return Position.to(text, utf8, LSP.PositionEncodingKind.UTF8, LSP.PositionEncodingKind.UTF16) + end +end + +---Convert position to specified encoding from specified encoding. +---@param text string +---@param position cmp_dictionary.kit.LSP.Position +---@param from_encoding cmp_dictionary.kit.LSP.PositionEncodingKind +---@param to_encoding cmp_dictionary.kit.LSP.PositionEncodingKind +function Position.to(text, position, from_encoding, to_encoding) + if to_encoding == LSP.PositionEncodingKind.UTF8 then + return Position.to_utf8(text, position, from_encoding) + elseif to_encoding == LSP.PositionEncodingKind.UTF16 then + return Position.to_utf16(text, position, from_encoding) + elseif to_encoding == LSP.PositionEncodingKind.UTF32 then + return Position.to_utf32(text, position, from_encoding) + end + error('LSP.Position: Unsupported encoding: ' .. to_encoding) +end + +---Convert position to utf8 from specified encoding. +---@param text string +---@param position cmp_dictionary.kit.LSP.Position +---@param from_encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +---@return cmp_dictionary.kit.LSP.Position +function Position.to_utf8(text, position, from_encoding) + from_encoding = from_encoding or LSP.PositionEncodingKind.UTF16 + if from_encoding == LSP.PositionEncodingKind.UTF8 then + return position + end + local ok, byteindex = pcall(function() + return vim.str_byteindex(text, position.character, from_encoding == LSP.PositionEncodingKind.UTF16) + end) + if ok then + position = { line = position.line, character = byteindex } + end + return position +end + +---Convert position to utf16 from specified encoding. +---@param text string +---@param position cmp_dictionary.kit.LSP.Position +---@param from_encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +---@return cmp_dictionary.kit.LSP.Position +function Position.to_utf16(text, position, from_encoding) + local utf8 = Position.to_utf8(text, position, from_encoding) + for index = utf8.character, 0, -1 do + local ok, utf16index = pcall(function() + return select(2, vim.str_utfindex(text, index)) + end) + if ok then + position = { line = utf8.line, character = utf16index } + break + end + end + return position +end + +---Convert position to utf32 from specified encoding. +---@param text string +---@param position cmp_dictionary.kit.LSP.Position +---@param from_encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +---@return cmp_dictionary.kit.LSP.Position +function Position.to_utf32(text, position, from_encoding) + local utf8 = Position.to_utf8(text, position, from_encoding) + for index = utf8.character, 0, -1 do + local ok, utf32index = pcall(function() + return select(1, vim.str_utfindex(text, index)) + end) + if ok then + position = { line = utf8.line, character = utf32index } + break + end + end + return position +end + +return Position diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Range.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Range.lua new file mode 100644 index 000000000..7f8aba317 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/Range.lua @@ -0,0 +1,55 @@ +local Position = require('cmp_dictionary.kit.LSP.Position') + +local Range = {} + +---Return the value is range or not. +---@param v any +---@return boolean +function Range.is(v) + return type(v) == 'table' and Position.is(v.start) and Position.is(v['end']) +end + +---Return the range is empty or not. +---@param range cmp_dictionary.kit.LSP.Range +---@return boolean +function Range.empty(range) + return range.start.line == range['end'].line and range.start.character == range['end'].character +end + +---Convert range to utf8 from specified encoding. +---@param text_start string +---@param range cmp_dictionary.kit.LSP.Range +---@param from_encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +---@return cmp_dictionary.kit.LSP.Range +function Range.to_utf8(text_start, text_end, range, from_encoding) + return { + start = Position.to_utf8(text_start, range.start, from_encoding), + ['end'] = Position.to_utf8(text_end, range['end'], from_encoding), + } +end + +---Convert range to utf16 from specified encoding. +---@param text_start string +---@param range cmp_dictionary.kit.LSP.Range +---@param from_encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +---@return cmp_dictionary.kit.LSP.Range +function Range.to_utf16(text_start, text_end, range, from_encoding) + return { + start = Position.to_utf16(text_start, range.start, from_encoding), + ['end'] = Position.to_utf16(text_end, range['end'], from_encoding), + } +end + +---Convert range to utf32 from specified encoding. +---@param text_start string +---@param range cmp_dictionary.kit.LSP.Range +---@param from_encoding? cmp_dictionary.kit.LSP.PositionEncodingKind +---@return cmp_dictionary.kit.LSP.Range +function Range.to_utf32(text_start, text_end, range, from_encoding) + return { + start = Position.to_utf32(text_start, range.start, from_encoding), + ['end'] = Position.to_utf32(text_end, range['end'], from_encoding), + } +end + +return Range diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/init.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/init.lua new file mode 100644 index 000000000..697584600 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/LSP/init.lua @@ -0,0 +1,1911 @@ +local LSP = {} + +---@enum cmp_dictionary.kit.LSP.SemanticTokenTypes +LSP.SemanticTokenTypes = { + namespace = 'namespace', + type = 'type', + class = 'class', + enum = 'enum', + interface = 'interface', + struct = 'struct', + typeParameter = 'typeParameter', + parameter = 'parameter', + variable = 'variable', + property = 'property', + enumMember = 'enumMember', + event = 'event', + ['function'] = 'function', + method = 'method', + macro = 'macro', + keyword = 'keyword', + modifier = 'modifier', + comment = 'comment', + string = 'string', + number = 'number', + regexp = 'regexp', + operator = 'operator', + decorator = 'decorator', +} + +---@enum cmp_dictionary.kit.LSP.SemanticTokenModifiers +LSP.SemanticTokenModifiers = { + declaration = 'declaration', + definition = 'definition', + readonly = 'readonly', + static = 'static', + deprecated = 'deprecated', + abstract = 'abstract', + async = 'async', + modification = 'modification', + documentation = 'documentation', + defaultLibrary = 'defaultLibrary', +} + +---@enum cmp_dictionary.kit.LSP.DocumentDiagnosticReportKind +LSP.DocumentDiagnosticReportKind = { + Full = 'full', + Unchanged = 'unchanged', +} + +---@enum cmp_dictionary.kit.LSP.ErrorCodes +LSP.ErrorCodes = { + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, + ServerNotInitialized = -32002, + UnknownErrorCode = -32001, +} + +---@enum cmp_dictionary.kit.LSP.LSPErrorCodes +LSP.LSPErrorCodes = { + RequestFailed = -32803, + ServerCancelled = -32802, + ContentModified = -32801, + RequestCancelled = -32800, +} + +---@enum cmp_dictionary.kit.LSP.FoldingRangeKind +LSP.FoldingRangeKind = { + Comment = 'comment', + Imports = 'imports', + Region = 'region', +} + +---@enum cmp_dictionary.kit.LSP.SymbolKind +LSP.SymbolKind = { + File = 1, + Module = 2, + Namespace = 3, + Package = 4, + Class = 5, + Method = 6, + Property = 7, + Field = 8, + Constructor = 9, + Enum = 10, + Interface = 11, + Function = 12, + Variable = 13, + Constant = 14, + String = 15, + Number = 16, + Boolean = 17, + Array = 18, + Object = 19, + Key = 20, + Null = 21, + EnumMember = 22, + Struct = 23, + Event = 24, + Operator = 25, + TypeParameter = 26, +} + +---@enum cmp_dictionary.kit.LSP.SymbolTag +LSP.SymbolTag = { + Deprecated = 1, +} + +---@enum cmp_dictionary.kit.LSP.UniquenessLevel +LSP.UniquenessLevel = { + document = 'document', + project = 'project', + group = 'group', + scheme = 'scheme', + global = 'global', +} + +---@enum cmp_dictionary.kit.LSP.MonikerKind +LSP.MonikerKind = { + import = 'import', + export = 'export', + ['local'] = 'local', +} + +---@enum cmp_dictionary.kit.LSP.InlayHintKind +LSP.InlayHintKind = { + Type = 1, + Parameter = 2, +} + +---@enum cmp_dictionary.kit.LSP.MessageType +LSP.MessageType = { + Error = 1, + Warning = 2, + Info = 3, + Log = 4, +} + +---@enum cmp_dictionary.kit.LSP.TextDocumentSyncKind +LSP.TextDocumentSyncKind = { + None = 0, + Full = 1, + Incremental = 2, +} + +---@enum cmp_dictionary.kit.LSP.TextDocumentSaveReason +LSP.TextDocumentSaveReason = { + Manual = 1, + AfterDelay = 2, + FocusOut = 3, +} + +---@enum cmp_dictionary.kit.LSP.CompletionItemKind +LSP.CompletionItemKind = { + Text = 1, + Method = 2, + Function = 3, + Constructor = 4, + Field = 5, + Variable = 6, + Class = 7, + Interface = 8, + Module = 9, + Property = 10, + Unit = 11, + Value = 12, + Enum = 13, + Keyword = 14, + Snippet = 15, + Color = 16, + File = 17, + Reference = 18, + Folder = 19, + EnumMember = 20, + Constant = 21, + Struct = 22, + Event = 23, + Operator = 24, + TypeParameter = 25, +} + +---@enum cmp_dictionary.kit.LSP.CompletionItemTag +LSP.CompletionItemTag = { + Deprecated = 1, +} + +---@enum cmp_dictionary.kit.LSP.InsertTextFormat +LSP.InsertTextFormat = { + PlainText = 1, + Snippet = 2, +} + +---@enum cmp_dictionary.kit.LSP.InsertTextMode +LSP.InsertTextMode = { + asIs = 1, + adjustIndentation = 2, +} + +---@enum cmp_dictionary.kit.LSP.DocumentHighlightKind +LSP.DocumentHighlightKind = { + Text = 1, + Read = 2, + Write = 3, +} + +---@enum cmp_dictionary.kit.LSP.CodeActionKind +LSP.CodeActionKind = { + Empty = '', + QuickFix = 'quickfix', + Refactor = 'refactor', + RefactorExtract = 'refactor.extract', + RefactorInline = 'refactor.inline', + RefactorRewrite = 'refactor.rewrite', + Source = 'source', + SourceOrganizeImports = 'source.organizeImports', + SourceFixAll = 'source.fixAll', +} + +---@enum cmp_dictionary.kit.LSP.TraceValues +LSP.TraceValues = { + Off = 'off', + Messages = 'messages', + Verbose = 'verbose', +} + +---@enum cmp_dictionary.kit.LSP.MarkupKind +LSP.MarkupKind = { + PlainText = 'plaintext', + Markdown = 'markdown', +} + +---@enum cmp_dictionary.kit.LSP.PositionEncodingKind +LSP.PositionEncodingKind = { + UTF8 = 'utf-8', + UTF16 = 'utf-16', + UTF32 = 'utf-32', +} + +---@enum cmp_dictionary.kit.LSP.FileChangeType +LSP.FileChangeType = { + Created = 1, + Changed = 2, + Deleted = 3, +} + +---@enum cmp_dictionary.kit.LSP.WatchKind +LSP.WatchKind = { + Create = 1, + Change = 2, + Delete = 4, +} + +---@enum cmp_dictionary.kit.LSP.DiagnosticSeverity +LSP.DiagnosticSeverity = { + Error = 1, + Warning = 2, + Information = 3, + Hint = 4, +} + +---@enum cmp_dictionary.kit.LSP.DiagnosticTag +LSP.DiagnosticTag = { + Unnecessary = 1, + Deprecated = 2, +} + +---@enum cmp_dictionary.kit.LSP.CompletionTriggerKind +LSP.CompletionTriggerKind = { + Invoked = 1, + TriggerCharacter = 2, + TriggerForIncompleteCompletions = 3, +} + +---@enum cmp_dictionary.kit.LSP.SignatureHelpTriggerKind +LSP.SignatureHelpTriggerKind = { + Invoked = 1, + TriggerCharacter = 2, + ContentChange = 3, +} + +---@enum cmp_dictionary.kit.LSP.CodeActionTriggerKind +LSP.CodeActionTriggerKind = { + Invoked = 1, + Automatic = 2, +} + +---@enum cmp_dictionary.kit.LSP.FileOperationPatternKind +LSP.FileOperationPatternKind = { + file = 'file', + folder = 'folder', +} + +---@enum cmp_dictionary.kit.LSP.NotebookCellKind +LSP.NotebookCellKind = { + Markup = 1, + Code = 2, +} + +---@enum cmp_dictionary.kit.LSP.ResourceOperationKind +LSP.ResourceOperationKind = { + Create = 'create', + Rename = 'rename', + Delete = 'delete', +} + +---@enum cmp_dictionary.kit.LSP.FailureHandlingKind +LSP.FailureHandlingKind = { + Abort = 'abort', + Transactional = 'transactional', + TextOnlyTransactional = 'textOnlyTransactional', + Undo = 'undo', +} + +---@enum cmp_dictionary.kit.LSP.PrepareSupportDefaultBehavior +LSP.PrepareSupportDefaultBehavior = { + Identifier = 1, +} + +---@enum cmp_dictionary.kit.LSP.TokenFormat +LSP.TokenFormat = { + Relative = 'relative', +} + +---@class cmp_dictionary.kit.LSP.ImplementationParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@class cmp_dictionary.kit.LSP.Location +---@field public uri string +---@field public range cmp_dictionary.kit.LSP.Range + +---@class cmp_dictionary.kit.LSP.ImplementationRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.ImplementationOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.TypeDefinitionParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@class cmp_dictionary.kit.LSP.TypeDefinitionRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.TypeDefinitionOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.WorkspaceFolder +---@field public uri string The associated URI for this workspace folder. +---@field public name string The name of the workspace folder. Used to refer to this
workspace folder in the user interface. + +---@class cmp_dictionary.kit.LSP.DidChangeWorkspaceFoldersParams +---@field public event cmp_dictionary.kit.LSP.WorkspaceFoldersChangeEvent The actual workspace folder change event. + +---@class cmp_dictionary.kit.LSP.ConfigurationParams +---@field public items cmp_dictionary.kit.LSP.ConfigurationItem[] + +---@class cmp_dictionary.kit.LSP.PartialResultParams +---@field public partialResultToken? cmp_dictionary.kit.LSP.ProgressToken An optional token that a server can use to report partial results (e.g. streaming) to
the client. + +---@class cmp_dictionary.kit.LSP.DocumentColorParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. + +---@class cmp_dictionary.kit.LSP.ColorInformation +---@field public range cmp_dictionary.kit.LSP.Range The range in the document where this color appears. +---@field public color cmp_dictionary.kit.LSP.Color The actual color value for this color range. + +---@class cmp_dictionary.kit.LSP.DocumentColorRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentColorOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.ColorPresentationParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public color cmp_dictionary.kit.LSP.Color The color to request presentations for. +---@field public range cmp_dictionary.kit.LSP.Range The range where the color would be inserted. Serves as a context. + +---@class cmp_dictionary.kit.LSP.ColorPresentation +---@field public label string The label of this color presentation. It will be shown on the color
picker header. By default this is also the text that is inserted when selecting
this color presentation. +---@field public textEdit? cmp_dictionary.kit.LSP.TextEdit An [edit](#TextEdit) which is applied to a document when selecting
this presentation for the color. When `falsy` the [label](#ColorPresentation.label)
is used. +---@field public additionalTextEdits? cmp_dictionary.kit.LSP.TextEdit[] An optional array of additional [text edits](#TextEdit) that are applied when
selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves. + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public workDoneProgress? boolean + +---@class cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions +---@field public documentSelector (cmp_dictionary.kit.LSP.DocumentSelector | nil) A document selector to identify the scope of the registration. If set to null
the document selector provided on the client side will be used. + +---@class cmp_dictionary.kit.LSP.FoldingRangeParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. + +---@class cmp_dictionary.kit.LSP.FoldingRange +---@field public startLine integer The zero-based start line of the range to fold. The folded area starts after the line's last character.
To be valid, the end must be zero or larger and smaller than the number of lines in the document. +---@field public startCharacter? integer The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line. +---@field public endLine integer The zero-based end line of the range to fold. The folded area ends with the line's last character.
To be valid, the end must be zero or larger and smaller than the number of lines in the document. +---@field public endCharacter? integer The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line. +---@field public kind? cmp_dictionary.kit.LSP.FoldingRangeKind Describes the kind of the folding range such as `comment' or 'region'. The kind
is used to categorize folding ranges and used by commands like 'Fold all comments'.
See [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds. +---@field public collapsedText? string The text that the client should show when the specified range is
collapsed. If not defined or not supported by the client, a default
will be chosen by the client.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.FoldingRangeRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.FoldingRangeOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.DeclarationParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@class cmp_dictionary.kit.LSP.DeclarationRegistrationOptions : cmp_dictionary.kit.LSP.DeclarationOptions, cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.SelectionRangeParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public positions cmp_dictionary.kit.LSP.Position[] The positions inside the text document. + +---@class cmp_dictionary.kit.LSP.SelectionRange +---@field public range cmp_dictionary.kit.LSP.Range The [range](#Range) of this selection range. +---@field public parent? cmp_dictionary.kit.LSP.SelectionRange The parent selection range containing this range. Therefore `parent.range` must contain `this.range`. + +---@class cmp_dictionary.kit.LSP.SelectionRangeRegistrationOptions : cmp_dictionary.kit.LSP.SelectionRangeOptions, cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressCreateParams +---@field public token cmp_dictionary.kit.LSP.ProgressToken The token to be used to report progress. + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressCancelParams +---@field public token cmp_dictionary.kit.LSP.ProgressToken The token to be used to report progress. + +---@class cmp_dictionary.kit.LSP.CallHierarchyPrepareParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams + +---@class cmp_dictionary.kit.LSP.CallHierarchyItem +---@field public name string The name of this item. +---@field public kind cmp_dictionary.kit.LSP.SymbolKind The kind of this item. +---@field public tags? cmp_dictionary.kit.LSP.SymbolTag[] Tags for this item. +---@field public detail? string More detail for this item, e.g. the signature of a function. +---@field public uri string The resource identifier of this item. +---@field public range cmp_dictionary.kit.LSP.Range The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code. +---@field public selectionRange cmp_dictionary.kit.LSP.Range The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.
Must be contained by the [`range`](#CallHierarchyItem.range). +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved between a call hierarchy prepare and
incoming calls or outgoing calls requests. + +---@class cmp_dictionary.kit.LSP.CallHierarchyRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.CallHierarchyOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.CallHierarchyIncomingCallsParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public item cmp_dictionary.kit.LSP.CallHierarchyItem + +---@class cmp_dictionary.kit.LSP.CallHierarchyIncomingCall +---@field public from cmp_dictionary.kit.LSP.CallHierarchyItem The item that makes the call. +---@field public fromRanges cmp_dictionary.kit.LSP.Range[] The ranges at which the calls appear. This is relative to the caller
denoted by [`this.from`](#CallHierarchyIncomingCall.from). + +---@class cmp_dictionary.kit.LSP.CallHierarchyOutgoingCallsParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public item cmp_dictionary.kit.LSP.CallHierarchyItem + +---@class cmp_dictionary.kit.LSP.CallHierarchyOutgoingCall +---@field public to cmp_dictionary.kit.LSP.CallHierarchyItem The item that is called. +---@field public fromRanges cmp_dictionary.kit.LSP.Range[] The range at which this item is called. This is the range relative to the caller, e.g the item
passed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)
and not [`this.to`](#CallHierarchyOutgoingCall.to). + +---@class cmp_dictionary.kit.LSP.SemanticTokensParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. + +---@class cmp_dictionary.kit.LSP.SemanticTokens +---@field public resultId? string An optional result id. If provided and clients support delta updating
the client will include the result id in the next semantic token request.
A server can then instead of computing all semantic tokens again simply
send a delta. +---@field public data integer[] The actual tokens. + +---@class cmp_dictionary.kit.LSP.SemanticTokensPartialResult +---@field public data integer[] + +---@class cmp_dictionary.kit.LSP.SemanticTokensRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.SemanticTokensOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.SemanticTokensDeltaParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public previousResultId string The result id of a previous response. The result Id can either point to a full response
or a delta response depending on what was received last. + +---@class cmp_dictionary.kit.LSP.SemanticTokensDelta +---@field public resultId? string +---@field public edits cmp_dictionary.kit.LSP.SemanticTokensEdit[] The semantic token edits to transform a previous result into a new result. + +---@class cmp_dictionary.kit.LSP.SemanticTokensDeltaPartialResult +---@field public edits cmp_dictionary.kit.LSP.SemanticTokensEdit[] + +---@class cmp_dictionary.kit.LSP.SemanticTokensRangeParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public range cmp_dictionary.kit.LSP.Range The range the semantic tokens are requested for. + +---@class cmp_dictionary.kit.LSP.ShowDocumentParams +---@field public uri string The document uri to show. +---@field public external? boolean Indicates to show the resource in an external program.
To show for example `https://code.visualstudio.com/`
in the default WEB browser set `external` to `true`. +---@field public takeFocus? boolean An optional property to indicate whether the editor
showing the document should take focus or not.
Clients might ignore this property if an external
program is started. +---@field public selection? cmp_dictionary.kit.LSP.Range An optional selection range if the document is a text
document. Clients might ignore the property if an
external program is started or the file is not a text
file. + +---@class cmp_dictionary.kit.LSP.ShowDocumentResult +---@field public success boolean A boolean indicating if the show was successful. + +---@class cmp_dictionary.kit.LSP.LinkedEditingRangeParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams + +---@class cmp_dictionary.kit.LSP.LinkedEditingRanges +---@field public ranges cmp_dictionary.kit.LSP.Range[] A list of ranges that can be edited together. The ranges must have
identical length and contain identical text content. The ranges cannot overlap. +---@field public wordPattern? string An optional word pattern (regular expression) that describes valid contents for
the given ranges. If no pattern is provided, the client configuration's word
pattern will be used. + +---@class cmp_dictionary.kit.LSP.LinkedEditingRangeRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.LinkedEditingRangeOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.CreateFilesParams +---@field public files cmp_dictionary.kit.LSP.FileCreate[] An array of all files/folders created in this operation. + +---@class cmp_dictionary.kit.LSP.WorkspaceEdit +---@field public changes? table Holds changes to existing resources. +---@field public documentChanges? (cmp_dictionary.kit.LSP.TextDocumentEdit | cmp_dictionary.kit.LSP.CreateFile | cmp_dictionary.kit.LSP.RenameFile | cmp_dictionary.kit.LSP.DeleteFile)[] Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes
are either an array of `TextDocumentEdit`s to express changes to n different text documents
where each text document edit addresses a specific version of a text document. Or it can contain
above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations.

Whether a client supports versioned document edits is expressed via
`workspace.workspaceEdit.documentChanges` client capability.

If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then
only plain `TextEdit`s using the `changes` property are supported. +---@field public changeAnnotations? table A map of change annotations that can be referenced in `AnnotatedTextEdit`s or create, rename and
delete file / folder operations.

Whether clients honor this property depends on the client capability `workspace.changeAnnotationSupport`.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.FileOperationRegistrationOptions +---@field public filters cmp_dictionary.kit.LSP.FileOperationFilter[] The actual filters. + +---@class cmp_dictionary.kit.LSP.RenameFilesParams +---@field public files cmp_dictionary.kit.LSP.FileRename[] An array of all files/folders renamed in this operation. When a folder is renamed, only
the folder will be included, and not its children. + +---@class cmp_dictionary.kit.LSP.DeleteFilesParams +---@field public files cmp_dictionary.kit.LSP.FileDelete[] An array of all files/folders deleted in this operation. + +---@class cmp_dictionary.kit.LSP.MonikerParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@class cmp_dictionary.kit.LSP.Moniker +---@field public scheme string The scheme of the moniker. For example tsc or .Net +---@field public identifier string The identifier of the moniker. The value is opaque in LSIF however
schema owners are allowed to define the structure if they want. +---@field public unique cmp_dictionary.kit.LSP.UniquenessLevel The scope in which the moniker is unique +---@field public kind? cmp_dictionary.kit.LSP.MonikerKind The moniker kind if known. + +---@class cmp_dictionary.kit.LSP.MonikerRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.MonikerOptions + +---@class cmp_dictionary.kit.LSP.TypeHierarchyPrepareParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams + +---@class cmp_dictionary.kit.LSP.TypeHierarchyItem +---@field public name string The name of this item. +---@field public kind cmp_dictionary.kit.LSP.SymbolKind The kind of this item. +---@field public tags? cmp_dictionary.kit.LSP.SymbolTag[] Tags for this item. +---@field public detail? string More detail for this item, e.g. the signature of a function. +---@field public uri string The resource identifier of this item. +---@field public range cmp_dictionary.kit.LSP.Range The range enclosing this symbol not including leading/trailing whitespace
but everything else, e.g. comments and code. +---@field public selectionRange cmp_dictionary.kit.LSP.Range The range that should be selected and revealed when this symbol is being
picked, e.g. the name of a function. Must be contained by the
[`range`](#TypeHierarchyItem.range). +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved between a type hierarchy prepare and
supertypes or subtypes requests. It could also be used to identify the
type hierarchy in the server, helping improve the performance on
resolving supertypes and subtypes. + +---@class cmp_dictionary.kit.LSP.TypeHierarchyRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.TypeHierarchyOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.TypeHierarchySupertypesParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public item cmp_dictionary.kit.LSP.TypeHierarchyItem + +---@class cmp_dictionary.kit.LSP.TypeHierarchySubtypesParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public item cmp_dictionary.kit.LSP.TypeHierarchyItem + +---@class cmp_dictionary.kit.LSP.InlineValueParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public range cmp_dictionary.kit.LSP.Range The document range for which inline values should be computed. +---@field public context cmp_dictionary.kit.LSP.InlineValueContext Additional information about the context in which inline values were
requested. + +---@class cmp_dictionary.kit.LSP.InlineValueRegistrationOptions : cmp_dictionary.kit.LSP.InlineValueOptions, cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.InlayHintParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public range cmp_dictionary.kit.LSP.Range The document range for which inlay hints should be computed. + +---@class cmp_dictionary.kit.LSP.InlayHint +---@field public position cmp_dictionary.kit.LSP.Position The position of this hint. +---@field public label (string | cmp_dictionary.kit.LSP.InlayHintLabelPart[]) The label of this hint. A human readable string or an array of
InlayHintLabelPart label parts.

*Note* that neither the string nor the label part can be empty. +---@field public kind? cmp_dictionary.kit.LSP.InlayHintKind The kind of this hint. Can be omitted in which case the client
should fall back to a reasonable default. +---@field public textEdits? cmp_dictionary.kit.LSP.TextEdit[] Optional text edits that are performed when accepting this inlay hint.

*Note* that edits are expected to change the document so that the inlay
hint (or its nearest variant) is now part of the document and the inlay
hint itself is now obsolete. +---@field public tooltip? (string | cmp_dictionary.kit.LSP.MarkupContent) The tooltip text when you hover over this item. +---@field public paddingLeft? boolean Render padding before the hint.

Note: Padding should use the editor's background color, not the
background color of the hint itself. That means padding can be used
to visually align/separate an inlay hint. +---@field public paddingRight? boolean Render padding after the hint.

Note: Padding should use the editor's background color, not the
background color of the hint itself. That means padding can be used
to visually align/separate an inlay hint. +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved on an inlay hint between
a `textDocument/inlayHint` and a `inlayHint/resolve` request. + +---@class cmp_dictionary.kit.LSP.InlayHintRegistrationOptions : cmp_dictionary.kit.LSP.InlayHintOptions, cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.DocumentDiagnosticParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public identifier? string The additional identifier provided during registration. +---@field public previousResultId? string The result id of a previous response if provided. + +---@class cmp_dictionary.kit.LSP.DocumentDiagnosticReportPartialResult +---@field public relatedDocuments table + +---@class cmp_dictionary.kit.LSP.DiagnosticServerCancellationData +---@field public retriggerRequest boolean + +---@class cmp_dictionary.kit.LSP.DiagnosticRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DiagnosticOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.WorkspaceDiagnosticParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public identifier? string The additional identifier provided during registration. +---@field public previousResultIds cmp_dictionary.kit.LSP.PreviousResultId[] The currently known diagnostic reports with their
previous result ids. + +---@class cmp_dictionary.kit.LSP.WorkspaceDiagnosticReport +---@field public items cmp_dictionary.kit.LSP.WorkspaceDocumentDiagnosticReport[] + +---@class cmp_dictionary.kit.LSP.WorkspaceDiagnosticReportPartialResult +---@field public items cmp_dictionary.kit.LSP.WorkspaceDocumentDiagnosticReport[] + +---@class cmp_dictionary.kit.LSP.DidOpenNotebookDocumentParams +---@field public notebookDocument cmp_dictionary.kit.LSP.NotebookDocument The notebook document that got opened. +---@field public cellTextDocuments cmp_dictionary.kit.LSP.TextDocumentItem[] The text documents that represent the content
of a notebook cell. + +---@class cmp_dictionary.kit.LSP.DidChangeNotebookDocumentParams +---@field public notebookDocument cmp_dictionary.kit.LSP.VersionedNotebookDocumentIdentifier The notebook document that did change. The version number points
to the version after all provided changes have been applied. If
only the text document content of a cell changes the notebook version
doesn't necessarily have to change. +---@field public change cmp_dictionary.kit.LSP.NotebookDocumentChangeEvent The actual changes to the notebook document.

The changes describe single state changes to the notebook document.
So if there are two changes c1 (at array index 0) and c2 (at array
index 1) for a notebook in state S then c1 moves the notebook from
S to S' and c2 from S' to S''. So c1 is computed on the state S and
c2 is computed on the state S'.

To mirror the content of a notebook using change events use the following approach:
- start with the same initial content
- apply the 'notebookDocument/didChange' notifications in the order you receive them.
- apply the `NotebookChangeEvent`s in a single notification in the order
you receive them. + +---@class cmp_dictionary.kit.LSP.DidSaveNotebookDocumentParams +---@field public notebookDocument cmp_dictionary.kit.LSP.NotebookDocumentIdentifier The notebook document that got saved. + +---@class cmp_dictionary.kit.LSP.DidCloseNotebookDocumentParams +---@field public notebookDocument cmp_dictionary.kit.LSP.NotebookDocumentIdentifier The notebook document that got closed. +---@field public cellTextDocuments cmp_dictionary.kit.LSP.TextDocumentIdentifier[] The text documents that represent the content
of a notebook cell that got closed. + +---@class cmp_dictionary.kit.LSP.RegistrationParams +---@field public registrations cmp_dictionary.kit.LSP.Registration[] + +---@class cmp_dictionary.kit.LSP.UnregistrationParams +---@field public unregisterations cmp_dictionary.kit.LSP.Unregistration[] + +---@class cmp_dictionary.kit.LSP.InitializeParams : cmp_dictionary.kit.LSP._InitializeParams, cmp_dictionary.kit.LSP.WorkspaceFoldersInitializeParams + +---@class cmp_dictionary.kit.LSP.InitializeResult +---@field public capabilities cmp_dictionary.kit.LSP.ServerCapabilities The capabilities the language server provides. +---@field public serverInfo? cmp_dictionary.kit.LSP.InitializeResult.serverInfo Information about the server.

@since 3.15.0 + +---@class cmp_dictionary.kit.LSP.InitializeResult.serverInfo +---@field public name string The name of the server as defined by the server. +---@field public version? string The server's version as defined by the server. + +---@class cmp_dictionary.kit.LSP.InitializeError +---@field public retry boolean Indicates whether the client execute the following retry logic:
(1) show the message provided by the ResponseError to the user
(2) user selects retry or cancel
(3) if user selected retry the initialize method is sent again. + +---@class cmp_dictionary.kit.LSP.InitializedParams + +---@class cmp_dictionary.kit.LSP.DidChangeConfigurationParams +---@field public settings cmp_dictionary.kit.LSP.LSPAny The actual changed settings + +---@class cmp_dictionary.kit.LSP.DidChangeConfigurationRegistrationOptions +---@field public section? (string | string[]) + +---@class cmp_dictionary.kit.LSP.ShowMessageParams +---@field public type cmp_dictionary.kit.LSP.MessageType The message type. See {@link MessageType} +---@field public message string The actual message. + +---@class cmp_dictionary.kit.LSP.ShowMessageRequestParams +---@field public type cmp_dictionary.kit.LSP.MessageType The message type. See {@link MessageType} +---@field public message string The actual message. +---@field public actions? cmp_dictionary.kit.LSP.MessageActionItem[] The message action items to present. + +---@class cmp_dictionary.kit.LSP.MessageActionItem +---@field public title string A short title like 'Retry', 'Open Log' etc. + +---@class cmp_dictionary.kit.LSP.LogMessageParams +---@field public type cmp_dictionary.kit.LSP.MessageType The message type. See {@link MessageType} +---@field public message string The actual message. + +---@class cmp_dictionary.kit.LSP.DidOpenTextDocumentParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentItem The document that was opened. + +---@class cmp_dictionary.kit.LSP.DidChangeTextDocumentParams +---@field public textDocument cmp_dictionary.kit.LSP.VersionedTextDocumentIdentifier The document that did change. The version number points
to the version after all provided content changes have
been applied. +---@field public contentChanges cmp_dictionary.kit.LSP.TextDocumentContentChangeEvent[] The actual content changes. The content changes describe single state changes
to the document. So if there are two content changes c1 (at array index 0) and
c2 (at array index 1) for a document in state S then c1 moves the document from
S to S' and c2 from S' to S''. So c1 is computed on the state S and c2 is computed
on the state S'.

To mirror the content of a document using change events use the following approach:
- start with the same initial content
- apply the 'textDocument/didChange' notifications in the order you receive them.
- apply the `TextDocumentContentChangeEvent`s in a single notification in the order
you receive them. + +---@class cmp_dictionary.kit.LSP.TextDocumentChangeRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions +---@field public syncKind cmp_dictionary.kit.LSP.TextDocumentSyncKind How documents are synced to the server. + +---@class cmp_dictionary.kit.LSP.DidCloseTextDocumentParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document that was closed. + +---@class cmp_dictionary.kit.LSP.DidSaveTextDocumentParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document that was saved. +---@field public text? string Optional the content when saved. Depends on the includeText value
when the save notification was requested. + +---@class cmp_dictionary.kit.LSP.TextDocumentSaveRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.SaveOptions + +---@class cmp_dictionary.kit.LSP.WillSaveTextDocumentParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document that will be saved. +---@field public reason cmp_dictionary.kit.LSP.TextDocumentSaveReason The 'TextDocumentSaveReason'. + +---@class cmp_dictionary.kit.LSP.TextEdit +---@field public range cmp_dictionary.kit.LSP.Range The range of the text document to be manipulated. To insert
text into a document create a range where start === end. +---@field public newText string The string to be inserted. For delete operations use an
empty string. + +---@class cmp_dictionary.kit.LSP.DidChangeWatchedFilesParams +---@field public changes cmp_dictionary.kit.LSP.FileEvent[] The actual file events. + +---@class cmp_dictionary.kit.LSP.DidChangeWatchedFilesRegistrationOptions +---@field public watchers cmp_dictionary.kit.LSP.FileSystemWatcher[] The watchers to register. + +---@class cmp_dictionary.kit.LSP.PublishDiagnosticsParams +---@field public uri string The URI for which diagnostic information is reported. +---@field public version? integer Optional the version number of the document the diagnostics are published for.

@since 3.15.0 +---@field public diagnostics cmp_dictionary.kit.LSP.Diagnostic[] An array of diagnostic information items. + +---@class cmp_dictionary.kit.LSP.CompletionParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public context? cmp_dictionary.kit.LSP.CompletionContext The completion context. This is only available it the client specifies
to send this using the client capability `textDocument.completion.contextSupport === true` + +---@class cmp_dictionary.kit.LSP.CompletionItem +---@field public label string The label of this completion item.

The label property is also by default the text that
is inserted when selecting this completion.

If label details are provided the label itself should
be an unqualified name of the completion item. +---@field public labelDetails? cmp_dictionary.kit.LSP.CompletionItemLabelDetails Additional details for the label

@since 3.17.0 +---@field public kind? cmp_dictionary.kit.LSP.CompletionItemKind The kind of this completion item. Based of the kind
an icon is chosen by the editor. +---@field public tags? cmp_dictionary.kit.LSP.CompletionItemTag[] Tags for this completion item.

@since 3.15.0 +---@field public detail? string A human-readable string with additional information
about this item, like type or symbol information. +---@field public documentation? (string | cmp_dictionary.kit.LSP.MarkupContent) A human-readable string that represents a doc-comment. +---@field public deprecated? boolean Indicates if this item is deprecated.
@deprecated Use `tags` instead. +---@field public preselect? boolean Select this item when showing.

*Note* that only one completion item can be selected and that the
tool / client decides which item that is. The rule is that the *first*
item of those that match best is selected. +---@field public sortText? string A string that should be used when comparing this item
with other items. When `falsy` the [label](#CompletionItem.label)
is used. +---@field public filterText? string A string that should be used when filtering a set of
completion items. When `falsy` the [label](#CompletionItem.label)
is used. +---@field public insertText? string A string that should be inserted into a document when selecting
this completion. When `falsy` the [label](#CompletionItem.label)
is used.

The `insertText` is subject to interpretation by the client side.
Some tools might not take the string literally. For example
VS Code when code complete is requested in this example
`con` and a completion item with an `insertText` of
`console` is provided it will only insert `sole`. Therefore it is
recommended to use `textEdit` instead since it avoids additional client
side interpretation. +---@field public insertTextFormat? cmp_dictionary.kit.LSP.InsertTextFormat The format of the insert text. The format applies to both the
`insertText` property and the `newText` property of a provided
`textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.

Please note that the insertTextFormat doesn't apply to
`additionalTextEdits`. +---@field public insertTextMode? cmp_dictionary.kit.LSP.InsertTextMode How whitespace and indentation is handled during completion
item insertion. If not provided the clients default value depends on
the `textDocument.completion.insertTextMode` client capability.

@since 3.16.0 +---@field public textEdit? (cmp_dictionary.kit.LSP.TextEdit | cmp_dictionary.kit.LSP.InsertReplaceEdit) An [edit](#TextEdit) which is applied to a document when selecting
this completion. When an edit is provided the value of
[insertText](#CompletionItem.insertText) is ignored.

Most editors support two different operations when accepting a completion
item. One is to insert a completion text and the other is to replace an
existing text with a completion text. Since this can usually not be
predetermined by a server it can report both ranges. Clients need to
signal support for `InsertReplaceEdits` via the
`textDocument.completion.insertReplaceSupport` client capability
property.

*Note 1:* The text edit's range as well as both ranges from an insert
replace edit must be a [single line] and they must contain the position
at which completion has been requested.
*Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range
must be a prefix of the edit's replace range, that means it must be
contained and starting at the same position.

@since 3.16.0 additional type `InsertReplaceEdit` +---@field public textEditText? string The edit text used if the completion item is part of a CompletionList and
CompletionList defines an item default for the text edit range.

Clients will only honor this property if they opt into completion list
item defaults using the capability `completionList.itemDefaults`.

If not provided and a list's default range is provided the label
property is used as a text.

@since 3.17.0 +---@field public additionalTextEdits? cmp_dictionary.kit.LSP.TextEdit[] An optional array of additional [text edits](#TextEdit) that are applied when
selecting this completion. Edits must not overlap (including the same insert position)
with the main [edit](#CompletionItem.textEdit) nor with themselves.

Additional text edits should be used to change text unrelated to the current cursor position
(for example adding an import statement at the top of the file if the completion item will
insert an unqualified type). +---@field public commitCharacters? string[] An optional set of characters that when pressed while this completion is active will accept it first and
then type that character. *Note* that all commit characters should have `length=1` and that superfluous
characters will be ignored. +---@field public command? cmp_dictionary.kit.LSP.Command An optional [command](#Command) that is executed *after* inserting this completion. *Note* that
additional modifications to the current document should be described with the
[additionalTextEdits](#CompletionItem.additionalTextEdits)-property. +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved on a completion item between a
[CompletionRequest](#CompletionRequest) and a [CompletionResolveRequest](#CompletionResolveRequest). + +---@class cmp_dictionary.kit.LSP.CompletionList +---@field public isIncomplete boolean This list it not complete. Further typing results in recomputing this list.

Recomputed lists have all their items replaced (not appended) in the
incomplete completion sessions. +---@field public itemDefaults? cmp_dictionary.kit.LSP.CompletionList.itemDefaults In many cases the items of an actual completion result share the same
value for properties like `commitCharacters` or the range of a text
edit. A completion list can therefore define item defaults which will
be used if a completion item itself doesn't specify the value.

If a completion list specifies a default value and a completion item
also specifies a corresponding value the one from the item is used.

Servers are only allowed to return default values if the client
signals support for this via the `completionList.itemDefaults`
capability.

@since 3.17.0 +---@field public items cmp_dictionary.kit.LSP.CompletionItem[] The completion items. + +---@class cmp_dictionary.kit.LSP.CompletionList.itemDefaults +---@field public commitCharacters? string[] A default commit character set.

@since 3.17.0 +---@field public editRange? (cmp_dictionary.kit.LSP.Range | { insert: cmp_dictionary.kit.LSP.Range, replace: cmp_dictionary.kit.LSP.Range }) A default edit range.

@since 3.17.0 +---@field public insertTextFormat? cmp_dictionary.kit.LSP.InsertTextFormat A default insert text format.

@since 3.17.0 +---@field public insertTextMode? cmp_dictionary.kit.LSP.InsertTextMode A default insert text mode.

@since 3.17.0 +---@field public data? cmp_dictionary.kit.LSP.LSPAny A default data value.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.CompletionRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.CompletionOptions + +---@class cmp_dictionary.kit.LSP.HoverParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams + +---@class cmp_dictionary.kit.LSP.Hover +---@field public contents (cmp_dictionary.kit.LSP.MarkupContent | cmp_dictionary.kit.LSP.MarkedString | cmp_dictionary.kit.LSP.MarkedString[]) The hover's content +---@field public range? cmp_dictionary.kit.LSP.Range An optional range inside the text document that is used to
visualize the hover, e.g. by changing the background color. + +---@class cmp_dictionary.kit.LSP.HoverRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.HoverOptions + +---@class cmp_dictionary.kit.LSP.SignatureHelpParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public context? cmp_dictionary.kit.LSP.SignatureHelpContext The signature help context. This is only available if the client specifies
to send this using the client capability `textDocument.signatureHelp.contextSupport === true`

@since 3.15.0 + +---@class cmp_dictionary.kit.LSP.SignatureHelp +---@field public signatures cmp_dictionary.kit.LSP.SignatureInformation[] One or more signatures. +---@field public activeSignature? integer The active signature. If omitted or the value lies outside the
range of `signatures` the value defaults to zero or is ignored if
the `SignatureHelp` has no signatures.

Whenever possible implementors should make an active decision about
the active signature and shouldn't rely on a default value.

In future version of the protocol this property might become
mandatory to better express this. +---@field public activeParameter? integer The active parameter of the active signature. If omitted or the value
lies outside the range of `signatures[activeSignature].parameters`
defaults to 0 if the active signature has parameters. If
the active signature has no parameters it is ignored.
In future version of the protocol this property might become
mandatory to better express the active parameter if the
active signature does have any. + +---@class cmp_dictionary.kit.LSP.SignatureHelpRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.SignatureHelpOptions + +---@class cmp_dictionary.kit.LSP.DefinitionParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@class cmp_dictionary.kit.LSP.DefinitionRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DefinitionOptions + +---@class cmp_dictionary.kit.LSP.ReferenceParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public context cmp_dictionary.kit.LSP.ReferenceContext + +---@class cmp_dictionary.kit.LSP.ReferenceRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.ReferenceOptions + +---@class cmp_dictionary.kit.LSP.DocumentHighlightParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams + +---@class cmp_dictionary.kit.LSP.DocumentHighlight +---@field public range cmp_dictionary.kit.LSP.Range The range this highlight applies to. +---@field public kind? cmp_dictionary.kit.LSP.DocumentHighlightKind The highlight kind, default is [text](#DocumentHighlightKind.Text). + +---@class cmp_dictionary.kit.LSP.DocumentHighlightRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentHighlightOptions + +---@class cmp_dictionary.kit.LSP.DocumentSymbolParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. + +---@class cmp_dictionary.kit.LSP.SymbolInformation : cmp_dictionary.kit.LSP.BaseSymbolInformation +---@field public deprecated? boolean Indicates if this symbol is deprecated.

@deprecated Use tags instead +---@field public location cmp_dictionary.kit.LSP.Location The location of this symbol. The location's range is used by a tool
to reveal the location in the editor. If the symbol is selected in the
tool the range's start information is used to position the cursor. So
the range usually spans more than the actual symbol's name and does
normally include things like visibility modifiers.

The range doesn't have to denote a node range in the sense of an abstract
syntax tree. It can therefore not be used to re-construct a hierarchy of
the symbols. + +---@class cmp_dictionary.kit.LSP.DocumentSymbol +---@field public name string The name of this symbol. Will be displayed in the user interface and therefore must not be
an empty string or a string only consisting of white spaces. +---@field public detail? string More detail for this symbol, e.g the signature of a function. +---@field public kind cmp_dictionary.kit.LSP.SymbolKind The kind of this symbol. +---@field public tags? cmp_dictionary.kit.LSP.SymbolTag[] Tags for this document symbol.

@since 3.16.0 +---@field public deprecated? boolean Indicates if this symbol is deprecated.

@deprecated Use tags instead +---@field public range cmp_dictionary.kit.LSP.Range The range enclosing this symbol not including leading/trailing whitespace but everything else
like comments. This information is typically used to determine if the clients cursor is
inside the symbol to reveal in the symbol in the UI. +---@field public selectionRange cmp_dictionary.kit.LSP.Range The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
Must be contained by the `range`. +---@field public children? cmp_dictionary.kit.LSP.DocumentSymbol[] Children of this symbol, e.g. properties of a class. + +---@class cmp_dictionary.kit.LSP.DocumentSymbolRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentSymbolOptions + +---@class cmp_dictionary.kit.LSP.CodeActionParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document in which the command was invoked. +---@field public range cmp_dictionary.kit.LSP.Range The range for which the command was invoked. +---@field public context cmp_dictionary.kit.LSP.CodeActionContext Context carrying additional information. + +---@class cmp_dictionary.kit.LSP.Command +---@field public title string Title of the command, like `save`. +---@field public command string The identifier of the actual command handler. +---@field public arguments? cmp_dictionary.kit.LSP.LSPAny[] Arguments that the command handler should be
invoked with. + +---@class cmp_dictionary.kit.LSP.CodeAction +---@field public title string A short, human-readable, title for this code action. +---@field public kind? cmp_dictionary.kit.LSP.CodeActionKind The kind of the code action.

Used to filter code actions. +---@field public diagnostics? cmp_dictionary.kit.LSP.Diagnostic[] The diagnostics that this code action resolves. +---@field public isPreferred? boolean Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
by keybindings.

A quick fix should be marked preferred if it properly addresses the underlying error.
A refactoring should be marked preferred if it is the most reasonable choice of actions to take.

@since 3.15.0 +---@field public disabled? cmp_dictionary.kit.LSP.CodeAction.disabled Marks that the code action cannot currently be applied.

Clients should follow the following guidelines regarding disabled code actions:

- Disabled code actions are not shown in automatic [lightbulbs](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)
code action menus.

- Disabled actions are shown as faded out in the code action menu when the user requests a more specific type
of code action, such as refactorings.

- If the user has a [keybinding](https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions)
that auto applies a code action and only disabled code actions are returned, the client should show the user an
error message with `reason` in the editor.

@since 3.16.0 +---@field public edit? cmp_dictionary.kit.LSP.WorkspaceEdit The workspace edit this code action performs. +---@field public command? cmp_dictionary.kit.LSP.Command A command this code action executes. If a code action
provides an edit and a command, first the edit is
executed and then the command. +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved on a code action between
a `textDocument/codeAction` and a `codeAction/resolve` request.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.CodeAction.disabled +---@field public reason string Human readable description of why the code action is currently disabled.

This is displayed in the code actions UI. + +---@class cmp_dictionary.kit.LSP.CodeActionRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.CodeActionOptions + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public query string A query string to filter symbols by. Clients may send an empty
string here to request all symbols. + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbol : cmp_dictionary.kit.LSP.BaseSymbolInformation +---@field public location (cmp_dictionary.kit.LSP.Location | { uri: string }) The location of the symbol. Whether a server is allowed to
return a location without a range depends on the client
capability `workspace.symbol.resolveSupport`.

See SymbolInformation#location for more details. +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved on a workspace symbol between a
workspace symbol request and a workspace symbol resolve request. + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolRegistrationOptions : cmp_dictionary.kit.LSP.WorkspaceSymbolOptions + +---@class cmp_dictionary.kit.LSP.CodeLensParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document to request code lens for. + +---@class cmp_dictionary.kit.LSP.CodeLens +---@field public range cmp_dictionary.kit.LSP.Range The range in which this code lens is valid. Should only span a single line. +---@field public command? cmp_dictionary.kit.LSP.Command The command this code lens represents. +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved on a code lens item between
a [CodeLensRequest](#CodeLensRequest) and a [CodeLensResolveRequest]
(#CodeLensResolveRequest) + +---@class cmp_dictionary.kit.LSP.CodeLensRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.CodeLensOptions + +---@class cmp_dictionary.kit.LSP.DocumentLinkParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams, cmp_dictionary.kit.LSP.PartialResultParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document to provide document links for. + +---@class cmp_dictionary.kit.LSP.DocumentLink +---@field public range cmp_dictionary.kit.LSP.Range The range this link applies to. +---@field public target? string The uri this link points to. If missing a resolve request is sent later. +---@field public tooltip? string The tooltip text when you hover over this link.

If a tooltip is provided, is will be displayed in a string that includes instructions on how to
trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
user settings, and localization.

@since 3.15.0 +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved on a document link between a
DocumentLinkRequest and a DocumentLinkResolveRequest. + +---@class cmp_dictionary.kit.LSP.DocumentLinkRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentLinkOptions + +---@class cmp_dictionary.kit.LSP.DocumentFormattingParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document to format. +---@field public options cmp_dictionary.kit.LSP.FormattingOptions The format options. + +---@class cmp_dictionary.kit.LSP.DocumentFormattingRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentFormattingOptions + +---@class cmp_dictionary.kit.LSP.DocumentRangeFormattingParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document to format. +---@field public range cmp_dictionary.kit.LSP.Range The range to format +---@field public options cmp_dictionary.kit.LSP.FormattingOptions The format options + +---@class cmp_dictionary.kit.LSP.DocumentRangeFormattingRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentRangeFormattingOptions + +---@class cmp_dictionary.kit.LSP.DocumentOnTypeFormattingParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document to format. +---@field public position cmp_dictionary.kit.LSP.Position The position around which the on type formatting should happen.
This is not necessarily the exact position where the character denoted
by the property `ch` got typed. +---@field public ch string The character that has been typed that triggered the formatting
on type request. That is not necessarily the last character that
got inserted into the document since the client could auto insert
characters as well (e.g. like automatic brace completion). +---@field public options cmp_dictionary.kit.LSP.FormattingOptions The formatting options. + +---@class cmp_dictionary.kit.LSP.DocumentOnTypeFormattingRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.DocumentOnTypeFormattingOptions + +---@class cmp_dictionary.kit.LSP.RenameParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The document to rename. +---@field public position cmp_dictionary.kit.LSP.Position The position at which this request was sent. +---@field public newName string The new name of the symbol. If the given name is not valid the
request must return a [ResponseError](#ResponseError) with an
appropriate message set. + +---@class cmp_dictionary.kit.LSP.RenameRegistrationOptions : cmp_dictionary.kit.LSP.TextDocumentRegistrationOptions, cmp_dictionary.kit.LSP.RenameOptions + +---@class cmp_dictionary.kit.LSP.PrepareRenameParams : cmp_dictionary.kit.LSP.TextDocumentPositionParams, cmp_dictionary.kit.LSP.WorkDoneProgressParams + +---@class cmp_dictionary.kit.LSP.ExecuteCommandParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public command string The identifier of the actual command handler. +---@field public arguments? cmp_dictionary.kit.LSP.LSPAny[] Arguments that the command should be invoked with. + +---@class cmp_dictionary.kit.LSP.ExecuteCommandRegistrationOptions : cmp_dictionary.kit.LSP.ExecuteCommandOptions + +---@class cmp_dictionary.kit.LSP.ApplyWorkspaceEditParams +---@field public label? string An optional label of the workspace edit. This label is
presented in the user interface for example on an undo
stack to undo the workspace edit. +---@field public edit cmp_dictionary.kit.LSP.WorkspaceEdit The edits to apply. + +---@class cmp_dictionary.kit.LSP.ApplyWorkspaceEditResult +---@field public applied boolean Indicates whether the edit was applied or not. +---@field public failureReason? string An optional textual description for why the edit was not applied.
This may be used by the server for diagnostic logging or to provide
a suitable error for a request that triggered the edit. +---@field public failedChange? integer Depending on the client's failure handling strategy `failedChange` might
contain the index of the change that failed. This property is only available
if the client signals a `failureHandlingStrategy` in its client capabilities. + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressBegin +---@field public kind "begin" +---@field public title string Mandatory title of the progress operation. Used to briefly inform about
the kind of operation being performed.

Examples: "Indexing" or "Linking dependencies". +---@field public cancellable? boolean Controls if a cancel button should show to allow the user to cancel the
long running operation. Clients that don't support cancellation are allowed
to ignore the setting. +---@field public message? string Optional, more detailed associated progress message. Contains
complementary information to the `title`.

Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
If unset, the previous progress message (if any) is still valid. +---@field public percentage? integer Optional progress percentage to display (value 100 is considered 100%).
If not provided infinite progress is assumed and clients are allowed
to ignore the `percentage` value in subsequent in report notifications.

The value should be steadily rising. Clients are free to ignore values
that are not following this rule. The value range is [0, 100]. + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressReport +---@field public kind "report" +---@field public cancellable? boolean Controls enablement state of a cancel button.

Clients that don't support cancellation or don't support controlling the button's
enablement state are allowed to ignore the property. +---@field public message? string Optional, more detailed associated progress message. Contains
complementary information to the `title`.

Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
If unset, the previous progress message (if any) is still valid. +---@field public percentage? integer Optional progress percentage to display (value 100 is considered 100%).
If not provided infinite progress is assumed and clients are allowed
to ignore the `percentage` value in subsequent in report notifications.

The value should be steadily rising. Clients are free to ignore values
that are not following this rule. The value range is [0, 100] + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressEnd +---@field public kind "end" +---@field public message? string Optional, a final message indicating to for example indicate the outcome
of the operation. + +---@class cmp_dictionary.kit.LSP.SetTraceParams +---@field public value cmp_dictionary.kit.LSP.TraceValues + +---@class cmp_dictionary.kit.LSP.LogTraceParams +---@field public message string +---@field public verbose? string + +---@class cmp_dictionary.kit.LSP.CancelParams +---@field public id (integer | string) The request id to cancel. + +---@class cmp_dictionary.kit.LSP.ProgressParams +---@field public token cmp_dictionary.kit.LSP.ProgressToken The progress token provided by the client or server. +---@field public value cmp_dictionary.kit.LSP.LSPAny The progress data. + +---@class cmp_dictionary.kit.LSP.TextDocumentPositionParams +---@field public textDocument cmp_dictionary.kit.LSP.TextDocumentIdentifier The text document. +---@field public position cmp_dictionary.kit.LSP.Position The position inside the text document. + +---@class cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public workDoneToken? cmp_dictionary.kit.LSP.ProgressToken An optional token that a server can use to report work done progress. + +---@class cmp_dictionary.kit.LSP.LocationLink +---@field public originSelectionRange? cmp_dictionary.kit.LSP.Range Span of the origin of this link.

Used as the underlined span for mouse interaction. Defaults to the word range at
the definition position. +---@field public targetUri string The target resource identifier of this link. +---@field public targetRange cmp_dictionary.kit.LSP.Range The full target range of this link. If the target for example is a symbol then target range is the
range enclosing this symbol not including leading/trailing whitespace but everything else
like comments. This information is typically used to highlight the range in the editor. +---@field public targetSelectionRange cmp_dictionary.kit.LSP.Range The range that should be selected and revealed when this link is being followed, e.g the name of a function.
Must be contained by the `targetRange`. See also `DocumentSymbol#range` + +---@class cmp_dictionary.kit.LSP.Range +---@field public start cmp_dictionary.kit.LSP.Position The range's start position. +---@field public end cmp_dictionary.kit.LSP.Position The range's end position. + +---@class cmp_dictionary.kit.LSP.ImplementationOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.StaticRegistrationOptions +---@field public id? string The id used to register the request. The id can be used to deregister
the request again. See also Registration#id. + +---@class cmp_dictionary.kit.LSP.TypeDefinitionOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.WorkspaceFoldersChangeEvent +---@field public added cmp_dictionary.kit.LSP.WorkspaceFolder[] The array of added workspace folders +---@field public removed cmp_dictionary.kit.LSP.WorkspaceFolder[] The array of the removed workspace folders + +---@class cmp_dictionary.kit.LSP.ConfigurationItem +---@field public scopeUri? string The scope to get the configuration section for. +---@field public section? string The configuration section asked for. + +---@class cmp_dictionary.kit.LSP.TextDocumentIdentifier +---@field public uri string The text document's uri. + +---@class cmp_dictionary.kit.LSP.Color +---@field public red integer The red component of this color in the range [0-1]. +---@field public green integer The green component of this color in the range [0-1]. +---@field public blue integer The blue component of this color in the range [0-1]. +---@field public alpha integer The alpha component of this color in the range [0-1]. + +---@class cmp_dictionary.kit.LSP.DocumentColorOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.FoldingRangeOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.DeclarationOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.Position +---@field public line integer Line position in a document (zero-based).

If a line number is greater than the number of lines in a document, it defaults back to the number of lines in the document.
If a line number is negative, it defaults to 0. +---@field public character integer Character offset on a line in a document (zero-based).

The meaning of this offset is determined by the negotiated
`PositionEncodingKind`.

If the character value is greater than the line length it defaults back to the
line length. + +---@class cmp_dictionary.kit.LSP.SelectionRangeOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.CallHierarchyOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.SemanticTokensOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public legend cmp_dictionary.kit.LSP.SemanticTokensLegend The legend used by the server +---@field public range? (boolean | { }) Server supports providing semantic tokens for a specific range
of a document. +---@field public full? (boolean | { delta?: boolean }) Server supports providing semantic tokens for a full document. + +---@class cmp_dictionary.kit.LSP.SemanticTokensEdit +---@field public start integer The start offset of the edit. +---@field public deleteCount integer The count of elements to remove. +---@field public data? integer[] The elements to insert. + +---@class cmp_dictionary.kit.LSP.LinkedEditingRangeOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.FileCreate +---@field public uri string A file:// URI for the location of the file/folder being created. + +---@class cmp_dictionary.kit.LSP.TextDocumentEdit +---@field public textDocument cmp_dictionary.kit.LSP.OptionalVersionedTextDocumentIdentifier The text document to change. +---@field public edits (cmp_dictionary.kit.LSP.TextEdit | cmp_dictionary.kit.LSP.AnnotatedTextEdit)[] The edits to be applied.

@since 3.16.0 - support for AnnotatedTextEdit. This is guarded using a
client capability. + +---@class cmp_dictionary.kit.LSP.CreateFile : cmp_dictionary.kit.LSP.ResourceOperation +---@field public kind "create" A create +---@field public uri string The resource to create. +---@field public options? cmp_dictionary.kit.LSP.CreateFileOptions Additional options + +---@class cmp_dictionary.kit.LSP.RenameFile : cmp_dictionary.kit.LSP.ResourceOperation +---@field public kind "rename" A rename +---@field public oldUri string The old (existing) location. +---@field public newUri string The new location. +---@field public options? cmp_dictionary.kit.LSP.RenameFileOptions Rename options. + +---@class cmp_dictionary.kit.LSP.DeleteFile : cmp_dictionary.kit.LSP.ResourceOperation +---@field public kind "delete" A delete +---@field public uri string The file to delete. +---@field public options? cmp_dictionary.kit.LSP.DeleteFileOptions Delete options. + +---@class cmp_dictionary.kit.LSP.ChangeAnnotation +---@field public label string A human-readable string describing the actual change. The string
is rendered prominent in the user interface. +---@field public needsConfirmation? boolean A flag which indicates that user confirmation is needed
before applying the change. +---@field public description? string A human-readable string which is rendered less prominent in
the user interface. + +---@class cmp_dictionary.kit.LSP.FileOperationFilter +---@field public scheme? string A Uri scheme like `file` or `untitled`. +---@field public pattern cmp_dictionary.kit.LSP.FileOperationPattern The actual file operation pattern. + +---@class cmp_dictionary.kit.LSP.FileRename +---@field public oldUri string A file:// URI for the original location of the file/folder being renamed. +---@field public newUri string A file:// URI for the new location of the file/folder being renamed. + +---@class cmp_dictionary.kit.LSP.FileDelete +---@field public uri string A file:// URI for the location of the file/folder being deleted. + +---@class cmp_dictionary.kit.LSP.MonikerOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.TypeHierarchyOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.InlineValueContext +---@field public frameId integer The stack frame (as a DAP Id) where the execution has stopped. +---@field public stoppedLocation cmp_dictionary.kit.LSP.Range The document range where execution has stopped.
Typically the end position of the range denotes the line where the inline values are shown. + +---@class cmp_dictionary.kit.LSP.InlineValueText +---@field public range cmp_dictionary.kit.LSP.Range The document range for which the inline value applies. +---@field public text string The text of the inline value. + +---@class cmp_dictionary.kit.LSP.InlineValueVariableLookup +---@field public range cmp_dictionary.kit.LSP.Range The document range for which the inline value applies.
The range is used to extract the variable name from the underlying document. +---@field public variableName? string If specified the name of the variable to look up. +---@field public caseSensitiveLookup boolean How to perform the lookup. + +---@class cmp_dictionary.kit.LSP.InlineValueEvaluatableExpression +---@field public range cmp_dictionary.kit.LSP.Range The document range for which the inline value applies.
The range is used to extract the evaluatable expression from the underlying document. +---@field public expression? string If specified the expression overrides the extracted expression. + +---@class cmp_dictionary.kit.LSP.InlineValueOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.InlayHintLabelPart +---@field public value string The value of this label part. +---@field public tooltip? (string | cmp_dictionary.kit.LSP.MarkupContent) The tooltip text when you hover over this label part. Depending on
the client capability `inlayHint.resolveSupport` clients might resolve
this property late using the resolve request. +---@field public location? cmp_dictionary.kit.LSP.Location An optional source code location that represents this
label part.

The editor will use this location for the hover and for code navigation
features: This part will become a clickable link that resolves to the
definition of the symbol at the given location (not necessarily the
location itself), it shows the hover that shows at the given location,
and it shows a context menu with further code navigation commands.

Depending on the client capability `inlayHint.resolveSupport` clients
might resolve this property late using the resolve request. +---@field public command? cmp_dictionary.kit.LSP.Command An optional command for this label part.

Depending on the client capability `inlayHint.resolveSupport` clients
might resolve this property late using the resolve request. + +---@class cmp_dictionary.kit.LSP.MarkupContent +---@field public kind cmp_dictionary.kit.LSP.MarkupKind The type of the Markup +---@field public value string The content itself + +---@class cmp_dictionary.kit.LSP.InlayHintOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public resolveProvider? boolean The server provides support to resolve additional
information for an inlay hint item. + +---@class cmp_dictionary.kit.LSP.RelatedFullDocumentDiagnosticReport : cmp_dictionary.kit.LSP.FullDocumentDiagnosticReport +---@field public relatedDocuments? table Diagnostics of related documents. This information is useful
in programming languages where code in a file A can generate
diagnostics in a file B which A depends on. An example of
such a language is C/C++ where marco definitions in a file
a.cpp and result in errors in a header file b.hpp.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.RelatedUnchangedDocumentDiagnosticReport : cmp_dictionary.kit.LSP.UnchangedDocumentDiagnosticReport +---@field public relatedDocuments? table Diagnostics of related documents. This information is useful
in programming languages where code in a file A can generate
diagnostics in a file B which A depends on. An example of
such a language is C/C++ where marco definitions in a file
a.cpp and result in errors in a header file b.hpp.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.FullDocumentDiagnosticReport +---@field public kind "full" A full document diagnostic report. +---@field public resultId? string An optional result id. If provided it will
be sent on the next diagnostic request for the
same document. +---@field public items cmp_dictionary.kit.LSP.Diagnostic[] The actual items. + +---@class cmp_dictionary.kit.LSP.UnchangedDocumentDiagnosticReport +---@field public kind "unchanged" A document diagnostic report indicating
no changes to the last result. A server can
only return `unchanged` if result ids are
provided. +---@field public resultId string A result id which will be sent on the next
diagnostic request for the same document. + +---@class cmp_dictionary.kit.LSP.DiagnosticOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public identifier? string An optional identifier under which the diagnostics are
managed by the client. +---@field public interFileDependencies boolean Whether the language has inter file dependencies meaning that
editing code in one file can result in a different diagnostic
set in another file. Inter file dependencies are common for
most programming languages and typically uncommon for linters. +---@field public workspaceDiagnostics boolean The server provides support for workspace diagnostics as well. + +---@class cmp_dictionary.kit.LSP.PreviousResultId +---@field public uri string The URI for which the client knowns a
result id. +---@field public value string The value of the previous result id. + +---@class cmp_dictionary.kit.LSP.NotebookDocument +---@field public uri string The notebook document's uri. +---@field public notebookType string The type of the notebook. +---@field public version integer The version number of this document (it will increase after each
change, including undo/redo). +---@field public metadata? cmp_dictionary.kit.LSP.LSPObject Additional metadata stored with the notebook
document.

Note: should always be an object literal (e.g. LSPObject) +---@field public cells cmp_dictionary.kit.LSP.NotebookCell[] The cells of a notebook. + +---@class cmp_dictionary.kit.LSP.TextDocumentItem +---@field public uri string The text document's uri. +---@field public languageId string The text document's language identifier. +---@field public version integer The version number of this document (it will increase after each
change, including undo/redo). +---@field public text string The content of the opened text document. + +---@class cmp_dictionary.kit.LSP.VersionedNotebookDocumentIdentifier +---@field public version integer The version number of this notebook document. +---@field public uri string The notebook document's uri. + +---@class cmp_dictionary.kit.LSP.NotebookDocumentChangeEvent +---@field public metadata? cmp_dictionary.kit.LSP.LSPObject The changed meta data if any.

Note: should always be an object literal (e.g. LSPObject) +---@field public cells? cmp_dictionary.kit.LSP.NotebookDocumentChangeEvent.cells Changes to cells + +---@class cmp_dictionary.kit.LSP.NotebookDocumentChangeEvent.cells +---@field public structure? cmp_dictionary.kit.LSP.NotebookDocumentChangeEvent.cells.structure Changes to the cell structure to add or
remove cells. +---@field public data? cmp_dictionary.kit.LSP.NotebookCell[] Changes to notebook cells properties like its
kind, execution summary or metadata. +---@field public textContent? { document: cmp_dictionary.kit.LSP.VersionedTextDocumentIdentifier, changes: cmp_dictionary.kit.LSP.TextDocumentContentChangeEvent[] }[] Changes to the text content of notebook cells. + +---@class cmp_dictionary.kit.LSP.NotebookDocumentChangeEvent.cells.structure +---@field public array cmp_dictionary.kit.LSP.NotebookCellArrayChange The change to the cell array. +---@field public didOpen? cmp_dictionary.kit.LSP.TextDocumentItem[] Additional opened cell text documents. +---@field public didClose? cmp_dictionary.kit.LSP.TextDocumentIdentifier[] Additional closed cell text documents. + +---@class cmp_dictionary.kit.LSP.NotebookDocumentIdentifier +---@field public uri string The notebook document's uri. + +---@class cmp_dictionary.kit.LSP.Registration +---@field public id string The id used to register the request. The id can be used to deregister
the request again. +---@field public method string The method / capability to register for. +---@field public registerOptions? cmp_dictionary.kit.LSP.LSPAny Options necessary for the registration. + +---@class cmp_dictionary.kit.LSP.Unregistration +---@field public id string The id used to unregister the request or notification. Usually an id
provided during the register request. +---@field public method string The method to unregister for. + +---@class cmp_dictionary.kit.LSP._InitializeParams : cmp_dictionary.kit.LSP.WorkDoneProgressParams +---@field public processId (integer | nil) The process Id of the parent process that started
the server.

Is `null` if the process has not been started by another process.
If the parent process is not alive then the server should exit. +---@field public clientInfo? cmp_dictionary.kit.LSP._InitializeParams.clientInfo Information about the client

@since 3.15.0 +---@field public locale? string The locale the client is currently showing the user interface
in. This must not necessarily be the locale of the operating
system.

Uses IETF language tags as the value's syntax
(See https://en.wikipedia.org/wiki/IETF_language_tag)

@since 3.16.0 +---@field public rootPath? (string | nil) The rootPath of the workspace. Is null
if no folder is open.

@deprecated in favour of rootUri. +---@field public rootUri (string | nil) The rootUri of the workspace. Is null if no
folder is open. If both `rootPath` and `rootUri` are set
`rootUri` wins.

@deprecated in favour of workspaceFolders. +---@field public capabilities cmp_dictionary.kit.LSP.ClientCapabilities The capabilities provided by the client (editor or tool) +---@field public initializationOptions? cmp_dictionary.kit.LSP.LSPAny User provided initialization options. +---@field public trace? ("off" | "messages" | "compact" | "verbose") The initial trace setting. If omitted trace is disabled ('off'). + +---@class cmp_dictionary.kit.LSP._InitializeParams.clientInfo +---@field public name string The name of the client as defined by the client. +---@field public version? string The client's version as defined by the client. + +---@class cmp_dictionary.kit.LSP.WorkspaceFoldersInitializeParams +---@field public workspaceFolders? (cmp_dictionary.kit.LSP.WorkspaceFolder[] | nil) The workspace folders configured in the client when the server starts.

This property is only available if the client supports workspace folders.
It can be `null` if the client supports workspace folders but none are
configured.

@since 3.6.0 + +---@class cmp_dictionary.kit.LSP.ServerCapabilities +---@field public positionEncoding? cmp_dictionary.kit.LSP.PositionEncodingKind The position encoding the server picked from the encodings offered
by the client via the client capability `general.positionEncodings`.

If the client didn't provide any position encodings the only valid
value that a server can return is 'utf-16'.

If omitted it defaults to 'utf-16'.

@since 3.17.0 +---@field public textDocumentSync? (cmp_dictionary.kit.LSP.TextDocumentSyncOptions | cmp_dictionary.kit.LSP.TextDocumentSyncKind) Defines how text documents are synced. Is either a detailed structure
defining each notification or for backwards compatibility the
TextDocumentSyncKind number. +---@field public notebookDocumentSync? (cmp_dictionary.kit.LSP.NotebookDocumentSyncOptions | cmp_dictionary.kit.LSP.NotebookDocumentSyncRegistrationOptions) Defines how notebook documents are synced.

@since 3.17.0 +---@field public completionProvider? cmp_dictionary.kit.LSP.CompletionOptions The server provides completion support. +---@field public hoverProvider? (boolean | cmp_dictionary.kit.LSP.HoverOptions) The server provides hover support. +---@field public signatureHelpProvider? cmp_dictionary.kit.LSP.SignatureHelpOptions The server provides signature help support. +---@field public declarationProvider? (boolean | cmp_dictionary.kit.LSP.DeclarationOptions | cmp_dictionary.kit.LSP.DeclarationRegistrationOptions) The server provides Goto Declaration support. +---@field public definitionProvider? (boolean | cmp_dictionary.kit.LSP.DefinitionOptions) The server provides goto definition support. +---@field public typeDefinitionProvider? (boolean | cmp_dictionary.kit.LSP.TypeDefinitionOptions | cmp_dictionary.kit.LSP.TypeDefinitionRegistrationOptions) The server provides Goto Type Definition support. +---@field public implementationProvider? (boolean | cmp_dictionary.kit.LSP.ImplementationOptions | cmp_dictionary.kit.LSP.ImplementationRegistrationOptions) The server provides Goto Implementation support. +---@field public referencesProvider? (boolean | cmp_dictionary.kit.LSP.ReferenceOptions) The server provides find references support. +---@field public documentHighlightProvider? (boolean | cmp_dictionary.kit.LSP.DocumentHighlightOptions) The server provides document highlight support. +---@field public documentSymbolProvider? (boolean | cmp_dictionary.kit.LSP.DocumentSymbolOptions) The server provides document symbol support. +---@field public codeActionProvider? (boolean | cmp_dictionary.kit.LSP.CodeActionOptions) The server provides code actions. CodeActionOptions may only be
specified if the client states that it supports
`codeActionLiteralSupport` in its initial `initialize` request. +---@field public codeLensProvider? cmp_dictionary.kit.LSP.CodeLensOptions The server provides code lens. +---@field public documentLinkProvider? cmp_dictionary.kit.LSP.DocumentLinkOptions The server provides document link support. +---@field public colorProvider? (boolean | cmp_dictionary.kit.LSP.DocumentColorOptions | cmp_dictionary.kit.LSP.DocumentColorRegistrationOptions) The server provides color provider support. +---@field public workspaceSymbolProvider? (boolean | cmp_dictionary.kit.LSP.WorkspaceSymbolOptions) The server provides workspace symbol support. +---@field public documentFormattingProvider? (boolean | cmp_dictionary.kit.LSP.DocumentFormattingOptions) The server provides document formatting. +---@field public documentRangeFormattingProvider? (boolean | cmp_dictionary.kit.LSP.DocumentRangeFormattingOptions) The server provides document range formatting. +---@field public documentOnTypeFormattingProvider? cmp_dictionary.kit.LSP.DocumentOnTypeFormattingOptions The server provides document formatting on typing. +---@field public renameProvider? (boolean | cmp_dictionary.kit.LSP.RenameOptions) The server provides rename support. RenameOptions may only be
specified if the client states that it supports
`prepareSupport` in its initial `initialize` request. +---@field public foldingRangeProvider? (boolean | cmp_dictionary.kit.LSP.FoldingRangeOptions | cmp_dictionary.kit.LSP.FoldingRangeRegistrationOptions) The server provides folding provider support. +---@field public selectionRangeProvider? (boolean | cmp_dictionary.kit.LSP.SelectionRangeOptions | cmp_dictionary.kit.LSP.SelectionRangeRegistrationOptions) The server provides selection range support. +---@field public executeCommandProvider? cmp_dictionary.kit.LSP.ExecuteCommandOptions The server provides execute command support. +---@field public callHierarchyProvider? (boolean | cmp_dictionary.kit.LSP.CallHierarchyOptions | cmp_dictionary.kit.LSP.CallHierarchyRegistrationOptions) The server provides call hierarchy support.

@since 3.16.0 +---@field public linkedEditingRangeProvider? (boolean | cmp_dictionary.kit.LSP.LinkedEditingRangeOptions | cmp_dictionary.kit.LSP.LinkedEditingRangeRegistrationOptions) The server provides linked editing range support.

@since 3.16.0 +---@field public semanticTokensProvider? (cmp_dictionary.kit.LSP.SemanticTokensOptions | cmp_dictionary.kit.LSP.SemanticTokensRegistrationOptions) The server provides semantic tokens support.

@since 3.16.0 +---@field public monikerProvider? (boolean | cmp_dictionary.kit.LSP.MonikerOptions | cmp_dictionary.kit.LSP.MonikerRegistrationOptions) The server provides moniker support.

@since 3.16.0 +---@field public typeHierarchyProvider? (boolean | cmp_dictionary.kit.LSP.TypeHierarchyOptions | cmp_dictionary.kit.LSP.TypeHierarchyRegistrationOptions) The server provides type hierarchy support.

@since 3.17.0 +---@field public inlineValueProvider? (boolean | cmp_dictionary.kit.LSP.InlineValueOptions | cmp_dictionary.kit.LSP.InlineValueRegistrationOptions) The server provides inline values.

@since 3.17.0 +---@field public inlayHintProvider? (boolean | cmp_dictionary.kit.LSP.InlayHintOptions | cmp_dictionary.kit.LSP.InlayHintRegistrationOptions) The server provides inlay hints.

@since 3.17.0 +---@field public diagnosticProvider? (cmp_dictionary.kit.LSP.DiagnosticOptions | cmp_dictionary.kit.LSP.DiagnosticRegistrationOptions) The server has support for pull model diagnostics.

@since 3.17.0 +---@field public workspace? cmp_dictionary.kit.LSP.ServerCapabilities.workspace Workspace specific server capabilities. +---@field public experimental? cmp_dictionary.kit.LSP.LSPAny Experimental server capabilities. + +---@class cmp_dictionary.kit.LSP.ServerCapabilities.workspace +---@field public workspaceFolders? cmp_dictionary.kit.LSP.WorkspaceFoldersServerCapabilities The server supports workspace folder.

@since 3.6.0 +---@field public fileOperations? cmp_dictionary.kit.LSP.FileOperationOptions The server is interested in notifications/requests for operations on files.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.VersionedTextDocumentIdentifier : cmp_dictionary.kit.LSP.TextDocumentIdentifier +---@field public version integer The version number of this document. + +---@class cmp_dictionary.kit.LSP.SaveOptions +---@field public includeText? boolean The client is supposed to include the content on save. + +---@class cmp_dictionary.kit.LSP.FileEvent +---@field public uri string The file's uri. +---@field public type cmp_dictionary.kit.LSP.FileChangeType The change type. + +---@class cmp_dictionary.kit.LSP.FileSystemWatcher +---@field public globPattern cmp_dictionary.kit.LSP.GlobPattern The glob pattern to watch. See {@link GlobPattern glob pattern} for more detail.

@since 3.17.0 support for relative patterns. +---@field public kind? cmp_dictionary.kit.LSP.WatchKind The kind of events of interest. If omitted it defaults
to WatchKind.Create | WatchKind.Change | WatchKind.Delete
which is 7. + +---@class cmp_dictionary.kit.LSP.Diagnostic +---@field public range cmp_dictionary.kit.LSP.Range The range at which the message applies +---@field public severity? cmp_dictionary.kit.LSP.DiagnosticSeverity The diagnostic's severity. Can be omitted. If omitted it is up to the
client to interpret diagnostics as error, warning, info or hint. +---@field public code? (integer | string) The diagnostic's code, which usually appear in the user interface. +---@field public codeDescription? cmp_dictionary.kit.LSP.CodeDescription An optional property to describe the error code.
Requires the code field (above) to be present/not null.

@since 3.16.0 +---@field public source? string A human-readable string describing the source of this
diagnostic, e.g. 'typescript' or 'super lint'. It usually
appears in the user interface. +---@field public message string The diagnostic's message. It usually appears in the user interface +---@field public tags? cmp_dictionary.kit.LSP.DiagnosticTag[] Additional metadata about the diagnostic.

@since 3.15.0 +---@field public relatedInformation? cmp_dictionary.kit.LSP.DiagnosticRelatedInformation[] An array of related diagnostic information, e.g. when symbol-names within
a scope collide all definitions can be marked via this property. +---@field public data? cmp_dictionary.kit.LSP.LSPAny A data entry field that is preserved between a `textDocument/publishDiagnostics`
notification and `textDocument/codeAction` request.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.CompletionContext +---@field public triggerKind cmp_dictionary.kit.LSP.CompletionTriggerKind How the completion was triggered. +---@field public triggerCharacter? string The trigger character (a single character) that has trigger code complete.
Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` + +---@class cmp_dictionary.kit.LSP.CompletionItemLabelDetails +---@field public detail? string An optional string which is rendered less prominently directly after {@link CompletionItem.label label},
without any spacing. Should be used for function signatures and type annotations. +---@field public description? string An optional string which is rendered less prominently after {@link CompletionItem.detail}. Should be used
for fully qualified names and file paths. + +---@class cmp_dictionary.kit.LSP.InsertReplaceEdit +---@field public newText string The string to be inserted. +---@field public insert cmp_dictionary.kit.LSP.Range The range if the insert is requested +---@field public replace cmp_dictionary.kit.LSP.Range The range if the replace is requested. + +---@class cmp_dictionary.kit.LSP.CompletionOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public triggerCharacters? string[] Most tools trigger completion request automatically without explicitly requesting
it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
starts to type an identifier. For example if the user types `c` in a JavaScript file
code complete will automatically pop up present `console` besides others as a
completion item. Characters that make up identifiers don't need to be listed here.

If code complete should automatically be trigger on characters not being valid inside
an identifier (for example `.` in JavaScript) list them in `triggerCharacters`. +---@field public allCommitCharacters? string[] The list of all possible characters that commit a completion. This field can be used
if clients don't support individual commit characters per completion item. See
`ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`

If a server provides both `allCommitCharacters` and commit characters on an individual
completion item the ones on the completion item win.

@since 3.2.0 +---@field public resolveProvider? boolean The server provides support to resolve additional
information for a completion item. +---@field public completionItem? cmp_dictionary.kit.LSP.CompletionOptions.completionItem The server supports the following `CompletionItem` specific
capabilities.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.CompletionOptions.completionItem +---@field public labelDetailsSupport? boolean The server has support for completion item label
details (see also `CompletionItemLabelDetails`) when
receiving a completion item in a resolve call.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.HoverOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.SignatureHelpContext +---@field public triggerKind cmp_dictionary.kit.LSP.SignatureHelpTriggerKind Action that caused signature help to be triggered. +---@field public triggerCharacter? string Character that caused signature help to be triggered.

This is undefined when `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter` +---@field public isRetrigger boolean `true` if signature help was already showing when it was triggered.

Retriggers occurs when the signature help is already active and can be caused by actions such as
typing a trigger character, a cursor move, or document content changes. +---@field public activeSignatureHelp? cmp_dictionary.kit.LSP.SignatureHelp The currently active `SignatureHelp`.

The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field updated based on
the user navigating through available signatures. + +---@class cmp_dictionary.kit.LSP.SignatureInformation +---@field public label string The label of this signature. Will be shown in
the UI. +---@field public documentation? (string | cmp_dictionary.kit.LSP.MarkupContent) The human-readable doc-comment of this signature. Will be shown
in the UI but can be omitted. +---@field public parameters? cmp_dictionary.kit.LSP.ParameterInformation[] The parameters of this signature. +---@field public activeParameter? integer The index of the active parameter.

If provided, this is used in place of `SignatureHelp.activeParameter`.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.SignatureHelpOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public triggerCharacters? string[] List of characters that trigger signature help automatically. +---@field public retriggerCharacters? string[] List of characters that re-trigger signature help.

These trigger characters are only active when signature help is already showing. All trigger characters
are also counted as re-trigger characters.

@since 3.15.0 + +---@class cmp_dictionary.kit.LSP.DefinitionOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.ReferenceContext +---@field public includeDeclaration boolean Include the declaration of the current symbol. + +---@class cmp_dictionary.kit.LSP.ReferenceOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.DocumentHighlightOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.BaseSymbolInformation +---@field public name string The name of this symbol. +---@field public kind cmp_dictionary.kit.LSP.SymbolKind The kind of this symbol. +---@field public tags? cmp_dictionary.kit.LSP.SymbolTag[] Tags for this symbol.

@since 3.16.0 +---@field public containerName? string The name of the symbol containing this symbol. This information is for
user interface purposes (e.g. to render a qualifier in the user interface
if necessary). It can't be used to re-infer a hierarchy for the document
symbols. + +---@class cmp_dictionary.kit.LSP.DocumentSymbolOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public label? string A human-readable string that is shown when multiple outlines trees
are shown for the same document.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.CodeActionContext +---@field public diagnostics cmp_dictionary.kit.LSP.Diagnostic[] An array of diagnostics known on the client side overlapping the range provided to the
`textDocument/codeAction` request. They are provided so that the server knows which
errors are currently presented to the user for the given range. There is no guarantee
that these accurately reflect the error state of the resource. The primary parameter
to compute code actions is the provided range. +---@field public only? cmp_dictionary.kit.LSP.CodeActionKind[] Requested kind of actions to return.

Actions not of this kind are filtered out by the client before being shown. So servers
can omit computing them. +---@field public triggerKind? cmp_dictionary.kit.LSP.CodeActionTriggerKind The reason why code actions were requested.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.CodeActionOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public codeActionKinds? cmp_dictionary.kit.LSP.CodeActionKind[] CodeActionKinds that this server may return.

The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server
may list out every specific kind they provide. +---@field public resolveProvider? boolean The server provides support to resolve additional
information for a code action.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public resolveProvider? boolean The server provides support to resolve additional
information for a workspace symbol.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.CodeLensOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public resolveProvider? boolean Code lens has a resolve provider as well. + +---@class cmp_dictionary.kit.LSP.DocumentLinkOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public resolveProvider? boolean Document links have a resolve provider as well. + +---@class cmp_dictionary.kit.LSP.FormattingOptions +---@field public tabSize integer Size of a tab in spaces. +---@field public insertSpaces boolean Prefer spaces over tabs. +---@field public trimTrailingWhitespace? boolean Trim trailing whitespace on a line.

@since 3.15.0 +---@field public insertFinalNewline? boolean Insert a newline character at the end of the file if one does not exist.

@since 3.15.0 +---@field public trimFinalNewlines? boolean Trim all newlines after the final newline at the end of the file.

@since 3.15.0 + +---@class cmp_dictionary.kit.LSP.DocumentFormattingOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.DocumentRangeFormattingOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions + +---@class cmp_dictionary.kit.LSP.DocumentOnTypeFormattingOptions +---@field public firstTriggerCharacter string A character on which formatting should be triggered, like `{`. +---@field public moreTriggerCharacter? string[] More trigger characters. + +---@class cmp_dictionary.kit.LSP.RenameOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public prepareProvider? boolean Renames should be checked and tested before being executed.

@since version 3.12.0 + +---@class cmp_dictionary.kit.LSP.ExecuteCommandOptions : cmp_dictionary.kit.LSP.WorkDoneProgressOptions +---@field public commands string[] The commands to be executed on the server + +---@class cmp_dictionary.kit.LSP.SemanticTokensLegend +---@field public tokenTypes string[] The token types a server uses. +---@field public tokenModifiers string[] The token modifiers a server uses. + +---@class cmp_dictionary.kit.LSP.OptionalVersionedTextDocumentIdentifier : cmp_dictionary.kit.LSP.TextDocumentIdentifier +---@field public version (integer | nil) The version number of this document. If a versioned text document identifier
is sent from the server to the client and the file is not open in the editor
(the server has not received an open notification before) the server can send
`null` to indicate that the version is unknown and the content on disk is the
truth (as specified with document content ownership). + +---@class cmp_dictionary.kit.LSP.AnnotatedTextEdit : cmp_dictionary.kit.LSP.TextEdit +---@field public annotationId cmp_dictionary.kit.LSP.ChangeAnnotationIdentifier The actual identifier of the change annotation + +---@class cmp_dictionary.kit.LSP.ResourceOperation +---@field public kind string The resource operation kind. +---@field public annotationId? cmp_dictionary.kit.LSP.ChangeAnnotationIdentifier An optional annotation identifier describing the operation.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.CreateFileOptions +---@field public overwrite? boolean Overwrite existing file. Overwrite wins over `ignoreIfExists` +---@field public ignoreIfExists? boolean Ignore if exists. + +---@class cmp_dictionary.kit.LSP.RenameFileOptions +---@field public overwrite? boolean Overwrite target if existing. Overwrite wins over `ignoreIfExists` +---@field public ignoreIfExists? boolean Ignores if target exists. + +---@class cmp_dictionary.kit.LSP.DeleteFileOptions +---@field public recursive? boolean Delete the content recursively if a folder is denoted. +---@field public ignoreIfNotExists? boolean Ignore the operation if the file doesn't exist. + +---@class cmp_dictionary.kit.LSP.FileOperationPattern +---@field public glob string The glob pattern to match. Glob patterns can have the following syntax:
- `*` to match one or more characters in a path segment
- `?` to match on one character in a path segment
- `**` to match any number of path segments, including none
- `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
- `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
- `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`) +---@field public matches? cmp_dictionary.kit.LSP.FileOperationPatternKind Whether to match files or folders with this pattern.

Matches both if undefined. +---@field public options? cmp_dictionary.kit.LSP.FileOperationPatternOptions Additional options used during matching. + +---@class cmp_dictionary.kit.LSP.WorkspaceFullDocumentDiagnosticReport : cmp_dictionary.kit.LSP.FullDocumentDiagnosticReport +---@field public uri string The URI for which diagnostic information is reported. +---@field public version (integer | nil) The version number for which the diagnostics are reported.
If the document is not marked as open `null` can be provided. + +---@class cmp_dictionary.kit.LSP.WorkspaceUnchangedDocumentDiagnosticReport : cmp_dictionary.kit.LSP.UnchangedDocumentDiagnosticReport +---@field public uri string The URI for which diagnostic information is reported. +---@field public version (integer | nil) The version number for which the diagnostics are reported.
If the document is not marked as open `null` can be provided. + +---@class cmp_dictionary.kit.LSP.LSPObject + +---@class cmp_dictionary.kit.LSP.NotebookCell +---@field public kind cmp_dictionary.kit.LSP.NotebookCellKind The cell's kind +---@field public document string The URI of the cell's text document
content. +---@field public metadata? cmp_dictionary.kit.LSP.LSPObject Additional metadata stored with the cell.

Note: should always be an object literal (e.g. LSPObject) +---@field public executionSummary? cmp_dictionary.kit.LSP.ExecutionSummary Additional execution summary information
if supported by the client. + +---@class cmp_dictionary.kit.LSP.NotebookCellArrayChange +---@field public start integer The start oftest of the cell that changed. +---@field public deleteCount integer The deleted cells +---@field public cells? cmp_dictionary.kit.LSP.NotebookCell[] The new cells, if any + +---@class cmp_dictionary.kit.LSP.ClientCapabilities +---@field public workspace? cmp_dictionary.kit.LSP.WorkspaceClientCapabilities Workspace specific client capabilities. +---@field public textDocument? cmp_dictionary.kit.LSP.TextDocumentClientCapabilities Text document specific client capabilities. +---@field public notebookDocument? cmp_dictionary.kit.LSP.NotebookDocumentClientCapabilities Capabilities specific to the notebook document support.

@since 3.17.0 +---@field public window? cmp_dictionary.kit.LSP.WindowClientCapabilities Window specific client capabilities. +---@field public general? cmp_dictionary.kit.LSP.GeneralClientCapabilities General client capabilities.

@since 3.16.0 +---@field public experimental? cmp_dictionary.kit.LSP.LSPAny Experimental client capabilities. + +---@class cmp_dictionary.kit.LSP.TextDocumentSyncOptions +---@field public openClose? boolean Open and close notifications are sent to the server. If omitted open close notification should not
be sent. +---@field public change? cmp_dictionary.kit.LSP.TextDocumentSyncKind Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None. +---@field public willSave? boolean If present will save notifications are sent to the server. If omitted the notification should not be
sent. +---@field public willSaveWaitUntil? boolean If present will save wait until requests are sent to the server. If omitted the request should not be
sent. +---@field public save? (boolean | cmp_dictionary.kit.LSP.SaveOptions) If present save notifications are sent to the server. If omitted the notification should not be
sent. + +---@class cmp_dictionary.kit.LSP.NotebookDocumentSyncOptions +---@field public notebookSelector ({ notebook: (string | cmp_dictionary.kit.LSP.NotebookDocumentFilter), cells?: { language: string }[] } | { notebook?: (string | cmp_dictionary.kit.LSP.NotebookDocumentFilter), cells: { language: string }[] })[] The notebooks to be synced +---@field public save? boolean Whether save notification should be forwarded to
the server. Will only be honored if mode === `notebook`. + +---@class cmp_dictionary.kit.LSP.NotebookDocumentSyncRegistrationOptions : cmp_dictionary.kit.LSP.NotebookDocumentSyncOptions, cmp_dictionary.kit.LSP.StaticRegistrationOptions + +---@class cmp_dictionary.kit.LSP.WorkspaceFoldersServerCapabilities +---@field public supported? boolean The server has support for workspace folders +---@field public changeNotifications? (string | boolean) Whether the server wants to receive workspace folder
change notifications.

If a string is provided the string is treated as an ID
under which the notification is registered on the client
side. The ID can be used to unregister for these events
using the `client/unregisterCapability` request. + +---@class cmp_dictionary.kit.LSP.FileOperationOptions +---@field public didCreate? cmp_dictionary.kit.LSP.FileOperationRegistrationOptions The server is interested in receiving didCreateFiles notifications. +---@field public willCreate? cmp_dictionary.kit.LSP.FileOperationRegistrationOptions The server is interested in receiving willCreateFiles requests. +---@field public didRename? cmp_dictionary.kit.LSP.FileOperationRegistrationOptions The server is interested in receiving didRenameFiles notifications. +---@field public willRename? cmp_dictionary.kit.LSP.FileOperationRegistrationOptions The server is interested in receiving willRenameFiles requests. +---@field public didDelete? cmp_dictionary.kit.LSP.FileOperationRegistrationOptions The server is interested in receiving didDeleteFiles file notifications. +---@field public willDelete? cmp_dictionary.kit.LSP.FileOperationRegistrationOptions The server is interested in receiving willDeleteFiles file requests. + +---@class cmp_dictionary.kit.LSP.CodeDescription +---@field public href string An URI to open with more information about the diagnostic error. + +---@class cmp_dictionary.kit.LSP.DiagnosticRelatedInformation +---@field public location cmp_dictionary.kit.LSP.Location The location of this related diagnostic information. +---@field public message string The message of this related diagnostic information. + +---@class cmp_dictionary.kit.LSP.ParameterInformation +---@field public label (string | (integer | integer)[]) The label of this parameter information.

Either a string or an inclusive start and exclusive end offsets within its containing
signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
string representation as `Position` and `Range` does.

*Note*: a label of type string should be a substring of its containing signature label.
Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`. +---@field public documentation? (string | cmp_dictionary.kit.LSP.MarkupContent) The human-readable doc-comment of this parameter. Will be shown
in the UI but can be omitted. + +---@class cmp_dictionary.kit.LSP.NotebookCellTextDocumentFilter +---@field public notebook (string | cmp_dictionary.kit.LSP.NotebookDocumentFilter) A filter that matches against the notebook
containing the notebook cell. If a string
value is provided it matches against the
notebook type. '*' matches every notebook. +---@field public language? string A language id like `python`.

Will be matched against the language id of the
notebook cell document. '*' matches every language. + +---@class cmp_dictionary.kit.LSP.FileOperationPatternOptions +---@field public ignoreCase? boolean The pattern should be matched ignoring casing. + +---@class cmp_dictionary.kit.LSP.ExecutionSummary +---@field public executionOrder integer A strict monotonically increasing value
indicating the execution order of a cell
inside a notebook. +---@field public success? boolean Whether the execution was successful or
not if known by the client. + +---@class cmp_dictionary.kit.LSP.WorkspaceClientCapabilities +---@field public applyEdit? boolean The client supports applying batch edits
to the workspace by supporting the request
'workspace/applyEdit' +---@field public workspaceEdit? cmp_dictionary.kit.LSP.WorkspaceEditClientCapabilities Capabilities specific to `WorkspaceEdit`s. +---@field public didChangeConfiguration? cmp_dictionary.kit.LSP.DidChangeConfigurationClientCapabilities Capabilities specific to the `workspace/didChangeConfiguration` notification. +---@field public didChangeWatchedFiles? cmp_dictionary.kit.LSP.DidChangeWatchedFilesClientCapabilities Capabilities specific to the `workspace/didChangeWatchedFiles` notification. +---@field public symbol? cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities Capabilities specific to the `workspace/symbol` request. +---@field public executeCommand? cmp_dictionary.kit.LSP.ExecuteCommandClientCapabilities Capabilities specific to the `workspace/executeCommand` request. +---@field public workspaceFolders? boolean The client has support for workspace folders.

@since 3.6.0 +---@field public configuration? boolean The client supports `workspace/configuration` requests.

@since 3.6.0 +---@field public semanticTokens? cmp_dictionary.kit.LSP.SemanticTokensWorkspaceClientCapabilities Capabilities specific to the semantic token requests scoped to the
workspace.

@since 3.16.0. +---@field public codeLens? cmp_dictionary.kit.LSP.CodeLensWorkspaceClientCapabilities Capabilities specific to the code lens requests scoped to the
workspace.

@since 3.16.0. +---@field public fileOperations? cmp_dictionary.kit.LSP.FileOperationClientCapabilities The client has support for file notifications/requests for user operations on files.

Since 3.16.0 +---@field public inlineValue? cmp_dictionary.kit.LSP.InlineValueWorkspaceClientCapabilities Capabilities specific to the inline values requests scoped to the
workspace.

@since 3.17.0. +---@field public inlayHint? cmp_dictionary.kit.LSP.InlayHintWorkspaceClientCapabilities Capabilities specific to the inlay hint requests scoped to the
workspace.

@since 3.17.0. +---@field public diagnostics? cmp_dictionary.kit.LSP.DiagnosticWorkspaceClientCapabilities Capabilities specific to the diagnostic requests scoped to the
workspace.

@since 3.17.0. + +---@class cmp_dictionary.kit.LSP.TextDocumentClientCapabilities +---@field public synchronization? cmp_dictionary.kit.LSP.TextDocumentSyncClientCapabilities Defines which synchronization capabilities the client supports. +---@field public completion? cmp_dictionary.kit.LSP.CompletionClientCapabilities Capabilities specific to the `textDocument/completion` request. +---@field public hover? cmp_dictionary.kit.LSP.HoverClientCapabilities Capabilities specific to the `textDocument/hover` request. +---@field public signatureHelp? cmp_dictionary.kit.LSP.SignatureHelpClientCapabilities Capabilities specific to the `textDocument/signatureHelp` request. +---@field public declaration? cmp_dictionary.kit.LSP.DeclarationClientCapabilities Capabilities specific to the `textDocument/declaration` request.

@since 3.14.0 +---@field public definition? cmp_dictionary.kit.LSP.DefinitionClientCapabilities Capabilities specific to the `textDocument/definition` request. +---@field public typeDefinition? cmp_dictionary.kit.LSP.TypeDefinitionClientCapabilities Capabilities specific to the `textDocument/typeDefinition` request.

@since 3.6.0 +---@field public implementation? cmp_dictionary.kit.LSP.ImplementationClientCapabilities Capabilities specific to the `textDocument/implementation` request.

@since 3.6.0 +---@field public references? cmp_dictionary.kit.LSP.ReferenceClientCapabilities Capabilities specific to the `textDocument/references` request. +---@field public documentHighlight? cmp_dictionary.kit.LSP.DocumentHighlightClientCapabilities Capabilities specific to the `textDocument/documentHighlight` request. +---@field public documentSymbol? cmp_dictionary.kit.LSP.DocumentSymbolClientCapabilities Capabilities specific to the `textDocument/documentSymbol` request. +---@field public codeAction? cmp_dictionary.kit.LSP.CodeActionClientCapabilities Capabilities specific to the `textDocument/codeAction` request. +---@field public codeLens? cmp_dictionary.kit.LSP.CodeLensClientCapabilities Capabilities specific to the `textDocument/codeLens` request. +---@field public documentLink? cmp_dictionary.kit.LSP.DocumentLinkClientCapabilities Capabilities specific to the `textDocument/documentLink` request. +---@field public colorProvider? cmp_dictionary.kit.LSP.DocumentColorClientCapabilities Capabilities specific to the `textDocument/documentColor` and the
`textDocument/colorPresentation` request.

@since 3.6.0 +---@field public formatting? cmp_dictionary.kit.LSP.DocumentFormattingClientCapabilities Capabilities specific to the `textDocument/formatting` request. +---@field public rangeFormatting? cmp_dictionary.kit.LSP.DocumentRangeFormattingClientCapabilities Capabilities specific to the `textDocument/rangeFormatting` request. +---@field public onTypeFormatting? cmp_dictionary.kit.LSP.DocumentOnTypeFormattingClientCapabilities Capabilities specific to the `textDocument/onTypeFormatting` request. +---@field public rename? cmp_dictionary.kit.LSP.RenameClientCapabilities Capabilities specific to the `textDocument/rename` request. +---@field public foldingRange? cmp_dictionary.kit.LSP.FoldingRangeClientCapabilities Capabilities specific to the `textDocument/foldingRange` request.

@since 3.10.0 +---@field public selectionRange? cmp_dictionary.kit.LSP.SelectionRangeClientCapabilities Capabilities specific to the `textDocument/selectionRange` request.

@since 3.15.0 +---@field public publishDiagnostics? cmp_dictionary.kit.LSP.PublishDiagnosticsClientCapabilities Capabilities specific to the `textDocument/publishDiagnostics` notification. +---@field public callHierarchy? cmp_dictionary.kit.LSP.CallHierarchyClientCapabilities Capabilities specific to the various call hierarchy requests.

@since 3.16.0 +---@field public semanticTokens? cmp_dictionary.kit.LSP.SemanticTokensClientCapabilities Capabilities specific to the various semantic token request.

@since 3.16.0 +---@field public linkedEditingRange? cmp_dictionary.kit.LSP.LinkedEditingRangeClientCapabilities Capabilities specific to the `textDocument/linkedEditingRange` request.

@since 3.16.0 +---@field public moniker? cmp_dictionary.kit.LSP.MonikerClientCapabilities Client capabilities specific to the `textDocument/moniker` request.

@since 3.16.0 +---@field public typeHierarchy? cmp_dictionary.kit.LSP.TypeHierarchyClientCapabilities Capabilities specific to the various type hierarchy requests.

@since 3.17.0 +---@field public inlineValue? cmp_dictionary.kit.LSP.InlineValueClientCapabilities Capabilities specific to the `textDocument/inlineValue` request.

@since 3.17.0 +---@field public inlayHint? cmp_dictionary.kit.LSP.InlayHintClientCapabilities Capabilities specific to the `textDocument/inlayHint` request.

@since 3.17.0 +---@field public diagnostic? cmp_dictionary.kit.LSP.DiagnosticClientCapabilities Capabilities specific to the diagnostic pull model.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.NotebookDocumentClientCapabilities +---@field public synchronization cmp_dictionary.kit.LSP.NotebookDocumentSyncClientCapabilities Capabilities specific to notebook document synchronization

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.WindowClientCapabilities +---@field public workDoneProgress? boolean It indicates whether the client supports server initiated
progress using the `window/workDoneProgress/create` request.

The capability also controls Whether client supports handling
of progress notifications. If set servers are allowed to report a
`workDoneProgress` property in the request specific server
capabilities.

@since 3.15.0 +---@field public showMessage? cmp_dictionary.kit.LSP.ShowMessageRequestClientCapabilities Capabilities specific to the showMessage request.

@since 3.16.0 +---@field public showDocument? cmp_dictionary.kit.LSP.ShowDocumentClientCapabilities Capabilities specific to the showDocument request.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.GeneralClientCapabilities +---@field public staleRequestSupport? cmp_dictionary.kit.LSP.GeneralClientCapabilities.staleRequestSupport Client capability that signals how the client
handles stale requests (e.g. a request
for which the client will not process the response
anymore since the information is outdated).

@since 3.17.0 +---@field public regularExpressions? cmp_dictionary.kit.LSP.RegularExpressionsClientCapabilities Client capabilities specific to regular expressions.

@since 3.16.0 +---@field public markdown? cmp_dictionary.kit.LSP.MarkdownClientCapabilities Client capabilities specific to the client's markdown parser.

@since 3.16.0 +---@field public positionEncodings? cmp_dictionary.kit.LSP.PositionEncodingKind[] The position encodings supported by the client. Client and server
have to agree on the same position encoding to ensure that offsets
(e.g. character position in a line) are interpreted the same on both
sides.

To keep the protocol backwards compatible the following applies: if
the value 'utf-16' is missing from the array of position encodings
servers can assume that the client supports UTF-16. UTF-16 is
therefore a mandatory encoding.

If omitted it defaults to ['utf-16'].

Implementation considerations: since the conversion from one encoding
into another requires the content of the file / line the conversion
is best done where the file is read which is usually on the server
side.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.GeneralClientCapabilities.staleRequestSupport +---@field public cancel boolean The client will actively cancel the request. +---@field public retryOnContentModified string[] The list of requests for which the client
will retry the request if it receives a
response with error code `ContentModified` + +---@class cmp_dictionary.kit.LSP.RelativePattern +---@field public baseUri (cmp_dictionary.kit.LSP.WorkspaceFolder | string) A workspace folder or a base URI to which this pattern will be matched
against relatively. +---@field public pattern cmp_dictionary.kit.LSP.Pattern The actual glob pattern; + +---@class cmp_dictionary.kit.LSP.WorkspaceEditClientCapabilities +---@field public documentChanges? boolean The client supports versioned document changes in `WorkspaceEdit`s +---@field public resourceOperations? cmp_dictionary.kit.LSP.ResourceOperationKind[] The resource operations the client supports. Clients should at least
support 'create', 'rename' and 'delete' files and folders.

@since 3.13.0 +---@field public failureHandling? cmp_dictionary.kit.LSP.FailureHandlingKind The failure handling strategy of a client if applying the workspace edit
fails.

@since 3.13.0 +---@field public normalizesLineEndings? boolean Whether the client normalizes line endings to the client specific
setting.
If set to `true` the client will normalize line ending characters
in a workspace edit to the client-specified new line
character.

@since 3.16.0 +---@field public changeAnnotationSupport? cmp_dictionary.kit.LSP.WorkspaceEditClientCapabilities.changeAnnotationSupport Whether the client in general supports change annotations on text edits,
create file, rename file and delete file changes.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.WorkspaceEditClientCapabilities.changeAnnotationSupport +---@field public groupsOnLabel? boolean Whether the client groups edits with equal labels into tree nodes,
for instance all edits labelled with "Changes in Strings" would
be a tree node. + +---@class cmp_dictionary.kit.LSP.DidChangeConfigurationClientCapabilities +---@field public dynamicRegistration? boolean Did change configuration notification supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.DidChangeWatchedFilesClientCapabilities +---@field public dynamicRegistration? boolean Did change watched files notification supports dynamic registration. Please note
that the current protocol doesn't support static configuration for file changes
from the server side. +---@field public relativePatternSupport? boolean Whether the client has support for {@link RelativePattern relative pattern}
or not.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities +---@field public dynamicRegistration? boolean Symbol request supports dynamic registration. +---@field public symbolKind? cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities.symbolKind Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. +---@field public tagSupport? cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities.tagSupport The client supports tags on `SymbolInformation`.
Clients supporting tags have to handle unknown tags gracefully.

@since 3.16.0 +---@field public resolveSupport? cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities.resolveSupport The client support partial workspace symbols. The client will send the
request `workspaceSymbol/resolve` to the server to resolve additional
properties.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities.symbolKind +---@field public valueSet? cmp_dictionary.kit.LSP.SymbolKind[] The symbol kind values the client supports. When this
property exists the client also guarantees that it will
handle values outside its set gracefully and falls back
to a default value when unknown.

If this property is not present the client only supports
the symbol kinds from `File` to `Array` as defined in
the initial version of the protocol. + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities.tagSupport +---@field public valueSet cmp_dictionary.kit.LSP.SymbolTag[] The tags supported by the client. + +---@class cmp_dictionary.kit.LSP.WorkspaceSymbolClientCapabilities.resolveSupport +---@field public properties string[] The properties that a client can resolve lazily. Usually
`location.range` + +---@class cmp_dictionary.kit.LSP.ExecuteCommandClientCapabilities +---@field public dynamicRegistration? boolean Execute command supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.SemanticTokensWorkspaceClientCapabilities +---@field public refreshSupport? boolean Whether the client implementation supports a refresh request sent from
the server to the client.

Note that this event is global and will force the client to refresh all
semantic tokens currently shown. It should be used with absolute care
and is useful for situation where a server for example detects a project
wide change that requires such a calculation. + +---@class cmp_dictionary.kit.LSP.CodeLensWorkspaceClientCapabilities +---@field public refreshSupport? boolean Whether the client implementation supports a refresh request sent from the
server to the client.

Note that this event is global and will force the client to refresh all
code lenses currently shown. It should be used with absolute care and is
useful for situation where a server for example detect a project wide
change that requires such a calculation. + +---@class cmp_dictionary.kit.LSP.FileOperationClientCapabilities +---@field public dynamicRegistration? boolean Whether the client supports dynamic registration for file requests/notifications. +---@field public didCreate? boolean The client has support for sending didCreateFiles notifications. +---@field public willCreate? boolean The client has support for sending willCreateFiles requests. +---@field public didRename? boolean The client has support for sending didRenameFiles notifications. +---@field public willRename? boolean The client has support for sending willRenameFiles requests. +---@field public didDelete? boolean The client has support for sending didDeleteFiles notifications. +---@field public willDelete? boolean The client has support for sending willDeleteFiles requests. + +---@class cmp_dictionary.kit.LSP.InlineValueWorkspaceClientCapabilities +---@field public refreshSupport? boolean Whether the client implementation supports a refresh request sent from the
server to the client.

Note that this event is global and will force the client to refresh all
inline values currently shown. It should be used with absolute care and is
useful for situation where a server for example detects a project wide
change that requires such a calculation. + +---@class cmp_dictionary.kit.LSP.InlayHintWorkspaceClientCapabilities +---@field public refreshSupport? boolean Whether the client implementation supports a refresh request sent from
the server to the client.

Note that this event is global and will force the client to refresh all
inlay hints currently shown. It should be used with absolute care and
is useful for situation where a server for example detects a project wide
change that requires such a calculation. + +---@class cmp_dictionary.kit.LSP.DiagnosticWorkspaceClientCapabilities +---@field public refreshSupport? boolean Whether the client implementation supports a refresh request sent from
the server to the client.

Note that this event is global and will force the client to refresh all
pulled diagnostics currently shown. It should be used with absolute care and
is useful for situation where a server for example detects a project wide
change that requires such a calculation. + +---@class cmp_dictionary.kit.LSP.TextDocumentSyncClientCapabilities +---@field public dynamicRegistration? boolean Whether text document synchronization supports dynamic registration. +---@field public willSave? boolean The client supports sending will save notifications. +---@field public willSaveWaitUntil? boolean The client supports sending a will save request and
waits for a response providing text edits which will
be applied to the document before it is saved. +---@field public didSave? boolean The client supports did save notifications. + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities +---@field public dynamicRegistration? boolean Whether completion supports dynamic registration. +---@field public completionItem? cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem The client supports the following `CompletionItem` specific
capabilities. +---@field public completionItemKind? cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItemKind +---@field public insertTextMode? cmp_dictionary.kit.LSP.InsertTextMode Defines how the client handles whitespace and indentation
when accepting a completion item that uses multi line
text in either `insertText` or `textEdit`.

@since 3.17.0 +---@field public contextSupport? boolean The client supports to send additional context information for a
`textDocument/completion` request. +---@field public completionList? cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionList The client supports the following `CompletionList` specific
capabilities.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem +---@field public snippetSupport? boolean Client supports snippets as insert text.

A snippet can define tab stops and placeholders with `$1`, `$2`
and `${3:foo}`. `$0` defines the final tab stop, it defaults to
the end of the snippet. Placeholders with equal identifiers are linked,
that is typing in one will update others too. +---@field public commitCharactersSupport? boolean Client supports commit characters on a completion item. +---@field public documentationFormat? cmp_dictionary.kit.LSP.MarkupKind[] Client supports the following content formats for the documentation
property. The order describes the preferred format of the client. +---@field public deprecatedSupport? boolean Client supports the deprecated property on a completion item. +---@field public preselectSupport? boolean Client supports the preselect property on a completion item. +---@field public tagSupport? cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem.tagSupport Client supports the tag property on a completion item. Clients supporting
tags have to handle unknown tags gracefully. Clients especially need to
preserve unknown tags when sending a completion item back to the server in
a resolve call.

@since 3.15.0 +---@field public insertReplaceSupport? boolean Client support insert replace edit to control different behavior if a
completion item is inserted in the text or should replace text.

@since 3.16.0 +---@field public resolveSupport? cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem.resolveSupport Indicates which properties a client can resolve lazily on a completion
item. Before version 3.16.0 only the predefined properties `documentation`
and `details` could be resolved lazily.

@since 3.16.0 +---@field public insertTextModeSupport? cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem.insertTextModeSupport The client supports the `insertTextMode` property on
a completion item to override the whitespace handling mode
as defined by the client (see `insertTextMode`).

@since 3.16.0 +---@field public labelDetailsSupport? boolean The client has support for completion item label
details (see also `CompletionItemLabelDetails`).

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem.tagSupport +---@field public valueSet cmp_dictionary.kit.LSP.CompletionItemTag[] The tags supported by the client. + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem.resolveSupport +---@field public properties string[] The properties that a client can resolve lazily. + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItem.insertTextModeSupport +---@field public valueSet cmp_dictionary.kit.LSP.InsertTextMode[] + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionItemKind +---@field public valueSet? cmp_dictionary.kit.LSP.CompletionItemKind[] The completion item kind values the client supports. When this
property exists the client also guarantees that it will
handle values outside its set gracefully and falls back
to a default value when unknown.

If this property is not present the client only supports
the completion items kinds from `Text` to `Reference` as defined in
the initial version of the protocol. + +---@class cmp_dictionary.kit.LSP.CompletionClientCapabilities.completionList +---@field public itemDefaults? string[] The client supports the following itemDefaults on
a completion list.

The value lists the supported property names of the
`CompletionList.itemDefaults` object. If omitted
no properties are supported.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.HoverClientCapabilities +---@field public dynamicRegistration? boolean Whether hover supports dynamic registration. +---@field public contentFormat? cmp_dictionary.kit.LSP.MarkupKind[] Client supports the following content formats for the content
property. The order describes the preferred format of the client. + +---@class cmp_dictionary.kit.LSP.SignatureHelpClientCapabilities +---@field public dynamicRegistration? boolean Whether signature help supports dynamic registration. +---@field public signatureInformation? cmp_dictionary.kit.LSP.SignatureHelpClientCapabilities.signatureInformation The client supports the following `SignatureInformation`
specific properties. +---@field public contextSupport? boolean The client supports to send additional context information for a
`textDocument/signatureHelp` request. A client that opts into
contextSupport will also support the `retriggerCharacters` on
`SignatureHelpOptions`.

@since 3.15.0 + +---@class cmp_dictionary.kit.LSP.SignatureHelpClientCapabilities.signatureInformation +---@field public documentationFormat? cmp_dictionary.kit.LSP.MarkupKind[] Client supports the following content formats for the documentation
property. The order describes the preferred format of the client. +---@field public parameterInformation? cmp_dictionary.kit.LSP.SignatureHelpClientCapabilities.signatureInformation.parameterInformation Client capabilities specific to parameter information. +---@field public activeParameterSupport? boolean The client supports the `activeParameter` property on `SignatureInformation`
literal.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.SignatureHelpClientCapabilities.signatureInformation.parameterInformation +---@field public labelOffsetSupport? boolean The client supports processing label offsets instead of a
simple label string.

@since 3.14.0 + +---@class cmp_dictionary.kit.LSP.DeclarationClientCapabilities +---@field public dynamicRegistration? boolean Whether declaration supports dynamic registration. If this is set to `true`
the client supports the new `DeclarationRegistrationOptions` return value
for the corresponding server capability as well. +---@field public linkSupport? boolean The client supports additional metadata in the form of declaration links. + +---@class cmp_dictionary.kit.LSP.DefinitionClientCapabilities +---@field public dynamicRegistration? boolean Whether definition supports dynamic registration. +---@field public linkSupport? boolean The client supports additional metadata in the form of definition links.

@since 3.14.0 + +---@class cmp_dictionary.kit.LSP.TypeDefinitionClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `TypeDefinitionRegistrationOptions` return value
for the corresponding server capability as well. +---@field public linkSupport? boolean The client supports additional metadata in the form of definition links.

Since 3.14.0 + +---@class cmp_dictionary.kit.LSP.ImplementationClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `ImplementationRegistrationOptions` return value
for the corresponding server capability as well. +---@field public linkSupport? boolean The client supports additional metadata in the form of definition links.

@since 3.14.0 + +---@class cmp_dictionary.kit.LSP.ReferenceClientCapabilities +---@field public dynamicRegistration? boolean Whether references supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.DocumentHighlightClientCapabilities +---@field public dynamicRegistration? boolean Whether document highlight supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.DocumentSymbolClientCapabilities +---@field public dynamicRegistration? boolean Whether document symbol supports dynamic registration. +---@field public symbolKind? cmp_dictionary.kit.LSP.DocumentSymbolClientCapabilities.symbolKind Specific capabilities for the `SymbolKind` in the
`textDocument/documentSymbol` request. +---@field public hierarchicalDocumentSymbolSupport? boolean The client supports hierarchical document symbols. +---@field public tagSupport? cmp_dictionary.kit.LSP.DocumentSymbolClientCapabilities.tagSupport The client supports tags on `SymbolInformation`. Tags are supported on
`DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.
Clients supporting tags have to handle unknown tags gracefully.

@since 3.16.0 +---@field public labelSupport? boolean The client supports an additional label presented in the UI when
registering a document symbol provider.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.DocumentSymbolClientCapabilities.symbolKind +---@field public valueSet? cmp_dictionary.kit.LSP.SymbolKind[] The symbol kind values the client supports. When this
property exists the client also guarantees that it will
handle values outside its set gracefully and falls back
to a default value when unknown.

If this property is not present the client only supports
the symbol kinds from `File` to `Array` as defined in
the initial version of the protocol. + +---@class cmp_dictionary.kit.LSP.DocumentSymbolClientCapabilities.tagSupport +---@field public valueSet cmp_dictionary.kit.LSP.SymbolTag[] The tags supported by the client. + +---@class cmp_dictionary.kit.LSP.CodeActionClientCapabilities +---@field public dynamicRegistration? boolean Whether code action supports dynamic registration. +---@field public codeActionLiteralSupport? cmp_dictionary.kit.LSP.CodeActionClientCapabilities.codeActionLiteralSupport The client support code action literals of type `CodeAction` as a valid
response of the `textDocument/codeAction` request. If the property is not
set the request can only return `Command` literals.

@since 3.8.0 +---@field public isPreferredSupport? boolean Whether code action supports the `isPreferred` property.

@since 3.15.0 +---@field public disabledSupport? boolean Whether code action supports the `disabled` property.

@since 3.16.0 +---@field public dataSupport? boolean Whether code action supports the `data` property which is
preserved between a `textDocument/codeAction` and a
`codeAction/resolve` request.

@since 3.16.0 +---@field public resolveSupport? cmp_dictionary.kit.LSP.CodeActionClientCapabilities.resolveSupport Whether the client supports resolving additional code action
properties via a separate `codeAction/resolve` request.

@since 3.16.0 +---@field public honorsChangeAnnotations? boolean Whether the client honors the change annotations in
text edits and resource operations returned via the
`CodeAction#edit` property by for example presenting
the workspace edit in the user interface and asking
for confirmation.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.CodeActionClientCapabilities.codeActionLiteralSupport +---@field public codeActionKind cmp_dictionary.kit.LSP.CodeActionClientCapabilities.codeActionLiteralSupport.codeActionKind The code action kind is support with the following value
set. + +---@class cmp_dictionary.kit.LSP.CodeActionClientCapabilities.codeActionLiteralSupport.codeActionKind +---@field public valueSet cmp_dictionary.kit.LSP.CodeActionKind[] The code action kind values the client supports. When this
property exists the client also guarantees that it will
handle values outside its set gracefully and falls back
to a default value when unknown. + +---@class cmp_dictionary.kit.LSP.CodeActionClientCapabilities.resolveSupport +---@field public properties string[] The properties that a client can resolve lazily. + +---@class cmp_dictionary.kit.LSP.CodeLensClientCapabilities +---@field public dynamicRegistration? boolean Whether code lens supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.DocumentLinkClientCapabilities +---@field public dynamicRegistration? boolean Whether document link supports dynamic registration. +---@field public tooltipSupport? boolean Whether the client supports the `tooltip` property on `DocumentLink`.

@since 3.15.0 + +---@class cmp_dictionary.kit.LSP.DocumentColorClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `DocumentColorRegistrationOptions` return value
for the corresponding server capability as well. + +---@class cmp_dictionary.kit.LSP.DocumentFormattingClientCapabilities +---@field public dynamicRegistration? boolean Whether formatting supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.DocumentRangeFormattingClientCapabilities +---@field public dynamicRegistration? boolean Whether range formatting supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.DocumentOnTypeFormattingClientCapabilities +---@field public dynamicRegistration? boolean Whether on type formatting supports dynamic registration. + +---@class cmp_dictionary.kit.LSP.RenameClientCapabilities +---@field public dynamicRegistration? boolean Whether rename supports dynamic registration. +---@field public prepareSupport? boolean Client supports testing for validity of rename operations
before execution.

@since 3.12.0 +---@field public prepareSupportDefaultBehavior? cmp_dictionary.kit.LSP.PrepareSupportDefaultBehavior Client supports the default behavior result.

The value indicates the default behavior used by the
client.

@since 3.16.0 +---@field public honorsChangeAnnotations? boolean Whether the client honors the change annotations in
text edits and resource operations returned via the
rename request's workspace edit by for example presenting
the workspace edit in the user interface and asking
for confirmation.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.FoldingRangeClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration for folding range
providers. If this is set to `true` the client supports the new
`FoldingRangeRegistrationOptions` return value for the corresponding
server capability as well. +---@field public rangeLimit? integer The maximum number of folding ranges that the client prefers to receive
per document. The value serves as a hint, servers are free to follow the
limit. +---@field public lineFoldingOnly? boolean If set, the client signals that it only supports folding complete lines.
If set, client will ignore specified `startCharacter` and `endCharacter`
properties in a FoldingRange. +---@field public foldingRangeKind? cmp_dictionary.kit.LSP.FoldingRangeClientCapabilities.foldingRangeKind Specific options for the folding range kind.

@since 3.17.0 +---@field public foldingRange? cmp_dictionary.kit.LSP.FoldingRangeClientCapabilities.foldingRange Specific options for the folding range.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.FoldingRangeClientCapabilities.foldingRangeKind +---@field public valueSet? cmp_dictionary.kit.LSP.FoldingRangeKind[] The folding range kind values the client supports. When this
property exists the client also guarantees that it will
handle values outside its set gracefully and falls back
to a default value when unknown. + +---@class cmp_dictionary.kit.LSP.FoldingRangeClientCapabilities.foldingRange +---@field public collapsedText? boolean If set, the client signals that it supports setting collapsedText on
folding ranges to display custom labels instead of the default text.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.SelectionRangeClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration for selection range providers. If this is set to `true`
the client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server
capability as well. + +---@class cmp_dictionary.kit.LSP.PublishDiagnosticsClientCapabilities +---@field public relatedInformation? boolean Whether the clients accepts diagnostics with related information. +---@field public tagSupport? cmp_dictionary.kit.LSP.PublishDiagnosticsClientCapabilities.tagSupport Client supports the tag property to provide meta data about a diagnostic.
Clients supporting tags have to handle unknown tags gracefully.

@since 3.15.0 +---@field public versionSupport? boolean Whether the client interprets the version property of the
`textDocument/publishDiagnostics` notification's parameter.

@since 3.15.0 +---@field public codeDescriptionSupport? boolean Client supports a codeDescription property

@since 3.16.0 +---@field public dataSupport? boolean Whether code action supports the `data` property which is
preserved between a `textDocument/publishDiagnostics` and
`textDocument/codeAction` request.

@since 3.16.0 + +---@class cmp_dictionary.kit.LSP.PublishDiagnosticsClientCapabilities.tagSupport +---@field public valueSet cmp_dictionary.kit.LSP.DiagnosticTag[] The tags supported by the client. + +---@class cmp_dictionary.kit.LSP.CallHierarchyClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
return value for the corresponding server capability as well. + +---@class cmp_dictionary.kit.LSP.SemanticTokensClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
return value for the corresponding server capability as well. +---@field public requests cmp_dictionary.kit.LSP.SemanticTokensClientCapabilities.requests Which requests the client supports and might send to the server
depending on the server's capability. Please note that clients might not
show semantic tokens or degrade some of the user experience if a range
or full request is advertised by the client but not provided by the
server. If for example the client capability `requests.full` and
`request.range` are both set to true but the server only provides a
range provider the client might not render a minimap correctly or might
even decide to not show any semantic tokens at all. +---@field public tokenTypes string[] The token types that the client supports. +---@field public tokenModifiers string[] The token modifiers that the client supports. +---@field public formats cmp_dictionary.kit.LSP.TokenFormat[] The token formats the clients supports. +---@field public overlappingTokenSupport? boolean Whether the client supports tokens that can overlap each other. +---@field public multilineTokenSupport? boolean Whether the client supports tokens that can span multiple lines. +---@field public serverCancelSupport? boolean Whether the client allows the server to actively cancel a
semantic token request, e.g. supports returning
LSPErrorCodes.ServerCancelled. If a server does the client
needs to retrigger the request.

@since 3.17.0 +---@field public augmentsSyntaxTokens? boolean Whether the client uses semantic tokens to augment existing
syntax tokens. If set to `true` client side created syntax
tokens and semantic tokens are both used for colorization. If
set to `false` the client only uses the returned semantic tokens
for colorization.

If the value is `undefined` then the client behavior is not
specified.

@since 3.17.0 + +---@class cmp_dictionary.kit.LSP.SemanticTokensClientCapabilities.requests +---@field public range? (boolean | { }) The client will send the `textDocument/semanticTokens/range` request if
the server provides a corresponding handler. +---@field public full? (boolean | { delta?: boolean }) The client will send the `textDocument/semanticTokens/full` request if
the server provides a corresponding handler. + +---@class cmp_dictionary.kit.LSP.LinkedEditingRangeClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
return value for the corresponding server capability as well. + +---@class cmp_dictionary.kit.LSP.MonikerClientCapabilities +---@field public dynamicRegistration? boolean Whether moniker supports dynamic registration. If this is set to `true`
the client supports the new `MonikerRegistrationOptions` return value
for the corresponding server capability as well. + +---@class cmp_dictionary.kit.LSP.TypeHierarchyClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
return value for the corresponding server capability as well. + +---@class cmp_dictionary.kit.LSP.InlineValueClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration for inline value providers. + +---@class cmp_dictionary.kit.LSP.InlayHintClientCapabilities +---@field public dynamicRegistration? boolean Whether inlay hints support dynamic registration. +---@field public resolveSupport? cmp_dictionary.kit.LSP.InlayHintClientCapabilities.resolveSupport Indicates which properties a client can resolve lazily on an inlay
hint. + +---@class cmp_dictionary.kit.LSP.InlayHintClientCapabilities.resolveSupport +---@field public properties string[] The properties that a client can resolve lazily. + +---@class cmp_dictionary.kit.LSP.DiagnosticClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is set to `true`
the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
return value for the corresponding server capability as well. +---@field public relatedDocumentSupport? boolean Whether the clients supports related documents for document diagnostic pulls. + +---@class cmp_dictionary.kit.LSP.NotebookDocumentSyncClientCapabilities +---@field public dynamicRegistration? boolean Whether implementation supports dynamic registration. If this is
set to `true` the client supports the new
`(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
return value for the corresponding server capability as well. +---@field public executionSummarySupport? boolean The client supports sending execution summary data per cell. + +---@class cmp_dictionary.kit.LSP.ShowMessageRequestClientCapabilities +---@field public messageActionItem? cmp_dictionary.kit.LSP.ShowMessageRequestClientCapabilities.messageActionItem Capabilities specific to the `MessageActionItem` type. + +---@class cmp_dictionary.kit.LSP.ShowMessageRequestClientCapabilities.messageActionItem +---@field public additionalPropertiesSupport? boolean Whether the client supports additional attributes which
are preserved and send back to the server in the
request's response. + +---@class cmp_dictionary.kit.LSP.ShowDocumentClientCapabilities +---@field public support boolean The client has support for the showDocument
request. + +---@class cmp_dictionary.kit.LSP.RegularExpressionsClientCapabilities +---@field public engine string The engine's name. +---@field public version? string The engine's version. + +---@class cmp_dictionary.kit.LSP.MarkdownClientCapabilities +---@field public parser string The name of the parser. +---@field public version? string The version of the parser. +---@field public allowedTags? string[] A list of HTML tags that the client allows / supports in
Markdown.

@since 3.17.0 + +---@alias cmp_dictionary.kit.LSP.TextDocumentImplementationResponse (cmp_dictionary.kit.LSP.Definition | cmp_dictionary.kit.LSP.DefinitionLink[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentTypeDefinitionResponse (cmp_dictionary.kit.LSP.Definition | cmp_dictionary.kit.LSP.DefinitionLink[] | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceWorkspaceFoldersResponse (cmp_dictionary.kit.LSP.WorkspaceFolder[] | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceConfigurationResponse cmp_dictionary.kit.LSP.LSPAny[] + +---@alias cmp_dictionary.kit.LSP.TextDocumentDocumentColorResponse cmp_dictionary.kit.LSP.ColorInformation[] + +---@alias cmp_dictionary.kit.LSP.TextDocumentColorPresentationResponse cmp_dictionary.kit.LSP.ColorPresentation[] + +---@alias cmp_dictionary.kit.LSP.TextDocumentFoldingRangeResponse (cmp_dictionary.kit.LSP.FoldingRange[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentDeclarationResponse (cmp_dictionary.kit.LSP.Declaration | cmp_dictionary.kit.LSP.DeclarationLink[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentSelectionRangeResponse (cmp_dictionary.kit.LSP.SelectionRange[] | nil) + +---@alias cmp_dictionary.kit.LSP.WindowWorkDoneProgressCreateResponse nil + +---@alias cmp_dictionary.kit.LSP.TextDocumentPrepareCallHierarchyResponse (cmp_dictionary.kit.LSP.CallHierarchyItem[] | nil) + +---@alias cmp_dictionary.kit.LSP.CallHierarchyIncomingCallsResponse (cmp_dictionary.kit.LSP.CallHierarchyIncomingCall[] | nil) + +---@alias cmp_dictionary.kit.LSP.CallHierarchyOutgoingCallsResponse (cmp_dictionary.kit.LSP.CallHierarchyOutgoingCall[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentSemanticTokensFullResponse (cmp_dictionary.kit.LSP.SemanticTokens | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentSemanticTokensFullDeltaResponse (cmp_dictionary.kit.LSP.SemanticTokens | cmp_dictionary.kit.LSP.SemanticTokensDelta | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentSemanticTokensRangeResponse (cmp_dictionary.kit.LSP.SemanticTokens | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceSemanticTokensRefreshResponse nil + +---@alias cmp_dictionary.kit.LSP.WindowShowDocumentResponse cmp_dictionary.kit.LSP.ShowDocumentResult + +---@alias cmp_dictionary.kit.LSP.TextDocumentLinkedEditingRangeResponse (cmp_dictionary.kit.LSP.LinkedEditingRanges | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceWillCreateFilesResponse (cmp_dictionary.kit.LSP.WorkspaceEdit | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceWillRenameFilesResponse (cmp_dictionary.kit.LSP.WorkspaceEdit | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceWillDeleteFilesResponse (cmp_dictionary.kit.LSP.WorkspaceEdit | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentMonikerResponse (cmp_dictionary.kit.LSP.Moniker[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentPrepareTypeHierarchyResponse (cmp_dictionary.kit.LSP.TypeHierarchyItem[] | nil) + +---@alias cmp_dictionary.kit.LSP.TypeHierarchySupertypesResponse (cmp_dictionary.kit.LSP.TypeHierarchyItem[] | nil) + +---@alias cmp_dictionary.kit.LSP.TypeHierarchySubtypesResponse (cmp_dictionary.kit.LSP.TypeHierarchyItem[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentInlineValueResponse (cmp_dictionary.kit.LSP.InlineValue[] | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceInlineValueRefreshResponse nil + +---@alias cmp_dictionary.kit.LSP.TextDocumentInlayHintResponse (cmp_dictionary.kit.LSP.InlayHint[] | nil) + +---@alias cmp_dictionary.kit.LSP.InlayHintResolveResponse cmp_dictionary.kit.LSP.InlayHint + +---@alias cmp_dictionary.kit.LSP.WorkspaceInlayHintRefreshResponse nil + +---@alias cmp_dictionary.kit.LSP.TextDocumentDiagnosticResponse cmp_dictionary.kit.LSP.DocumentDiagnosticReport + +---@alias cmp_dictionary.kit.LSP.WorkspaceDiagnosticResponse cmp_dictionary.kit.LSP.WorkspaceDiagnosticReport + +---@alias cmp_dictionary.kit.LSP.WorkspaceDiagnosticRefreshResponse nil + +---@alias cmp_dictionary.kit.LSP.ClientRegisterCapabilityResponse nil + +---@alias cmp_dictionary.kit.LSP.ClientUnregisterCapabilityResponse nil + +---@alias cmp_dictionary.kit.LSP.InitializeResponse cmp_dictionary.kit.LSP.InitializeResult + +---@alias cmp_dictionary.kit.LSP.ShutdownResponse nil + +---@alias cmp_dictionary.kit.LSP.WindowShowMessageRequestResponse (cmp_dictionary.kit.LSP.MessageActionItem | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentWillSaveWaitUntilResponse (cmp_dictionary.kit.LSP.TextEdit[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentCompletionResponse (cmp_dictionary.kit.LSP.CompletionItem[] | cmp_dictionary.kit.LSP.CompletionList | nil) + +---@alias cmp_dictionary.kit.LSP.CompletionItemResolveResponse cmp_dictionary.kit.LSP.CompletionItem + +---@alias cmp_dictionary.kit.LSP.TextDocumentHoverResponse (cmp_dictionary.kit.LSP.Hover | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentSignatureHelpResponse (cmp_dictionary.kit.LSP.SignatureHelp | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentDefinitionResponse (cmp_dictionary.kit.LSP.Definition | cmp_dictionary.kit.LSP.DefinitionLink[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentReferencesResponse (cmp_dictionary.kit.LSP.Location[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentDocumentHighlightResponse (cmp_dictionary.kit.LSP.DocumentHighlight[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentDocumentSymbolResponse (cmp_dictionary.kit.LSP.SymbolInformation[] | cmp_dictionary.kit.LSP.DocumentSymbol[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentCodeActionResponse ((cmp_dictionary.kit.LSP.Command | cmp_dictionary.kit.LSP.CodeAction)[] | nil) + +---@alias cmp_dictionary.kit.LSP.CodeActionResolveResponse cmp_dictionary.kit.LSP.CodeAction + +---@alias cmp_dictionary.kit.LSP.WorkspaceSymbolResponse (cmp_dictionary.kit.LSP.SymbolInformation[] | cmp_dictionary.kit.LSP.WorkspaceSymbol[] | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceSymbolResolveResponse cmp_dictionary.kit.LSP.WorkspaceSymbol + +---@alias cmp_dictionary.kit.LSP.TextDocumentCodeLensResponse (cmp_dictionary.kit.LSP.CodeLens[] | nil) + +---@alias cmp_dictionary.kit.LSP.CodeLensResolveResponse cmp_dictionary.kit.LSP.CodeLens + +---@alias cmp_dictionary.kit.LSP.WorkspaceCodeLensRefreshResponse nil + +---@alias cmp_dictionary.kit.LSP.TextDocumentDocumentLinkResponse (cmp_dictionary.kit.LSP.DocumentLink[] | nil) + +---@alias cmp_dictionary.kit.LSP.DocumentLinkResolveResponse cmp_dictionary.kit.LSP.DocumentLink + +---@alias cmp_dictionary.kit.LSP.TextDocumentFormattingResponse (cmp_dictionary.kit.LSP.TextEdit[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentRangeFormattingResponse (cmp_dictionary.kit.LSP.TextEdit[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentOnTypeFormattingResponse (cmp_dictionary.kit.LSP.TextEdit[] | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentRenameResponse (cmp_dictionary.kit.LSP.WorkspaceEdit | nil) + +---@alias cmp_dictionary.kit.LSP.TextDocumentPrepareRenameResponse (cmp_dictionary.kit.LSP.PrepareRenameResult | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceExecuteCommandResponse (cmp_dictionary.kit.LSP.LSPAny | nil) + +---@alias cmp_dictionary.kit.LSP.WorkspaceApplyEditResponse cmp_dictionary.kit.LSP.ApplyWorkspaceEditResult + +---@alias cmp_dictionary.kit.LSP.Definition (cmp_dictionary.kit.LSP.Location | cmp_dictionary.kit.LSP.Location[]) + +---@alias cmp_dictionary.kit.LSP.DefinitionLink cmp_dictionary.kit.LSP.LocationLink + +---@alias cmp_dictionary.kit.LSP.LSPArray cmp_dictionary.kit.LSP.LSPAny[] + +---@alias cmp_dictionary.kit.LSP.LSPAny (cmp_dictionary.kit.LSP.LSPObject | cmp_dictionary.kit.LSP.LSPArray | string | integer | integer | integer | boolean | nil) + +---@alias cmp_dictionary.kit.LSP.Declaration (cmp_dictionary.kit.LSP.Location | cmp_dictionary.kit.LSP.Location[]) + +---@alias cmp_dictionary.kit.LSP.DeclarationLink cmp_dictionary.kit.LSP.LocationLink + +---@alias cmp_dictionary.kit.LSP.InlineValue (cmp_dictionary.kit.LSP.InlineValueText | cmp_dictionary.kit.LSP.InlineValueVariableLookup | cmp_dictionary.kit.LSP.InlineValueEvaluatableExpression) + +---@alias cmp_dictionary.kit.LSP.DocumentDiagnosticReport (cmp_dictionary.kit.LSP.RelatedFullDocumentDiagnosticReport | cmp_dictionary.kit.LSP.RelatedUnchangedDocumentDiagnosticReport) + +---@alias cmp_dictionary.kit.LSP.PrepareRenameResult (cmp_dictionary.kit.LSP.Range | { range: cmp_dictionary.kit.LSP.Range, placeholder: string } | { defaultBehavior: boolean }) + +---@alias cmp_dictionary.kit.LSP.ProgressToken (integer | string) + +---@alias cmp_dictionary.kit.LSP.DocumentSelector cmp_dictionary.kit.LSP.DocumentFilter[] + +---@alias cmp_dictionary.kit.LSP.ChangeAnnotationIdentifier string + +---@alias cmp_dictionary.kit.LSP.WorkspaceDocumentDiagnosticReport (cmp_dictionary.kit.LSP.WorkspaceFullDocumentDiagnosticReport | cmp_dictionary.kit.LSP.WorkspaceUnchangedDocumentDiagnosticReport) + +---@alias cmp_dictionary.kit.LSP.TextDocumentContentChangeEvent ({ range: cmp_dictionary.kit.LSP.Range, rangeLength?: integer, text: string } | { text: string }) + +---@alias cmp_dictionary.kit.LSP.MarkedString (string | { language: string, value: string }) + +---@alias cmp_dictionary.kit.LSP.DocumentFilter (cmp_dictionary.kit.LSP.TextDocumentFilter | cmp_dictionary.kit.LSP.NotebookCellTextDocumentFilter) + +---@alias cmp_dictionary.kit.LSP.GlobPattern (cmp_dictionary.kit.LSP.Pattern | cmp_dictionary.kit.LSP.RelativePattern) + +---@alias cmp_dictionary.kit.LSP.TextDocumentFilter ({ language: string, scheme?: string, pattern?: string } | { language?: string, scheme: string, pattern?: string } | { language?: string, scheme?: string, pattern: string }) + +---@alias cmp_dictionary.kit.LSP.NotebookDocumentFilter ({ notebookType: string, scheme?: string, pattern?: string } | { notebookType?: string, scheme: string, pattern?: string } | { notebookType?: string, scheme?: string, pattern: string }) + +---@alias cmp_dictionary.kit.LSP.Pattern string + +return LSP diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/Session.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/Session.lua new file mode 100644 index 000000000..9479361dc --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/Session.lua @@ -0,0 +1,117 @@ +---@diagnostic disable: invisible +local mpack = require('mpack') +local Async = require('cmp_dictionary.kit.Async') + +---Encode data to msgpack. +---@param v any +---@return string +local function encode(v) + if v == nil then + return mpack.encode(mpack.NIL) + end + return mpack.encode(v) +end + +---@class cmp_dictionary.kit.Thread.Server.Session +---@field private mpack_session any +---@field private reader uv.uv_pipe_t +---@field private writer uv.uv_pipe_t +---@field private _on_request table +---@field private _on_notification table +local Session = {} +Session.__index = Session + +---Create new session. +---@return cmp_dictionary.kit.Thread.Server.Session +function Session.new() + local self = setmetatable({}, Session) + self.mpack_session = mpack.Session({ unpack = mpack.Unpacker() }) + self.reader = nil + self.writer = nil + self._on_request = {} + self._on_notification = {} + return self +end + +---Connect reader/writer. +---@param reader uv.uv_pipe_t +---@param writer uv.uv_pipe_t +function Session:connect(reader, writer) + self.reader = reader + self.writer = writer + + self.reader:read_start(function(err, data) + if err then + error(err) + end + + local offset = 1 + local length = #data + while offset <= length do + local type, id_or_cb, method_or_error, params_or_result, new_offset = self.mpack_session:receive(data, offset) + if type == 'request' then + local request_id, method, params = id_or_cb, method_or_error, params_or_result + Async.resolve():next(function() + return Async.run(function() + return self._on_request[method](params) + end) + end):next(function(res) + self.writer:write(self.mpack_session:reply(request_id) .. encode(mpack.NIL) .. encode(res)) + end):catch(function(err_) + self.writer:write(self.mpack_session:reply(request_id) .. encode(err_) .. encode(mpack.NIL)) + end) + elseif type == 'notification' then + local method, params = method_or_error, params_or_result + self._on_notification[method](params) + elseif type == 'response' then + local callback, err_, res = id_or_cb, method_or_error, params_or_result + if err_ == mpack.NIL then + callback(nil, res) + else + callback(err_, nil) + end + end + offset = new_offset + end + end) +end + +---Add request handler. +---@param method string +---@param callback fun(params: table): any +function Session:on_request(method, callback) + self._on_request[method] = callback +end + +---Add notification handler. +---@param method string +---@param callback fun(params: table) +function Session:on_notification(method, callback) + self._on_notification[method] = callback +end + +---Send request to the peer. +---@param method string +---@param params table +---@return cmp_dictionary.kit.Async.AsyncTask +function Session:request(method, params) + return Async.new(function(resolve, reject) + local request = self.mpack_session:request(function(err, res) + if err then + reject(err) + else + resolve(res) + end + end) + self.writer:write(request .. encode(method) .. encode(params)) + end) +end + +---Send notification to the peer. +---@param method string +---@param params table +function Session:notify(method, params) + self.writer:write(self.mpack_session:notify() .. encode(method) .. encode(params)) +end + +return Session diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/_bootstrap.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/_bootstrap.lua new file mode 100644 index 000000000..0b63345e4 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/_bootstrap.lua @@ -0,0 +1,20 @@ +vim.o.runtimepath = _G.arg[1] + +local uv = require('luv') +local Session = require('cmp_dictionary.kit.Thread.Server.Session') + +local stdin = uv.new_pipe() +stdin:open(0) +local stdout = uv.new_pipe() +stdout:open(1) + +local session = Session.new() +session:connect(stdin, stdout) + +session:on_request('connect', function(params) + loadstring(params.dispatcher)(session) +end) + +while true do + uv.run('once') +end diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/init.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/init.lua new file mode 100644 index 000000000..e18e3f333 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/init.lua @@ -0,0 +1,111 @@ +local uv = require('luv') +local Async = require('cmp_dictionary.kit.Async') +local Session = require('cmp_dictionary.kit.Thread.Server.Session') + +---Return current executing file directory. +---@return string +local function dirname() + return debug.getinfo(2, "S").source:sub(2):match("(.*)/") +end + +---@class cmp_dictionary.kit.Thread.Server +---@field private stdin uv.uv_pipe_t +---@field private stdout uv.uv_pipe_t +---@field private stderr uv.uv_pipe_t +---@field private dispatcher fun(session: cmp_dictionary.kit.Thread.Server.Session): nil +---@field private process? uv.uv_process_t +---@field private session? cmp_dictionary.kit.Thread.Server.Session +local Server = {} +Server.__index = Server + +---Create new server instance. +---@param dispatcher fun(session: cmp_dictionary.kit.Thread.Server.Session): nil +---@return cmp_dictionary.kit.Thread.Server +function Server.new(dispatcher) + local self = setmetatable({}, Server) + self.dispatcher = dispatcher + self.session = Session.new() + self.process = nil + return self +end + +---Connect to server. +---@return cmp_dictionary.kit.Async.AsyncTask +function Server:connect() + return Async.run(function() + Async.schedule():await() + local stdin = uv.new_pipe() + local stdout = uv.new_pipe() + local stderr = uv.new_pipe() + self.process = uv.spawn('nvim', { + cwd = uv.cwd(), + args = { + '--headless', + '--noplugin', + '-l', + ('%s/_bootstrap.lua'):format(dirname()), + vim.o.runtimepath + }, + stdio = { stdin, stdout, stderr } + }) + + stderr:read_start(function(err, data) + if err then + error(err) + end + print(data) + end) + + self.session:connect(stdout, stdin) + return self.session:request('connect', { + dispatcher = string.dump(self.dispatcher) + }):await() + end) +end + +---Add request handler. +---@param method string +---@param callback fun(params: table): any +function Server:on_request(method, callback) + self.session:on_request(method, callback) +end + +---Add notification handler. +---@param method string +---@param callback fun(params: table) +function Server:on_notification(method, callback) + self.session:on_notification(method, callback) +end + +--- Send request. +---@param method string +---@param params table +function Server:request(method, params) + if not self.process then + error('Server is not connected.') + end + return self.session:request(method, params) +end + +---Send notification. +---@param method string +---@param params table +function Server:notify(method, params) + if not self.process then + error('Server is not connected.') + end + self.session:notify(method, params) +end + +---Kill server process. +function Server:kill() + if self.process then + local ok, err = self.process:kill('SIGINT') + if not ok then + error(err) + end + self.process = nil + end +end + +return Server diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Worker.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Worker.lua new file mode 100644 index 000000000..bb6749e69 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Worker.lua @@ -0,0 +1,62 @@ +local uv = require('luv') +local AsyncTask = require('cmp_dictionary.kit.Async.AsyncTask') + +---@class cmp_dictionary.kit.Thread.WorkerOption +---@field public runtimepath string[] + +local Worker = {} +Worker.__index = Worker + +---Create a new thread. +---@param runner function +function Worker.new(runner) + local self = setmetatable({}, Worker) + self.runner = string.dump(runner) + return self +end + +---Call worker function. +---@return cmp_dictionary.kit.Async.AsyncTask +function Worker:__call(...) + local args_ = { ... } + return AsyncTask.new(function(resolve, reject) + uv.new_work(function(runner, args, option) + args = vim.mpack.decode(args) + option = vim.mpack.decode(option) + + --Initialize cwd. + require('luv').chdir(option.cwd) + + --Initialize package.loaders. + table.insert(package.loaders, 2, vim._load_package) + + --Run runner function. + local ok, res = pcall(function() + return require('cmp_dictionary.kit.Async.AsyncTask').resolve(assert(loadstring(runner))(unpack(args))):sync() + end) + + res = vim.mpack.encode({ res }) + + --Return error or result. + if not ok then + return res, nil + else + return nil, res + end + end, function(err, res) + if err then + reject(vim.mpack.decode(err)[1]) + else + resolve(vim.mpack.decode(res)[1]) + end + end):queue( + self.runner, + vim.mpack.encode(args_), + vim.mpack.encode({ + cwd = uv.cwd(), + }) + ) + end) +end + +return Worker diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/Keymap.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/Keymap.lua new file mode 100644 index 000000000..c1e26eac7 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/Keymap.lua @@ -0,0 +1,88 @@ +local kit = require('cmp_dictionary.kit') +local Async = require('cmp_dictionary.kit.Async') + +---@alias cmp_dictionary.kit.Vim.Keymap.Keys { keys: string, remap: boolean } +---@alias cmp_dictionary.kit.Vim.Keymap.KeysSpecifier string|{ keys: string, remap: boolean } + +---@param keys cmp_dictionary.kit.Vim.Keymap.KeysSpecifier +---@return cmp_dictionary.kit.Vim.Keymap.Keys +local function to_keys(keys) + if type(keys) == 'table' then + return keys + end + return { keys = keys, remap = false } +end + +local Keymap = {} + +Keymap._callbacks = {} + +---Replace termcodes. +---@param keys string +---@return string +function Keymap.termcodes(keys) + return vim.api.nvim_replace_termcodes(keys, true, true, true) +end + +---Set callback for consuming next typeahead. +---@param callback fun() +---@return cmp_dictionary.kit.Async.AsyncTask +function Keymap.next(callback) + return Keymap.send(''):next(callback) +end + +---Send keys. +---@param keys cmp_dictionary.kit.Vim.Keymap.KeysSpecifier|cmp_dictionary.kit.Vim.Keymap.KeysSpecifier[] +---@param no_insert? boolean +---@return cmp_dictionary.kit.Async.AsyncTask +function Keymap.send(keys, no_insert) + local unique_id = kit.unique_id() + return Async.new(function(resolve, _) + Keymap._callbacks[unique_id] = resolve + + local callback = Keymap.termcodes(('lua require("cmp_dictionary.kit.Vim.Keymap")._resolve(%s)'):format(unique_id)) + if no_insert then + for _, keys_ in ipairs(kit.to_array(keys)) do + keys_ = to_keys(keys_) + vim.api.nvim_feedkeys(keys_.keys, keys_.remap and 'm' or 'n', true) + end + vim.api.nvim_feedkeys(callback, 'n', true) + else + vim.api.nvim_feedkeys(callback, 'in', true) + for _, keys_ in ipairs(kit.reverse(kit.to_array(keys))) do + keys_ = to_keys(keys_) + vim.api.nvim_feedkeys(keys_.keys, 'i' .. (keys_.remap and 'm' or 'n'), true) + end + end + end):catch(function() + Keymap._callbacks[unique_id] = nil + end) +end + +---Return sendabke keys with callback function. +---@param callback fun(...: any): any +---@return string +function Keymap.to_sendable(callback) + local unique_id = kit.unique_id() + Keymap._callbacks[unique_id] = Async.async(callback) + return Keymap.termcodes(('lua require("cmp_dictionary.kit.Vim.Keymap")._resolve(%s)'):format(unique_id)) +end + +---Test spec helper. +---@param spec fun(): any +function Keymap.spec(spec) + local task = Async.resolve():next(Async.async(spec)) + vim.api.nvim_feedkeys('', 'x', true) + task:sync() + collectgarbage('collect') + vim.wait(200) +end + +---Resolve running keys. +---@param unique_id integer +function Keymap._resolve(unique_id) + Keymap._callbacks[unique_id]() + Keymap._callbacks[unique_id] = nil +end + +return Keymap diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/RegExp.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/RegExp.lua new file mode 100644 index 000000000..8c16b22ef --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/RegExp.lua @@ -0,0 +1,42 @@ +local RegExp = {} + +---@type table +RegExp._cache = {} + +---Create a RegExp object. +---@param pattern string +---@return { match_str: fun(self, text: string) } +function RegExp.get(pattern) + if not RegExp._cache[pattern] then + RegExp._cache[pattern] = vim.regex(pattern) + end + return RegExp._cache[pattern] +end + +---Grep and substitute text. +---@param text string +---@param pattern string +---@param replacement string +---@return string +function RegExp.gsub(text, pattern, replacement) + return vim.fn.substitute(text, pattern, replacement, 'g') +end + +---Match pattern in text for specified position. +---@param text string +---@param pattern string +---@param pos number 1-origin index +---@return string?, integer?, integer? 1-origin-index +function RegExp.extract_at(text, pattern, pos) + local before_text = text:sub(1, pos - 1) + local after_text = text:sub(pos) + local b_s, _ = RegExp.get(pattern .. '$'):match_str(before_text) + local _, a_e = RegExp.get('^' .. pattern):match_str(after_text) + if b_s or a_e then + b_s = b_s or #before_text + a_e = #before_text + (a_e or 0) + return text:sub(b_s + 1, a_e), b_s + 1, a_e + 1 + end +end + +return RegExp diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/Syntax.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/Syntax.lua new file mode 100644 index 000000000..d65f2c40c --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Vim/Syntax.lua @@ -0,0 +1,61 @@ +local kit = require('cmp_dictionary.kit') + +local Syntax = {} + +---Return the specified position is in the specified syntax. +---@param cursor { [1]: integer, [2]: integer } +---@param groups string[] +function Syntax.within(cursor, groups) + for _, group in ipairs(Syntax.get_syntax_groups(cursor)) do + if vim.tbl_contains(groups, group) then + return true + end + end + return false +end + +---Get all syntax groups for specified position. +---NOTE: This function accepts 0-origin cursor position. +---@param cursor { [1]: integer, [2]: integer } +---@return string[] +function Syntax.get_syntax_groups(cursor) + return kit.concat(Syntax.get_vim_syntax_groups(cursor), Syntax.get_treesitter_syntax_groups(cursor)) +end + +---Get vim's syntax groups for specified position. +---NOTE: This function accepts 0-origin cursor position. +---@param cursor { [1]: integer, [2]: integer } +---@return string[] +function Syntax.get_vim_syntax_groups(cursor) + local unique = {} + local groups = {} + for _, syntax_id in ipairs(vim.fn.synstack(cursor[1] + 1, cursor[2] + 1)) do + local name = vim.fn.synIDattr(vim.fn.synIDtrans(syntax_id), 'name') + if not unique[name] then + unique[name] = true + table.insert(groups, name) + end + end + for _, syntax_id in ipairs(vim.fn.synstack(cursor[1] + 1, cursor[2] + 1)) do + local name = vim.fn.synIDattr(syntax_id, 'name') + if not unique[name] then + unique[name] = true + table.insert(groups, name) + end + end + return groups +end + +---Get tree-sitter's syntax groups for specified position. +---NOTE: This function accepts 0-origin cursor position. +---@param cursor { [1]: integer, [2]: integer } +---@return string[] +function Syntax.get_treesitter_syntax_groups(cursor) + local groups = {} + for _, capture in ipairs(vim.treesitter.get_captures_at_pos(0, cursor[1], cursor[2])) do + table.insert(groups, ('@%s'):format(capture.capture)) + end + return groups +end + +return Syntax diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/kit/init.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/init.lua new file mode 100644 index 000000000..2ee890919 --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/kit/init.lua @@ -0,0 +1,213 @@ +local kit = {} + +local is_thread = vim.is_thread() + +---Create gabage collection detector. +---@param callback fun(...: any): any +---@return userdata +function kit.gc(callback) + local gc = newproxy(true) + if vim.is_thread() or os.getenv('NODE_ENV') == 'test' then + getmetatable(gc).__gc = callback + else + getmetatable(gc).__gc = vim.schedule_wrap(callback) + end + return gc +end + +---Bind arguments for function. +---@param fn fun(...: any): any +---@vararg any +---@return fun(...: any): any +function kit.bind(fn, ...) + local args = { ... } + return function(...) + return fn(unpack(args), ...) + end +end + +---Safe version of vim.schedule. +---@param fn fun(...: any): any +function kit.safe_schedule(fn) + if is_thread then + fn() + else + vim.schedule(fn) + end +end + +---Safe version of vim.schedule_wrap. +---@param fn fun(...: any): any +function kit.safe_schedule_wrap(fn) + if is_thread then + return fn + else + return vim.schedule_wrap(fn) + end +end + +---Create unique id. +---@return integer +kit.unique_id = setmetatable({ + unique_id = 0, +}, { + __call = function(self) + self.unique_id = self.unique_id + 1 + return self.unique_id + end, +}) + +---Merge two tables. +---@generic T +---NOTE: This doesn't merge array-like table. +---@param tbl1 T +---@param tbl2 T +---@return T +function kit.merge(tbl1, tbl2) + local is_dict1 = kit.is_dict(tbl1) + local is_dict2 = kit.is_dict(tbl2) + if is_dict1 and is_dict2 then + local new_tbl = {} + for k, v in pairs(tbl2) do + if tbl1[k] ~= vim.NIL then + new_tbl[k] = kit.merge(tbl1[k], v) + end + end + for k, v in pairs(tbl1) do + if tbl2[k] == nil then + if v ~= vim.NIL then + new_tbl[k] = v + else + new_tbl[k] = nil + end + end + end + return new_tbl + elseif is_dict1 and not is_dict2 then + return kit.merge(tbl1, {}) + elseif not is_dict1 and is_dict2 then + return kit.merge(tbl2, {}) + end + + if tbl1 == vim.NIL then + return nil + elseif tbl1 == nil then + return tbl2 + else + return tbl1 + end +end + +---Recursive convert value via callback function. +---@param tbl table +---@param callback fun(value: any): any +---@return table +function kit.convert(tbl, callback) + if kit.is_dict(tbl) then + local new_tbl = {} + for k, v in pairs(tbl) do + new_tbl[k] = kit.convert(v, callback) + end + return new_tbl + end + return callback(tbl) +end + +---Map array. +---@param array table +---@param fn fun(item: unknown, index: integer): unknown +---@return unknown[] +function kit.map(array, fn) + local new_array = {} + for i, item in ipairs(array) do + table.insert(new_array, fn(item, i)) + end + return new_array +end + +---Concatenate two tables. +---NOTE: This doesn't concatenate dict-like table. +---@param tbl1 table +---@param tbl2 table +---@return table +function kit.concat(tbl1, tbl2) + local new_tbl = {} + for _, item in ipairs(tbl1) do + table.insert(new_tbl, item) + end + for _, item in ipairs(tbl2) do + table.insert(new_tbl, item) + end + return new_tbl +end + +---The value to array. +---@param value any +---@return table +function kit.to_array(value) + if type(value) == 'table' then + if vim.tbl_islist(value) or vim.tbl_isempty(value) then + return value + end + end + return { value } +end + +---Check the value is array. +---@param value any +---@return boolean +function kit.is_array(value) + return not not (type(value) == 'table' and (vim.tbl_islist(value) or vim.tbl_isempty(value))) +end + +---Check the value is dict. +---@param value any +---@return boolean +function kit.is_dict(value) + return type(value) == 'table' and (not vim.tbl_islist(value) or vim.tbl_isempty(value)) +end + +---Reverse the array. +---@param array table +---@return table +function kit.reverse(array) + if not kit.is_array(array) then + error('[kit] specified value is not an array.') + end + + local new_array = {} + for i = #array, 1, -1 do + table.insert(new_array, array[i]) + end + return new_array +end + +---@generic T +---@param value T? +---@param default T +function kit.default(value, default) + if value == nil then + return default + end + return value +end + +---Get object path with default value. +---@generic T +---@param value table +---@param path integer|string|(string|integer)[] +---@param default? T +---@return T +function kit.get(value, path, default) + local result = value + for _, key in ipairs(kit.to_array(path)) do + if type(result) == 'table' then + result = result[key] + else + return default + end + end + return result or default +end + +return kit diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/lfu.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/lfu.lua new file mode 100644 index 000000000..50317ea8b --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/lfu.lua @@ -0,0 +1,132 @@ +---@class CacheNode +---@field key integer +---@field value integer +---@field freq integer +---@field prev CacheNode +---@field next CacheNode +local CacheNode = {} + +---Initialize the cache node +---@param key any +---@param value any +---@return CacheNode +function CacheNode.init(key, value) + return { + key = key, + value = value, + freq = 1, + prev = nil, + next = nil, + } +end + +---@class LinkedList +---@field head CacheNode +---@field tail CacheNode +---@field length integer +local LinkedList = {} + +---Initialize the linked list +---@return LinkedList +function LinkedList.init() + local self = {} + self.head = CacheNode.init(0, 0) -- dummy + self.tail = CacheNode.init(0, 0) -- dummy + self.head.next = self.tail + self.tail.prev = self.head + self.length = 0 + return setmetatable(self, { __index = LinkedList }) +end + +---Add node +---@param node CacheNode +function LinkedList:add(node) + node.prev = self.head + node.next = self.head.next + self.head.next = node + node.next.prev = node + self.length = self.length + 1 +end + +---Remove node +---@param node CacheNode +function LinkedList:remove(node) + node.prev.next = node.next + node.next.prev = node.prev + self.length = self.length - 1 +end + +---@class LfuCache +---@field capacity integer +---@field key2node table +---@field list_map table +---@field total_size integer +---@field min_freq integer +local LfuCache = {} + +---Initialize the cache +---@param capacity integer +---@return LfuCache +function LfuCache.init(capacity) + local self = {} + self.capacity = capacity + self.key2node = {} + self.list_map = { LinkedList.init() } + self.total_size = 0 + self.min_freq = 0 + return setmetatable(self, { __index = LfuCache }) +end + +---Add a data to the cache +---@param key any +---@param value any +function LfuCache:set(key, value) + if self.key2node[key] then + local node = self.key2node[key] + node.value = value + self:_update(node) + else + if self.total_size == self.capacity then + local last_node = self.list_map[self.min_freq].tail.prev + self.key2node[last_node.key] = nil + self.list_map[self.min_freq]:remove(last_node) + self.total_size = self.total_size - 1 + end + + local new_node = CacheNode.init(key, value) + self.key2node[key] = new_node + self.list_map[1]:add(new_node) + self.min_freq = 1 + self.total_size = self.total_size + 1 + end +end + +---Fetching a data from the cache +---@param key any +---@return any +function LfuCache:get(key) + if self.key2node[key] then + local node = self.key2node[key] + self:_update(node) + return node.value + end +end + +---Update the number of accesses to a node +---@param node CacheNode +function LfuCache:_update(node) + local cur_freq = node.freq + self.list_map[cur_freq]:remove(node) + + node.freq = cur_freq + 1 + if not self.list_map[node.freq] then + self.list_map[node.freq] = LinkedList.init() + end + self.list_map[node.freq]:add(node) + + if self.list_map[self.min_freq].length == 0 then + self.min_freq = cur_freq + 1 + end +end + +return LfuCache diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/lfu_spec.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/lfu_spec.lua new file mode 100644 index 000000000..6c1574d2e --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/lfu_spec.lua @@ -0,0 +1,28 @@ +local lfu = require("cmp_dictionary.lfu") + +local cache + +describe("Test for lfu.lua", function() + before_each(function() + cache = lfu.init(3) + end) + + it("single cache", function() + cache:set("a", 1) + assert.are.equals(1, cache:get("a")) + end) + + it("remove the least frequent cache", function() + cache:set("a", 1) + cache:set("b", 2) + cache:set("c", 3) + assert.are.equals(1, cache:get("a")) -- freq = 2 + assert.are.equals(1, cache:get("a")) -- freq = 3 + assert.are.equals(2, cache:get("b")) -- freq = 2 + assert.are.equals(3, cache:get("c")) -- freq = 2 + + cache:set("d", 4) + -- Removed the least frequent cache with the oldest accesses. + assert.is_nil(cache:get("b")) + end) +end) diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/lib/utf8.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/lib/utf8.lua new file mode 100644 index 000000000..a4507aabb --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/lib/utf8.lua @@ -0,0 +1,279 @@ +local utf8 = {} + +local bit = require("bit") -- luajit + +local band = bit.band +local bor = bit.bor +local rshift = bit.rshift +local lshift = bit.lshift + +---The pattern (a string, not a function) "[\0-\x7F\xC2-\xF4][\x80-\xBF]*", +---which matches exactly one UTF-8 byte sequence, assuming that the subject is a valid UTF-8 string. +utf8.charpattern = "[%z\x01-\x7F\xC2-\xF4][\x80-\xBF]*" + +---@param idx integer +---@param func_name string +---@param range_name string +---@return string @error message +local function create_errmsg(idx, func_name, range_name) + return string.format("bad argument #%s to '%s' (%s out of range)", idx, func_name, range_name) +end + +---Converts indexes of a string to positive numbers. +---@param str string +---@param idx integer +---@param msg string +---@return integer +local function validate_range(str, idx, msg) + idx = idx > 0 and idx or #str + idx + 1 + if idx < 0 or idx > #str then + error(msg, 2) + end + return idx +end + +---Receives zero or more integers, converts each one to its corresponding UTF-8 byte sequence +---and returns a string with the concatenation of all these sequences. +---@vararg integer +---@return string +function utf8.char(...) + local buffer = {} + for i, v in ipairs({ ... }) do + if v < 0 or v > 0x10FFFF then + error(create_errmsg(i, "char", "value"), 2) + elseif v < 0x80 then + -- single-byte + buffer[i] = string.char(v) + elseif v < 0x800 then + -- two-byte + local b1 = bor(0xC0, band(rshift(v, 6), 0x1F)) -- 110x-xxxx + local b2 = bor(0x80, band(v, 0x3F)) -- 10xx-xxxx + buffer[i] = string.char(b1, b2) + elseif v < 0x10000 then + -- three-byte + local b1 = bor(0xE0, band(rshift(v, 12), 0x0F)) -- 1110-xxxx + local b2 = bor(0x80, band(rshift(v, 6), 0x3F)) -- 10xx-xxxx + local b3 = bor(0x80, band(v, 0x3F)) -- 10xx-xxxx + buffer[i] = string.char(b1, b2, b3) + else + -- four-byte + local b1 = bor(0xF0, band(rshift(v, 18), 0x07)) -- 1111-0xxx + local b2 = bor(0x80, band(rshift(v, 12), 0x3F)) -- 10xx-xxxx + local b3 = bor(0x80, band(rshift(v, 6), 0x3F)) -- 10xx-xxxx + local b4 = bor(0x80, band(v, 0x3F)) -- 10xx-xxxx + buffer[i] = string.char(b1, b2, b3, b4) + end + end + return table.concat(buffer, "") +end + +---Returns the next one character range. +---@param s string +---@param start_pos integer +---@return integer? start_pos, integer? end_pos +local function next_char(s, start_pos) + local b1 = s:byte(start_pos) + if not b1 then + return -- for offset's #s+1 + end + + local end_pos + + if band(b1, 0x80) == 0x00 then -- single-byte (0xxx-xxxx) + return start_pos, start_pos + elseif 0xC2 <= b1 and b1 <= 0xDF then -- two-byte (range 0xC2 to 0xDF) + end_pos = start_pos + 1 + elseif band(b1, 0xF0) == 0xE0 then -- three-byte (1110-xxxx) + end_pos = start_pos + 2 + elseif 0xF0 <= b1 and b1 <= 0xF4 then -- four-byte (range 0xF0 to 0xF4) + end_pos = start_pos + 3 + else -- invalid 1st byte + return + end + + -- validate (end_pos) + if end_pos > #s then + return + end + -- validate (continuation) + for _, bn in ipairs({ s:byte(start_pos + 1, end_pos) }) do + if band(bn, 0xC0) ~= 0x80 then -- 10xx-xxxx? + return + end + end + + return start_pos, end_pos +end + +---Returns values so that the construction +--- +---for p, c in utf8.codes(s) do body end +--- +---will iterate over all UTF-8 characters in string s, with p being the position (in bytes) and c the code point of each character. +---It raises an error if it meets any invalid byte sequence. +---@param s string +---@return function iterator +function utf8.codes(s) + vim.validate({ + s = { s, "string" }, + }) + + local i = 1 + return function() + if i > #s then + return + end + + local start_pos, end_pos = next_char(s, i) + if start_pos == nil then + error("invalid UTF-8 code", 2) + end + + i = end_pos + 1 + return start_pos, s:sub(start_pos, end_pos) + end +end + +---Returns the code points (as integers) from all characters in s that start between byte position i and j (both included). +---The default for i is 1 and for j is i. +---It raises an error if it meets any invalid byte sequence. +---@param s string +---@param i? integer start position. default=1 +---@param j? integer end position. default=i +---@return integer @code point +function utf8.codepoint(s, i, j) + vim.validate({ + s = { s, "string" }, + i = { i, "number", true }, + j = { j, "number", true }, + }) + i = validate_range(s, i or 1, create_errmsg(2, "codepoint", "initial position")) + j = validate_range(s, j or i, create_errmsg(3, "codepoint", "final position")) + + local ret = {} + repeat + local char_start, char_end = next_char(s, i) + if char_start == nil then + error("invalid UTF-8 code", 2) + end + + i = char_end + 1 + + local len = char_end - char_start + 1 + if len == 1 then + -- single-byte + table.insert(ret, s:byte(char_start)) + else + -- multi-byte + local b1 = s:byte(char_start) + b1 = band(lshift(b1, len + 1), 0xFF) -- e.g. 110x-xxxx -> xxxx-x000 + b1 = lshift(b1, len * 5 - 7) -- >> len+1 and << (len-1)*6 + + local cp = 0 + for k = char_start + 1, char_end do + local bn = s:byte(k) + cp = bor(lshift(cp, 6), band(bn, 0x3F)) + end + + cp = bor(b1, cp) + table.insert(ret, cp) + end + until char_end >= j + + return unpack(ret) +end + +---Returns the number of UTF-8 characters in string s that start between positions i and j (both inclusive). +---The default for i is 1 and for j is -1. +---If it finds any invalid byte sequence, returns fail plus the position of the first invalid byte. +---@param s string +---@param i? integer start position. default=1 +---@param j? integer end position. default=-1 +---@return integer | nil +---@return integer? +function utf8.len(s, i, j) + vim.validate({ + s = { s, "string" }, + i = { i, "number", true }, + j = { j, "number", true }, + }) + i = validate_range(s, i or 1, create_errmsg(2, "len", "initial position")) + j = validate_range(s, j or -1, create_errmsg(3, "len", "final position")) + + local len = 0 + + repeat + local char_start, char_end = next_char(s, i) + if char_start == nil then + return nil, i + end + + i = char_end + 1 + len = len + 1 + until char_end >= j + + return len +end + +---Returns the position (in bytes) where the encoding of the n-th character of s (counting from position i) starts. +---A negative n gets characters before position i. +---The default for i is 1 when n is non-negative and #s+1 otherwise, so that utf8.offset(s, -n) gets the offset of the n-th character from the end of the string. +---If the specified character is neither in the subject nor right after its end, the function returns fail. +--- +---As a special case, when n is 0 the function returns the start of the encoding of the character that contains the i-th byte of s. +---@param s string +---@param n integer +---@param i? integer start position. if n >= 0, default=1, otherwise default=#s+1 +---@return integer? +function utf8.offset(s, n, i) + vim.validate({ + s = { s, "string" }, + n = { n, "number" }, + i = { i, "number", true }, + }) + + i = i or n >= 0 and 1 or #s + 1 + + if n >= 0 or i ~= #s + 1 then + i = validate_range(s, i, create_errmsg(3, "offset", "position")) + end + + if n == 0 then + for j = i, 1, -1 do + local char_start = next_char(s, j) + if char_start then + return char_start + end + end + elseif n > 0 then + if not next_char(s, i) then + error("initial position is a continuation byte", 2) + end + + for j = i, #s do + local char_start = next_char(s, j) + if char_start then + n = n - 1 + if n == 0 then + return char_start + end + end + end + else + if i ~= #s + 1 and not next_char(s, i) then + error("initial position is a continuation byte", 2) + end + + for j = i, 1, -1 do + local char_start = next_char(s, j) + if char_start then + n = n + 1 + if n == 0 then + return char_start + end + end + end + end +end + +return utf8 diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/source.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/source.lua new file mode 100644 index 000000000..8f478fbde --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/source.lua @@ -0,0 +1,125 @@ +local source = {} + +local utf8 = require("cmp_dictionary.lib.utf8") +local config = require("cmp_dictionary.config") +local caches = require("cmp_dictionary.caches") +local db = require("cmp_dictionary.db") + +function source.new() + return setmetatable({}, { __index = source }) +end + +---@return string +function source.get_keyword_pattern() + return [[\k\+]] +end + +local candidate_cache = { + req = "", + items = {}, +} + +---@param str string +---@return boolean +local function is_capital(str) + return str:find("^%u") and true or false +end + +---@param str string +---@return string +local function to_lower_first(str) + local l = str:gsub("^.", string.lower) + return l +end + +---@param str string +---@return string +local function to_upper_first(str) + local u = str:gsub("^.", string.upper) + return u +end + +---@param req string +---@param isIncomplete boolean +---@return table +function source.get_candidate(req, isIncomplete) + if candidate_cache.req == req then + return { items = candidate_cache.items, isIncomplete = isIncomplete } + end + + local items + local request = config.get("sqlite") and db.request or caches.request + items, isIncomplete = request(req, isIncomplete) + + if config.get("first_case_insensitive") then + local pre, post = to_upper_first, to_lower_first + if is_capital(req) then + pre, post = post, pre + end + for _, item in ipairs(request(pre(req), isIncomplete)) do + table.insert(items, { label = post(item.label), detail = item.detail }) + end + end + + candidate_cache.req = req + candidate_cache.items = items + + return { items = items, isIncomplete = isIncomplete } +end + +---@param request cmp.SourceCompletionApiParams +---@param callback fun(response: lsp.CompletionResponse|nil) +function source.complete(_, request, callback) + -- Clear the cache since the dictionary has been updated. + if config.get("sqlite") then + if db.is_just_updated() then + candidate_cache = {} + end + else + if caches.is_just_updated() then + candidate_cache = {} + end + end + + local exact = config.get("exact") + + ---@type string + local line = request.context.cursor_before_line + local offset = request.offset + line = line:sub(offset) + if line == "" then + return + end + + local req, isIncomplete + if exact > 0 then + local line_len = utf8.len(line) + if line_len <= exact then + req = line + isIncomplete = line_len < exact + else + local last = exact + if line_len ~= #line then + last = utf8.offset(line, exact + 1) - 1 + end + req = line:sub(1, last) + isIncomplete = false + end + else + -- must be -1 + req = line + isIncomplete = true + end + + callback(source.get_candidate(req, isIncomplete)) +end + +function source.resolve(_, completion_item, callback) + if config.get("sqlite") then + db.document(completion_item, callback) + else + require("cmp_dictionary.document")(completion_item, callback) + end +end + +return source diff --git a/bundle/cmp-dictionary/lua/cmp_dictionary/util.lua b/bundle/cmp-dictionary/lua/cmp_dictionary/util.lua new file mode 100644 index 000000000..91a21ddca --- /dev/null +++ b/bundle/cmp-dictionary/lua/cmp_dictionary/util.lua @@ -0,0 +1,118 @@ +local uv = vim.uv or vim.loop + +local M = {} + +---@param path string +---@return string buffer +function M.read_file_sync(path) + -- 292 == 0x444 + local fd = assert(uv.fs_open(path, "r", 292)) + local stat = assert(uv.fs_fstat(fd)) + local buffer = assert(uv.fs_read(fd, stat.size, 0)) + uv.fs_close(fd) + return buffer +end + +---@param list unknown[] +---@return unknown[] +local function deduplicate(list) + local set = {} + local new_list = {} + for _, v in ipairs(list) do + if not set[v] then + table.insert(new_list, v) + set[v] = true + end + end + return new_list +end + +---@return string[] +function M.get_dictionaries() + -- Workaround. vim.opt_global returns now a local value. + -- https://github.com/neovim/neovim/issues/21506 + ---@type string[] + local global = vim.split(vim.go.dictionary, ",") + ---@type string[] + local local_ = vim.opt_local.dictionary:get() + + local dict = {} + for _, al in ipairs({ global, local_ }) do + for _, d in ipairs(al) do + if vim.fn.filereadable(vim.fn.expand(d)) == 1 then + table.insert(dict, d) + end + end + end + dict = deduplicate(dict) + return dict +end + +---@param vector string[] +---@param index integer +---@param key string +---@return boolean +local function ascending_order(vector, index, key) + return vector[index] >= key +end + +---@param vector unknown[] +---@param key string +---@param cb fun(vec: unknown[], idx: integer, key: string): boolean +---@return integer +function M.binary_search(vector, key, cb) + local left = 0 + local right = #vector + local isOK = cb or ascending_order + + -- (left, right] + while right - left > 1 do + local mid = math.floor((left + right) / 2) + if isOK(vector, mid, key) then + right = mid + else + left = mid + end + end + + return right +end + +local timer = {} + +local function stop(name) + if timer[name] then + timer[name]:stop() + timer[name]:close() + timer[name] = nil + end +end + +function M.debounce(name, callback, timeout) + stop(name) + timer[name] = uv.new_timer() + timer[name]:start( + timeout, + 0, + vim.schedule_wrap(function() + stop(name) + callback() + end) + ) +end + +M.bool_fn = setmetatable({}, { + __index = function(_, key) + return function(...) + local v = vim.fn[key](...) + if not v or v == 0 or v == "" then + return false + elseif type(v) == "table" and next(v) == nil then + return false + end + return true + end + end, +}) + +return M diff --git a/bundle/cmp-dictionary/stylua.toml b/bundle/cmp-dictionary/stylua.toml new file mode 100644 index 000000000..609d7739d --- /dev/null +++ b/bundle/cmp-dictionary/stylua.toml @@ -0,0 +1,5 @@ +column_width = 100 +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 2 +quote_style = "AutoPreferDouble" diff --git a/lua/config/nvim-cmp.lua b/lua/config/nvim-cmp.lua index ce7701360..c2b7a8042 100644 --- a/lua/config/nvim-cmp.lua +++ b/lua/config/nvim-cmp.lua @@ -98,6 +98,10 @@ cmp.setup({ }, sources = cmp.config.sources({ { name = 'nvim_lsp' }, + { + name = 'dictionary', + keyword_length = 2, + }, { name = 'path' }, { name = 'neosnippet' }, }, { @@ -106,20 +110,51 @@ cmp.setup({ }) -- `/` cmdline setup. -- cmp.setup.cmdline('/', { - -- mapping = cmp.mapping.preset.cmdline(), - -- sources = { - -- { name = 'buffer' }, - -- }, +-- mapping = cmp.mapping.preset.cmdline(), +-- sources = { +-- { name = 'buffer' }, +-- }, -- }) -- `/` cmdline setup. -- cmp.setup.cmdline(':', { - -- mapping = cmp.mapping.preset.cmdline(), - -- sources = { - -- { name = 'buffer' }, - -- { name = 'path' }, - -- }, +-- mapping = cmp.mapping.preset.cmdline(), +-- sources = { +-- { name = 'buffer' }, +-- { name = 'path' }, +-- }, -- }) -- Setup lspconfig. local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities()) -- Replace with each lsp server you've enabled. + +-- for cmp dictionary +local dict = require("cmp_dictionary") + +dict.setup({ + -- The following are default values. + exact = 2, + first_case_insensitive = false, + document = false, + -- document_command = "wn %s -over", + async = true, + sqlite = false, + max_items = -1, + capacity = 5, + debug = false, +}) + + +-- dict.switcher({ + -- filetype = { + -- lua = "/path/to/lua.dict", + -- javascript = { "/path/to/js.dict", "/path/to/js2.dict" }, + -- }, + -- filepath = { + -- [".*xmake.lua"] = { "/path/to/xmake.dict", "/path/to/lua.dict" }, + -- ["%.tmux.*%.conf"] = { "/path/to/js.dict", "/path/to/js2.dict" }, + -- }, + -- spelllang = { + -- en = "/path/to/english.dict", + -- }, +-- })