diff options
Diffstat (limited to 'runtime/doc')
-rw-r--r-- | runtime/doc/api.txt | 138 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 4 | ||||
-rw-r--r-- | runtime/doc/if_lua.txt | 114 | ||||
-rw-r--r-- | runtime/doc/lsp.txt | 662 | ||||
-rw-r--r-- | runtime/doc/options.txt | 12 |
5 files changed, 926 insertions, 4 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index d6e420c427..4ed0a6aba0 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -439,6 +439,43 @@ Example: create a float with scratch buffer: > > ============================================================================== +Extended marks *api-extended-marks* + +Extended marks (extmarks) represent buffer annotations that track text changes +in the buffer. They could be used to represent cursors, folds, misspelled +words, and anything else that needs to track a logical location in the buffer +over time. + +Example: + +We will set an extmark at the first row and third column. |api-indexing| is +zero-indexed, so we use row=0 and column=2. Passing id=0 creates a new mark +and returns the id: > + + let g:mark_ns = nvim_create_namespace('myplugin') + let g:mark_id = nvim_buf_set_extmark(0, g:mark_ns, 0, 0, 2, {}) + +We can get a mark by its id: > + + echo nvim_buf_get_extmark_by_id(0, g:mark_ns, g:mark_id) + => [0, 2] + +We can get all marks in a buffer for our namespace (or by a range): > + + echo nvim_buf_get_extmarks(0, g:mark_ns, 0, -1, -1) + => [[1, 0, 2]] + +Deleting all text surrounding an extmark does not remove the extmark. To +remove an extmark use |nvim_buf_del_extmark()|. + +Namespaces allow your plugin to manage only its own extmarks, ignoring those +created by another plugin. + +Extmark positions changed by an edit will be restored on undo/redo. Creating +and deleting extmarks is not a buffer change, thus new undo states are not +created for extmark changes. + +============================================================================== Global Functions *api-global* nvim_command({command}) *nvim_command()* @@ -1747,6 +1784,86 @@ nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()* Return: ~ (row, col) tuple + *nvim_buf_get_extmark_by_id()* +nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}) + Returns position for a given extmark id + + Parameters: ~ + {buffer} The buffer handle + {namespace} a identifier returned previously with + nvim_create_namespace + {id} the extmark id + + Return: ~ + (row, col) tuple or empty list () if extmark id was absent + + *nvim_buf_get_extmarks()* +nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts}) + List extmarks in a range (inclusive) + + range ends can be specified as (row, col) tuples, as well as + extmark ids in the same namespace. In addition, 0 and -1 works + as shorthands for (0,0) and (-1,-1) respectively, so that all + marks in the buffer can be quieried as: + + all_marks = nvim_buf_get_extmarks(0, my_ns, 0, -1, -1) + + If end is a lower position than start, then the range will be + traversed backwards. This is mostly used with limited amount, + to be able to get the first marks prior to a given position. + + Parameters: ~ + {buffer} The buffer handle + {ns_id} An id returned previously from + nvim_create_namespace + {lower} One of: extmark id, (row, col) or 0, -1 for + buffer ends + {upper} One of: extmark id, (row, col) or 0, -1 for + buffer ends + {opts} additional options. Supports the keys: + • amount: Maximum number of marks to return + + Return: ~ + [[extmark_id, row, col], ...] + + *nvim_buf_set_extmark()* +nvim_buf_set_extmark({buffer}, {ns_id}, {id}, {line}, {col}, {opts}) + Create or update an extmark at a position + + If an invalid namespace is given, an error will be raised. + + To create a new extmark, pass in id=0. The new extmark id will + be returned. To move an existing mark, pass in its id. + + It is also allowed to create a new mark by passing in a + previously unused id, but the caller must then keep track of + existing and unused ids itself. This is mainly useful over + RPC, to avoid needing to wait for the return value. + + Parameters: ~ + {buffer} The buffer handle + {ns_id} a identifier returned previously with + nvim_create_namespace + {id} The extmark's id or 0 to create a new mark. + {row} The row to set the extmark to. + {col} The column to set the extmark to. + {opts} Optional parameters. Currently not used. + + Return: ~ + the id of the extmark. + +nvim_buf_del_extmark({buffer}, {ns_id}, {id}) *nvim_buf_del_extmark()* + Remove an extmark + + Parameters: ~ + {buffer} The buffer handle + {ns_id} a identifier returned previously with + nvim_create_namespace + {id} The extmarks's id + + Return: ~ + true on success, false if the extmark was not found. + *nvim_buf_add_highlight()* nvim_buf_add_highlight({buffer}, {ns_id}, {hl_group}, {line}, {col_start}, {col_end}) @@ -1842,6 +1959,27 @@ nvim_buf_set_virtual_text({buffer}, {ns_id}, {line}, {chunks}, {opts}) Return: ~ The ns_id that was used +nvim_buf_get_virtual_text({buffer}, {lnum}) *nvim_buf_get_virtual_text()* + Get the virtual text (annotation) for a buffer line. + + The virtual text is returned as list of lists, whereas the + inner lists have either one or two elements. The first element + is the actual text, the optional second element is the + highlight group. + + The format is exactly the same as given to + nvim_buf_set_virtual_text(). + + If there is no virtual text associated with the given line, an + empty list is returned. + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {line} Line to get the virtual text from (zero-indexed) + + Return: ~ + List of virtual text chunks + nvim__buf_stats({buffer}) *nvim__buf_stats()* TODO: Documentation diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 1eb873a5b4..79bf81dc0e 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1737,6 +1737,10 @@ v:lnum Line number for the 'foldexpr' |fold-expr|, 'formatexpr' and expressions is being evaluated. Read-only when in the |sandbox|. + *v:lua* *lua-variable* +v:lua Prefix for calling lua functions from expressions. + See |v:lua-call| for more information. + *v:mouse_win* *mouse_win-variable* v:mouse_win Window number for a mouse click obtained with |getchar()|. First window has number 1, like with |winnr()|. The value is diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index 97d851a20f..911197acd4 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -327,6 +327,38 @@ Return value is also always converted. When converting, |msgpack-special-dict|s are treated specially. ============================================================================== +v:lua function calls *v:lua-call* + +The special prefix `v:lua` can be used in vimL expressions to call lua +functions which are global or nested inside global tables. The expression +`v:lua.func(arg1, arg2)` is equivalent to executing the lua code +`return func(...)` where the args have been converted to lua values. In addition +`v:lua.somemod.func(args)` will work like `return somemod.func(...)` . + +`v:lua` can also be used in function options like 'omnifunc'. As an +example, consider the following lua implementation of an omnifunc: > + + function mymod.omnifunc(findstart, base) + if findstart == 1 then + return 0 + else + return {'stuff', 'steam', 'strange things'} + end + end + vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc') + +A limitation is that the plugin module ("mymod" in this case) must +be made available as a global. + +Note: `v:lua` without a call is not allowed in a vimL expression. Funcrefs +to lua functions cannot be created. The following are errors: > + + let g:Myvar = v:lua.myfunc + call SomeFunc(v:lua.mycallback) + let g:foo = v:lua + let g:foo = v:['lua'] + +============================================================================== Lua standard modules *lua-stdlib* The Nvim Lua "standard library" (stdlib) is the `vim` module, which exposes @@ -587,6 +619,26 @@ vim.in_fast_event() *vim.in_fast_event()* for input. When this is `false` most API functions are callable (but may be subject to other restrictions such as |textlock|). +vim.NIL *vim.NIL* + Special value used to represent NIL in msgpack-rpc and |v:null| in + vimL interaction, and similar cases. Lua `nil` cannot be used as + part of a lua table representing a Dictionary or Array, as it + is equivalent to a missing value: `{"foo", nil}` is the same as + `{"foo"}` + +vim.rpcnotify({channel}, {method}[, {args}...]) *vim.rpcnotify()* + Sends {event} to {channel} via |RPC| and returns immediately. + If {channel} is 0, the event is broadcast to all channels. + + This function also works in a fast callback |lua-loop-callbacks|. + +vim.rpcrequest({channel}, {method}[, {args}...]) *vim.rpcrequest()* + Sends a request to {channel} to invoke {method} via + |RPC| and blocks until a response is received. + + Note: NIL values as part of the return value is represented as + |vim.NIL| special value + vim.stricmp({a}, {b}) *vim.stricmp()* Compares strings case-insensitively. Returns 0, 1 or -1 if strings are equal, {a} is greater than {b} or {a} is lesser than {b}, @@ -624,6 +676,9 @@ vim.fn.{func}({...}) *vim.fn* be represented directly as a Lua number. Empty lists and dictionaries both are represented by an empty table. + Note: |v:null| values as part of the return value is represented as + |vim.NIL| special value + Note: vim.fn keys are generated lazily, thus `pairs(vim.fn)` only enumerates functions that were called at least once. @@ -824,4 +879,63 @@ pesc({s}) *vim.pesc()* See also: ~ https://github.com/rxi/lume +validate({opt}) *vim.validate()* + Validates a parameter specification (types and values). + + Usage example: > + + function user.new(name, age, hobbies) + vim.validate{ + name={name, 'string'}, + age={age, 'number'}, + hobbies={hobbies, 'table'}, + } + ... + end +< + + Examples with explicit argument values (can be run directly): > + + vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}} + => NOP (success) +< +> + vim.validate{arg1={1, 'table'}} + => error('arg1: expected table, got number') +< +> + vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} + => error('arg1: expected even number, got 3') +< + + Parameters: ~ + {opt} Map of parameter names to validations. Each key is + a parameter name; each value is a tuple in one of + these forms: + 1. (arg_value, type_name, optional) + • arg_value: argument value + • type_name: string type name, one of: ("table", + "t", "string", "s", "number", "n", "boolean", + "b", "function", "f", "nil", "thread", + "userdata") + • optional: (optional) boolean, if true, `nil` + is valid + + 2. (arg_value, fn, msg) + • arg_value: argument value + • fn: any function accepting one argument, + returns true if and only if the argument is + valid + • msg: (optional) error string if validation + fails + +is_callable({f}) *vim.is_callable()* + Returns true if object `f` can be called as a function. + + Parameters: ~ + {f} Any object + + Return: ~ + true if `f` is callable, else false + vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt new file mode 100644 index 0000000000..26850b3683 --- /dev/null +++ b/runtime/doc/lsp.txt @@ -0,0 +1,662 @@ +*lsp.txt* The Language Server Protocol + + NVIM REFERENCE MANUAL + + +Neovim Language Server Protocol (LSP) API + +Neovim exposes a powerful API that conforms to Microsoft's published Language +Server Protocol specification. The documentation can be found here: + + https://microsoft.github.io/language-server-protocol/ + + +================================================================================ + *lsp-api* + +Neovim exposes a API for the language server protocol. To get the real benefits +of this API, a language server must be installed. +Many examples can be found here: + + https://microsoft.github.io/language-server-protocol/implementors/servers/ + +After installing a language server to your machine, you must let Neovim know +how to start and interact with that language server. + +To do so, you can either: +- Use the |vim.lsp.add_filetype_config()|, which solves the common use-case of + a single server for one or more filetypes. This can also be used from vim + via |lsp#add_filetype_config()|. +- Or |vim.lsp.start_client()| and |vim.lsp.buf_attach_client()|. These are the + backbone of the LSP API. These are easy to use enough for basic or more + complex configurations such as in |lsp-advanced-js-example|. + +================================================================================ + *lsp-filetype-config* + +These are utilities specific to filetype based configurations. + + *lsp#add_filetype_config()* + *vim.lsp.add_filetype_config()* +lsp#add_filetype_config({config}) for Vim. +vim.lsp.add_filetype_config({config}) for Lua + + These are functions which can be used to create a simple configuration which + will start a language server for a list of filetypes based on the |FileType| + event. + It will lazily start start the server, meaning that it will only start once + a matching filetype is encountered. + + The {config} options are the same as |vim.lsp.start_client()|, but + with a few additions and distinctions: + + Additional parameters:~ + `filetype` + {string} or {list} of filetypes to attach to. + `name` + A unique identifying string among all other servers configured with + |vim.lsp.add_filetype_config|. + + Differences:~ + `root_dir` + Will default to |getcwd()| instead of being required. + + NOTE: the function options in {config} like {config.on_init} are for Lua + callbacks, not Vim callbacks. +> + " Go example + call lsp#add_filetype_config({ + \ 'filetype': 'go', + \ 'name': 'gopls', + \ 'cmd': 'gopls' + \ }) + " Python example + call lsp#add_filetype_config({ + \ 'filetype': 'python', + \ 'name': 'pyls', + \ 'cmd': 'pyls' + \ }) + " Rust example + call lsp#add_filetype_config({ + \ 'filetype': 'rust', + \ 'name': 'rls', + \ 'cmd': 'rls', + \ 'capabilities': { + \ 'clippy_preference': 'on', + \ 'all_targets': v:false, + \ 'build_on_save': v:true, + \ 'wait_to_build': 0 + \ }}) +< +> + -- From Lua + vim.lsp.add_filetype_config { + name = "clangd"; + filetype = {"c", "cpp"}; + cmd = "clangd -background-index"; + capabilities = { + offsetEncoding = {"utf-8", "utf-16"}; + }; + on_init = vim.schedule_wrap(function(client, result) + if result.offsetEncoding then + client.offset_encoding = result.offsetEncoding + end + end) + } +< + *vim.lsp.copy_filetype_config()* +vim.lsp.copy_filetype_config({existing_name}, [{override_config}]) + + You can use this to copy an existing filetype configuration and change it by + specifying {override_config} which will override any properties in the + existing configuration. If you don't specify a new unique name with + {override_config.name} then it will try to create one and return it. + + Returns:~ + `name` the new configuration name. + + *vim.lsp.get_filetype_client_by_name()* +vim.lsp.get_filetype_client_by_name({name}) + + Use this to look up a client by its name created from + |vim.lsp.add_filetype_config()|. + + Returns nil if the client is not active or the name is not valid. + +================================================================================ + *lsp-core-api* +These are the core api functions for working with clients. You will mainly be +using |vim.lsp.start_client()| and |vim.lsp.buf_attach_client()| for operations +and |vim.lsp.get_client_by_id()| to retrieve a client by its id after it has +initialized (or {config.on_init}. see below) + + *vim.lsp.start_client()* + +vim.lsp.start_client({config}) + + The main function used for starting clients. + Start a client and initialize it. + + Its arguments are passed via a configuration object {config}. + + Mandatory parameters:~ + + `root_dir` + {string} specifying the directory where the LSP server will base + as its rootUri on initialization. + + `cmd` + {string} or {list} which is the base command to execute for the LSP. A + string will be run using |'shell'| and a list will be interpreted as a + bare command with arguments passed. This is the same as |jobstart()|. + + Optional parameters:~ + + `cmd_cwd` + {string} specifying the directory to launch the `cmd` process. This is not + related to `root_dir`. + By default, |getcwd()| is used. + + `cmd_env` + {table} specifying the environment flags to pass to the LSP on spawn. + This can be specified using keys like a map or as a list with `k=v` pairs + or both. Non-string values are coerced to a string. + For example: + `{ "PRODUCTION=true"; "TEST=123"; PORT = 8080; HOST = "0.0.0.0"; }` + + `capabilities` + A {table} which will be used instead of + `vim.lsp.protocol.make_client_capabilities()` which contains neovim's + default capabilities and passed to the language server on initialization. + You'll probably want to use make_client_capabilities() and modify the + result. + NOTE: + To send an empty dictionary, you should use + `{[vim.type_idx]=vim.types.dictionary}` Otherwise, it will be encoded as + an array. + + `callbacks` + A {table} of whose keys are language server method names and the values + are `function(err, method, params, client_id)` See |lsp-callbacks| for + more. This will be combined with |lsp-builtin-callbacks| to provide + defaults. + + `init_options` + A {table} of values to pass in the initialization request as + `initializationOptions`. See the `initialize` in the LSP spec. + + `name` + A {string} used in log messages. Defaults to {client_id} + + `offset_encoding` + One of "utf-8", "utf-16", or "utf-32" which is the encoding that the LSP + server expects. + The default encoding for Language Server Protocol is UTF-16, but there are + language servers which may use other encodings. + By default, it is "utf-16" as specified in the LSP specification. The + client does not verify this is correct. + + `on_error(code, ...)` + A function for handling errors thrown by client operation. {code} is a + number describing the error. Other arguments may be passed depending on + the error kind. See |vim.lsp.client_errors| for possible errors. + `vim.lsp.client_errors[code]` can be used to retrieve a human + understandable string. + + `on_init(client, initialize_result)` + A function which is called after the request `initialize` is completed. + `initialize_result` contains `capabilities` and anything else the server + may send. For example, `clangd` sends `initialize_result.offsetEncoding` + if `capabilities.offsetEncoding` was sent to it. You can *only* modify the + `client.offset_encoding` here before any notifications are sent. + + `on_attach(client, bufnr)` + A function which is called after the client is attached to a buffer. + + `on_exit(code, signal, client_id)` + A function which is called after the client has exited. code is the exit + code of the process, and signal is a number describing the signal used to + terminate (if any). + + `trace` + "off" | "messages" | "verbose" | nil passed directly to the language + server in the initialize request. + Invalid/empty values will default to "off" + + Returns:~ + {client_id} + You can use |vim.lsp.get_client_by_id()| to get the actual client object. + See |lsp-client| for what the client structure will be. + + NOTE: The client is only available *after* it has been initialized, which + may happen after a small delay (or never if there is an error). For this + reason, you may want to use `on_init` to do any actions once the client has + been initialized. + + *lsp-client* + +The client object has some methods and members related to using the client. + + Methods:~ + + `request(method, params, [callback])` + Send a request to the server. If callback is not specified, it will use + {client.callbacks} to try to find a callback. If one is not found there, + then an error will occur. + This is a thin wrapper around {client.rpc.request} with some additional + checking. + Returns a boolean to indicate if the notification was successful. If it + is false, then it will always be false (the client has shutdown). + If it was successful, then it will return the request id as the second + result. You can use this with `notify("$/cancel", { id = request_id })` + to cancel the request. This helper is made automatically with + |vim.lsp.buf_request()| + Returns: status, [client_id] + + `notify(method, params)` + This is just {client.rpc.notify}() + Returns a boolean to indicate if the notification was successful. If it + is false, then it will always be false (the client has shutdown). + Returns: status + + `cancel_request(id)` + This is just {client.rpc.notify}("$/cancelRequest", { id = id }) + Returns the same as `notify()`. + + `stop([force])` + Stop a client, optionally with force. + By default, it will just ask the server to shutdown without force. + If you request to stop a client which has previously been requested to + shutdown, it will automatically escalate and force shutdown. + + `is_stopped()` + Returns true if the client is fully stopped. + + Members: ~ + `id` (number) + The id allocated to the client. + + `name` (string) + If a name is specified on creation, that will be used. Otherwise it is + just the client id. This is used for logs and messages. + + `offset_encoding` (string) + The encoding used for communicating with the server. You can modify this + in the `on_init` method before text is sent to the server. + + `callbacks` (table) + The callbacks used by the client as described in |lsp-callbacks|. + + `config` (table) + A copy of the table that was passed by the user to + |vim.lsp.start_client()|. + + `server_capabilities` (table) + The response from the server sent on `initialize` describing the + server's capabilities. + + `resolved_capabilities` (table) + A normalized table of capabilities that we have detected based on the + initialize response from the server in `server_capabilities`. + + + *vim.lsp.buf_attach_client()* +vim.lsp.buf_attach_client({bufnr}, {client_id}) + + Implements the `textDocument/did*` notifications required to track a buffer + for any language server. + + Without calling this, the server won't be notified of changes to a buffer. + + *vim.lsp.get_client_by_id()* +vim.lsp.get_client_by_id({client_id}) + + Look up an active client by its id, returns nil if it is not yet initialized + or is not a valid id. Returns |lsp-client| + + *vim.lsp.stop_client()* +vim.lsp.stop_client({client_id}, [{force}]) + + Stop a client, optionally with force. + By default, it will just ask the server to shutdown without force. + If you request to stop a client which has previously been requested to + shutdown, it will automatically escalate and force shutdown. + + You can also use `client.stop()` if you have access to the client. + + *vim.lsp.stop_all_clients()* +vim.lsp.stop_all_clients([{force}]) + + |vim.lsp.stop_client()|, but for all active clients. + + *vim.lsp.get_active_clients()* +vim.lsp.get_active_clients() + + Return a list of all of the active clients. See |lsp-client| for a + description of what a client looks like. + + *vim.lsp.rpc_response_error()* +vim.lsp.rpc_response_error({code}, [{message}], [{data}]) + + Helper function to create an RPC response object/table. This is an alias for + |vim.lsp.rpc.rpc_response_error|. Code must be an RPC error code as + described in `vim.lsp.protocol.ErrorCodes`. + + You can describe an optional {message} string or arbitrary {data} to send to + the server. + +================================================================================ + *vim.lsp.builtin_callbacks* + +The |vim.lsp.builtin_callbacks| table contains the default |lsp-callbacks| +that are used when creating a new client. The keys are the LSP method names. + +The following requests and notifications have built-in callbacks defined to +handle the response in an idiomatic way. + + textDocument/completion + textDocument/declaration + textDocument/definition + textDocument/hover + textDocument/implementation + textDocument/rename + textDocument/signatureHelp + textDocument/typeDefinition + window/logMessage + window/showMessage + +You can check these via `vim.tbl_keys(vim.lsp.builtin_callbacks)`. + +These will be automatically used and can be overridden by users (either by +modifying the |vim.lsp.builtin_callbacks| object or on a per-client basis +by passing in a table via the {callbacks} parameter on |vim.lsp.start_client| +or |vim.lsp.add_filetype_config|. + +More information about callbacks can be found in |lsp-callbacks|. + +================================================================================ + *lsp-callbacks* + +Callbacks are functions which are called in a variety of situations by the +client. Their signature is `function(err, method, params, client_id)` They can +be set by the {callbacks} parameter for |vim.lsp.start_client| and +|vim.lsp.add_filetype_config| or via the |vim.lsp.builtin_callbacks|. + +This will be called for: +- notifications from the server, where `err` will always be `nil` +- requests initiated by the server. The parameter `err` will be `nil` here as + well. + For these, you can respond by returning two values: `result, err` The + err must be in the format of an RPC error, which is + `{ code, message, data? }` + You can use |vim.lsp.rpc_response_error()| to help with creating this object. +- as a callback for requests initiated by the client if the request doesn't + explicitly specify a callback (such as in |vim.lsp.buf_request|). + +================================================================================ + *vim.lsp.protocol* +vim.lsp.protocol + + Contains constants as described in the Language Server Protocol + specification and helper functions for creating protocol related objects. + + https://github.com/microsoft/language-server-protocol/raw/gh-pages/_specifications/specification-3-14.md + + Useful examples are `vim.lsp.protocol.ErrorCodes`. These objects allow + reverse lookup by either the number or string name. + + e.g. vim.lsp.protocol.TextDocumentSyncKind.Full == 1 + vim.lsp.protocol.TextDocumentSyncKind[1] == "Full" + + Utility functions used internally are: + `vim.lsp.make_client_capabilities()` + Make a ClientCapabilities object. These are the builtin + capabilities. + `vim.lsp.make_text_document_position_params()` + Make a TextDocumentPositionParams object. + `vim.lsp.resolve_capabilities(server_capabilites)` + Creates a normalized object describing capabilities from the server + capabilities. + +================================================================================ + *vim.lsp.util* + +TODO: Describe the utils here for handling/applying things from LSP. + +================================================================================ + *lsp-buf-methods* +There are methods which operate on the buffer level for all of the active +clients attached to the buffer. + + *vim.lsp.buf_request()* +vim.lsp.buf_request({bufnr}, {method}, {params}, [{callback}]) + Send a async request for all the clients active and attached to the buffer. + + Parameters: ~ + {bufnr}: The buffer handle or 0 for the current buffer. + + {method}: The LSP method name. + + {params}: The parameters to send. + + {callback}: An optional `function(err, method, params, client_id)` which + will be called for this request. If you do not specify it, then it will + use the client's callback in {client.callbacks}. See |lsp-callbacks| for + more information. + + Returns:~ + + A table from client id to the request id for all of the successful + requests. + + The second result is a function which can be used to cancel all the + requests. You can do this individually with `client.cancel_request()` + + *vim.lsp.buf_request_sync()* +vim.lsp.buf_request_sync({bufnr}, {method}, {params}, [{timeout_ms}]) + Calls |vim.lsp.buf_request()|, but it will wait for the result and block Vim + in the process. + The parameters are the same as |vim.lsp.buf_request()|, but the return + result is different. + It will wait maximum of {timeout_ms} which defaults to 100ms. + + Returns:~ + + If the timeout is exceeded or a cancel is sent or an error, it will cancel + the request and return `nil, err` where `err` is a string that describes + the reason why it failed. + + If it is successful, it will return a table from client id to result id. + + *vim.lsp.buf_notify()* +vim.lsp.buf_notify({bufnr}, {method}, {params}) + Send a notification to all servers on the buffer. + + Parameters: ~ + {bufnr}: The buffer handle or 0 for the current buffer. + + {method}: The LSP method name. + + {params}: The parameters to send. + +================================================================================ + *lsp-logging* + + *lsp#set_log_level()* +lsp#set_log_level({level}) + You can set the log level for language server client logging. + Possible values: "trace", "debug", "info", "warn", "error" + + Default: "warn" + + Example: `call lsp#set_log_level("debug")` + + *lsp#get_log_path()* + *vim.lsp.get_log_path()* +lsp#get_log_path() +vim.lsp.get_log_path() + Returns the path that LSP logs are written. + + *vim.lsp.log_levels* +vim.lsp.log_levels + Log level dictionary with reverse lookup as well. + + Can be used to lookup the number from the name or the name from the number. + Levels by name: 'trace', 'debug', 'info', 'warn', 'error' + Level numbers begin with 'trace' at 0 + +================================================================================ + *lsp-omnifunc* + *vim.lsp.omnifunc()* + *lsp#omnifunc* +lsp#omnifunc({findstart}, {base}) +vim.lsp.omnifunc({findstart}, {base}) + +To configure omnifunc, add the following in your init.vim: +> + set omnifunc=lsp#omnifunc + + " This is optional, but you may find it useful + autocmd CompleteDone * pclose +< +================================================================================ + *lsp-vim-functions* + +These methods can be used in mappings and are the equivalent of using the +request from lua as follows: + +> + lua vim.lsp.buf_request(0, "textDocument/hover", vim.lsp.protocol.make_text_document_position_params()) +< + + lsp#text_document_declaration() + lsp#text_document_definition() + lsp#text_document_hover() + lsp#text_document_implementation() + lsp#text_document_signature_help() + lsp#text_document_type_definition() + +> + " Example config + autocmd Filetype rust,python,go,c,cpp setl omnifunc=lsp#omnifunc + nnoremap <silent> ;dc :call lsp#text_document_declaration()<CR> + nnoremap <silent> ;df :call lsp#text_document_definition()<CR> + nnoremap <silent> ;h :call lsp#text_document_hover()<CR> + nnoremap <silent> ;i :call lsp#text_document_implementation()<CR> + nnoremap <silent> ;s :call lsp#text_document_signature_help()<CR> + nnoremap <silent> ;td :call lsp#text_document_type_definition()<CR> +< +================================================================================ + *lsp-advanced-js-example* + +For more advanced configurations where just filtering by filetype isn't +sufficient, you can use the `vim.lsp.start_client()` and +`vim.lsp.buf_attach_client()` commands to easily customize the configuration +however you please. For example, if you want to do your own filtering, or +start a new LSP client based on the root directory for if you plan to work +with multiple projects in a single session. Below is a fully working Lua +example which can do exactly that. + +The example will: +1. Check for each new buffer whether or not we want to start an LSP client. +2. Try to find a root directory by ascending from the buffer's path. +3. Create a new LSP for that root directory if one doesn't exist. +4. Attach the buffer to the client for that root directory. + +> + -- Some path manipulation utilities + local function is_dir(filename) + local stat = vim.loop.fs_stat(filename) + return stat and stat.type == 'directory' or false + end + + local path_sep = vim.loop.os_uname().sysname == "Windows" and "\\" or "/" + -- Asumes filepath is a file. + local function dirname(filepath) + local is_changed = false + local result = filepath:gsub(path_sep.."([^"..path_sep.."]+)$", function() + is_changed = true + return "" + end) + return result, is_changed + end + + local function path_join(...) + return table.concat(vim.tbl_flatten {...}, path_sep) + end + + -- Ascend the buffer's path until we find the rootdir. + -- is_root_path is a function which returns bool + local function buffer_find_root_dir(bufnr, is_root_path) + local bufname = vim.api.nvim_buf_get_name(bufnr) + if vim.fn.filereadable(bufname) == 0 then + return nil + end + local dir = bufname + -- Just in case our algo is buggy, don't infinite loop. + for _ = 1, 100 do + local did_change + dir, did_change = dirname(dir) + if is_root_path(dir, bufname) then + return dir, bufname + end + -- If we can't ascend further, then stop looking. + if not did_change then + return nil + end + end + end + + -- A table to store our root_dir to client_id lookup. We want one LSP per + -- root directory, and this is how we assert that. + local javascript_lsps = {} + -- Which filetypes we want to consider. + local javascript_filetypes = { + ["javascript.jsx"] = true; + ["javascript"] = true; + ["typescript"] = true; + ["typescript.jsx"] = true; + } + + -- Create a template configuration for a server to start, minus the root_dir + -- which we will specify later. + local javascript_lsp_config = { + name = "javascript"; + cmd = { path_join(os.getenv("JAVASCRIPT_LANGUAGE_SERVER_DIRECTORY"), "lib", "language-server-stdio.js") }; + } + + -- This needs to be global so that we can call it from the autocmd. + function check_start_javascript_lsp() + local bufnr = vim.api.nvim_get_current_buf() + -- Filter which files we are considering. + if not javascript_filetypes[vim.api.nvim_buf_get_option(bufnr, 'filetype')] then + return + end + -- Try to find our root directory. We will define this as a directory which contains + -- node_modules. Another choice would be to check for `package.json`, or for `.git`. + local root_dir = buffer_find_root_dir(bufnr, function(dir) + return is_dir(path_join(dir, 'node_modules')) + -- return vim.fn.filereadable(path_join(dir, 'package.json')) == 1 + -- return is_dir(path_join(dir, '.git')) + end) + -- We couldn't find a root directory, so ignore this file. + if not root_dir then return end + + -- Check if we have a client alredy or start and store it. + local client_id = javascript_lsps[root_dir] + if not client_id then + local new_config = vim.tbl_extend("error", javascript_lsp_config, { + root_dir = root_dir; + }) + client_id = vim.lsp.start_client(new_config) + javascript_lsps[root_dir] = client_id + end + -- Finally, attach to the buffer to track changes. This will do nothing if we + -- are already attached. + vim.lsp.buf_attach_client(bufnr, client_id) + end + + vim.api.nvim_command [[autocmd BufReadPost * lua check_start_javascript_lsp()]] +< + +vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 52d8624935..e64ff1b12c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1875,7 +1875,7 @@ A jump table for the options with a short description can be found at |Q_op|. security reasons. *'dip'* *'diffopt'* -'diffopt' 'dip' string (default "internal,filler") +'diffopt' 'dip' string (default "internal,filler,closeoff") global Option settings for diff mode. It can consist of the following items. All are optional. Items must be separated by a comma. @@ -1932,6 +1932,12 @@ A jump table for the options with a short description can be found at |Q_op|. vertical Start diff mode with vertical splits (unless explicitly specified otherwise). + closeoff When a window is closed where 'diff' is set + and there is only one window remaining in the + same tab page with 'diff' set, execute + `:diffoff` in that window. This undoes a + `:diffsplit` command. + hiddenoff Do not use diff mode for a buffer when it becomes hidden. @@ -2242,8 +2248,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'fileformat'* *'ff'* 'fileformat' 'ff' string (Windows default: "dos", - Unix default: "unix", - Macintosh default: "mac") + Unix default: "unix") local to buffer This gives the <EOL> of the current buffer, which is used for reading/writing the buffer from/to a file: @@ -2265,7 +2270,6 @@ A jump table for the options with a short description can be found at |Q_op|. 'fileformats' 'ffs' string (default: Vim+Vi Win32: "dos,unix", Vim Unix: "unix,dos", - Vim Mac: "mac,unix,dos", Vi others: "") global This gives the end-of-line (<EOL>) formats that will be tried when |