aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/doc/api.txt140
-rw-r--r--runtime/doc/builtin.txt188
-rw-r--r--runtime/doc/deprecated.txt13
-rw-r--r--runtime/doc/eval.txt12
-rw-r--r--runtime/doc/lsp.txt4
-rw-r--r--runtime/doc/lua.txt12
-rw-r--r--runtime/doc/nvim_terminal_emulator.txt18
-rw-r--r--runtime/doc/ui.txt4
-rw-r--r--runtime/lua/vim/_editor.lua17
-rw-r--r--runtime/lua/vim/filetype.lua86
-rw-r--r--runtime/lua/vim/filetype/detect.lua413
-rw-r--r--runtime/lua/vim/lsp.lua5
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua42
-rw-r--r--runtime/lua/vim/lsp/log.lua81
-rw-r--r--runtime/lua/vim/lsp/util.lua2
15 files changed, 700 insertions, 337 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index ed3a838b6d..d4477df803 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -59,7 +59,7 @@ Nvim instance:
# trailing '&' which is required since Nvim won't process events while
# running a blocking command):
#
- # :!./hello.rb &
+ # :!./hello.rb &
#
# Or from another shell by setting NVIM_LISTEN_ADDRESS:
# $ NVIM_LISTEN_ADDRESS=[address] ./hello.rb
@@ -1361,69 +1361,6 @@ nvim_out_write({str}) *nvim_out_write()*
Parameters: ~
{str} Message
-nvim_parse_cmd({str}, {opts}) *nvim_parse_cmd()*
- Parse command line.
-
- Doesn't check the validity of command arguments.
-
- Attributes: ~
- |api-fast|
-
- Parameters: ~
- {str} Command line string to parse. Cannot contain "\n".
- {opts} Optional parameters. Reserved for future use.
-
- Return: ~
- Dictionary containing command information, with these
- keys:
- • cmd: (string) Command name.
- • line1: (number) Starting line of command range. Only
- applicable if command can take a range.
- • line2: (number) Final line of command range. Only
- applicable if command can take a range.
- • bang: (boolean) Whether command contains a bang (!)
- modifier.
- • args: (array) Command arguments.
- • addr: (string) Value of |:command-addr|. Uses short
- name.
- • nargs: (string) Value of |:command-nargs|.
- • nextcmd: (string) Next command if there are multiple
- commands separated by a |:bar|. Empty if there isn't a
- next command.
- • magic: (dictionary) Which characters have special
- meaning in the command arguments.
- • file: (boolean) The command expands filenames. Which
- means characters such as "%", "#" and wildcards are
- expanded.
- • bar: (boolean) The "|" character is treated as a
- command separator and the double quote character (")
- is treated as the start of a comment.
-
- • mods: (dictionary) |:command-modifiers|.
- • silent: (boolean) |:silent|.
- • emsg_silent: (boolean) |:silent!|.
- • sandbox: (boolean) |:sandbox|.
- • noautocmd: (boolean) |:noautocmd|.
- • browse: (boolean) |:browse|.
- • confirm: (boolean) |:confirm|.
- • hide: (boolean) |:hide|.
- • keepalt: (boolean) |:keepalt|.
- • keepjumps: (boolean) |:keepjumps|.
- • keepmarks: (boolean) |:keepmarks|.
- • keeppatterns: (boolean) |:keeppatterns|.
- • lockmarks: (boolean) |:lockmarks|.
- • noswapfile: (boolean) |:noswapfile|.
- • tab: (integer) |:tab|.
- • verbose: (integer) |:verbose|.
- • vertical: (boolean) |:vertical|.
- • split: (string) Split modifier string, is an empty
- string when there's no split modifier. If there is a
- split modifier it can be one of:
- • "aboveleft": |:aboveleft|.
- • "belowright": |:belowright|.
- • "topleft": |:topleft|.
- • "botright": |:botright|.
-
nvim_paste({data}, {crlf}, {phase}) *nvim_paste()*
Pastes at cursor, in any mode.
@@ -1822,6 +1759,76 @@ nvim_exec({src}, {output}) *nvim_exec()*
|execute()|
|nvim_command()|
+nvim_parse_cmd({str}, {opts}) *nvim_parse_cmd()*
+ Parse command line.
+
+ Doesn't check the validity of command arguments.
+
+ Attributes: ~
+ |api-fast|
+
+ Parameters: ~
+ {str} Command line string to parse. Cannot contain "\n".
+ {opts} Optional parameters. Reserved for future use.
+
+ Return: ~
+ Dictionary containing command information, with these
+ keys:
+ • cmd: (string) Command name.
+ • range: (number) Number of items in the command
+ |<range>|. Can be 0, 1 or 2.
+ • line1: (number) Starting line of command |<range>|. -1
+ if command cannot take a range. |<line1>|
+ • line2: (number) Final line of command |<range>|. -1 if
+ command cannot take a range. |<line2>|
+ • count: (number) Any |<count>| that was supplied to the
+ command. -1 if command cannot take a count.
+ • reg: (number) The optional command |<register>|, if
+ specified. Empty string if not specified or if command
+ cannot take a register.
+ • bang: (boolean) Whether command contains a |<bang>| (!)
+ modifier.
+ • args: (array) Command arguments.
+ • addr: (string) Value of |:command-addr|. Uses short
+ name.
+ • nargs: (string) Value of |:command-nargs|.
+ • nextcmd: (string) Next command if there are multiple
+ commands separated by a |:bar|. Empty if there isn't a
+ next command.
+ • magic: (dictionary) Which characters have special
+ meaning in the command arguments.
+ • file: (boolean) The command expands filenames. Which
+ means characters such as "%", "#" and wildcards are
+ expanded.
+ • bar: (boolean) The "|" character is treated as a
+ command separator and the double quote character (")
+ is treated as the start of a comment.
+
+ • mods: (dictionary) |:command-modifiers|.
+ • silent: (boolean) |:silent|.
+ • emsg_silent: (boolean) |:silent!|.
+ • sandbox: (boolean) |:sandbox|.
+ • noautocmd: (boolean) |:noautocmd|.
+ • browse: (boolean) |:browse|.
+ • confirm: (boolean) |:confirm|.
+ • hide: (boolean) |:hide|.
+ • keepalt: (boolean) |:keepalt|.
+ • keepjumps: (boolean) |:keepjumps|.
+ • keepmarks: (boolean) |:keepmarks|.
+ • keeppatterns: (boolean) |:keeppatterns|.
+ • lockmarks: (boolean) |:lockmarks|.
+ • noswapfile: (boolean) |:noswapfile|.
+ • tab: (integer) |:tab|.
+ • verbose: (integer) |:verbose|. -1 when omitted.
+ • vertical: (boolean) |:vertical|.
+ • split: (string) Split modifier string, is an empty
+ string when there's no split modifier. If there is a
+ split modifier it can be one of:
+ • "aboveleft": |:aboveleft|.
+ • "belowright": |:belowright|.
+ • "topleft": |:topleft|.
+ • "botright": |:botright|.
+
*nvim_parse_expression()*
nvim_parse_expression({expr}, {flags}, {highlight})
Parse a VimL expression.
@@ -2706,6 +2713,11 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts})
"hl_group" is used as highlight for the cchar
if provided, otherwise it defaults to
|hl-Conceal|.
+ • ui_watched: boolean that indicates the mark
+ should be drawn by a UI. When set, the UI will
+ receive win_extmark events. Note: the mark is
+ positioned by virt_text attributes. Can be
+ used together with virt_text.
Return: ~
Id of the created/updated extmark
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 3e75914743..a909fd0d6b 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -158,7 +158,6 @@ foldclosedend({lnum}) Number last line of fold at {lnum} if closed
foldlevel({lnum}) Number fold level at {lnum}
foldtext() String line displayed for closed fold
foldtextresult({lnum}) String text for closed fold at {lnum}
-foreground() Number bring the Vim window to the foreground
fullcommand({name}) String get full command from {name}
funcref({name} [, {arglist}] [, {dict}])
Funcref reference to function {name}
@@ -352,16 +351,6 @@ reg_recording() String get the recording register name
reltime([{start} [, {end}]]) List get time value
reltimefloat({time}) Float turn the time value into a Float
reltimestr({time}) String turn time value into a String
-remote_expr({server}, {string} [, {idvar} [, {timeout}]])
- String send expression
-remote_foreground({server}) Number bring Vim server to the foreground
-remote_peek({serverid} [, {retvar}])
- Number check for reply string
-remote_read({serverid} [, {timeout}])
- String read reply string
-remote_send({server}, {string} [, {idvar}])
- String send key sequence
-remote_startserver({name}) none become server {name}
remove({list}, {idx} [, {end}]) any/List
remove items {idx}-{end} from {list}
remove({blob}, {idx} [, {end}]) Number/Blob
@@ -395,8 +384,6 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [...]]])
List search for other end of start/end pair
searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
List search for {pattern}
-server2client({clientid}, {string})
- Number send reply string
serverlist() String get a list of available servers
setbufline({expr}, {lnum}, {text})
Number set line {lnum} to {text} in buffer
@@ -1974,7 +1961,7 @@ expand({string} [, {nosuf} [, {list}]]) *expand()*
<cword> word under the cursor
<cWORD> WORD under the cursor
<client> the {clientid} of the last received
- message |server2client()|
+ message
Modifiers:
:p expand to full path
:h head (last path component removed)
@@ -2409,14 +2396,6 @@ foldtextresult({lnum}) *foldtextresult()*
Can also be used as a |method|: >
GetLnum()->foldtextresult()
<
- *foreground()*
-foreground() Move the Vim window to the foreground. Useful when sent from
- a client to a Vim server. |remote_send()|
- On Win32 systems this might not work, the OS does not always
- allow a window to bring itself to the foreground. Use
- |remote_foreground()| instead.
- {only in the Win32 GUI and console version}
-
fullcommand({name}) *fullcommand()*
Get the full command name from a short abbreviated command
name; see |20.2| for details on command abbreviations.
@@ -4280,6 +4259,15 @@ jobstart({cmd} [, {opts}]) *jobstart()*
by CommandLineToArgvW https://msdn.microsoft.com/bb776391
unless cmd[0] is some form of "cmd.exe".
+ *jobstart-env*
+ The job environment is initialized as follows:
+ $NVIM is set to |v:servername| of the parent Nvim
+ $NVIM_LISTEN_ADDRESS is unset
+ $NVIM_LOG_FILE is unset
+ $VIM is unset
+ $VIMRUNTIME is unset
+ You can set these with the `env` option.
+
*jobstart-options*
{opts} is a dictionary with these keys:
clear_env: (boolean) `env` defines the job environment
@@ -4290,8 +4278,8 @@ jobstart({cmd} [, {opts}]) *jobstart()*
killed when Nvim exits. If the process exits
before Nvim, `on_exit` will be invoked.
env: (dict) Map of environment variable name:value
- pairs extending (or replacing if |clear_env|)
- the current environment.
+ pairs extending (or replacing with |clear_env|)
+ the current environment. |jobstart-env|
height: (number) Height of the `pty` terminal.
|on_exit|: (function) Callback invoked when the job exits.
|on_stdout|: (function) Callback invoked when the job emits
@@ -4305,8 +4293,8 @@ jobstart({cmd} [, {opts}]) *jobstart()*
platforms, this option is silently ignored.)
pty: (boolean) Connect the job to a new pseudo
terminal, and its streams to the master file
- descriptor. Then `on_stderr` is ignored,
- `on_stdout` receives all output.
+ descriptor. `on_stdout` receives all output,
+ `on_stderr` is ignored. |terminal-start|
rpc: (boolean) Use |msgpack-rpc| to communicate with
the job over stdio. Then `on_stdout` is ignored,
but `on_stderr` can still be used.
@@ -5242,9 +5230,8 @@ mode([expr]) Return a string that indicates the current mode.
! Shell or external command is executing
t Terminal mode: keys go to the job
- This is useful in the 'statusline' option or when used
- with |remote_expr()| In most other places it always returns
- "c" or "n".
+ This is useful in the 'statusline' option or RPC calls. In
+ most other places it always returns "c" or "n".
Note that in the future more modes and more specific modes may
be added. It's better not to compare the whole string but only
the leading character(s).
@@ -5964,107 +5951,6 @@ reltimestr({time}) *reltimestr()*
Can also be used as a |method|: >
reltime(start)->reltimestr()
<
- *remote_expr()* *E449*
-remote_expr({server}, {string} [, {idvar} [, {timeout}]])
- Send the {string} to {server}. The {server} argument is a
- string, also see |{server}|.
-
- The string is sent as an expression and the result is returned
- after evaluation. The result must be a String or a |List|. A
- |List| is turned into a String by joining the items with a
- line break in between (not at the end), like with join(expr,
- "\n").
-
- If {idvar} is present and not empty, it is taken as the name
- of a variable and a {serverid} for later use with
- |remote_read()| is stored there.
-
- If {timeout} is given the read times out after this many
- seconds. Otherwise a timeout of 600 seconds is used.
-
- See also |clientserver| |RemoteReply|.
- This function is not available in the |sandbox|.
- Note: Any errors will cause a local error message to be issued
- and the result will be the empty string.
-
- Variables will be evaluated in the global namespace,
- independent of a function currently being active. Except
- when in debug mode, then local function variables and
- arguments can be evaluated.
-
- Examples: >
- :echo remote_expr("gvim", "2+2")
- :echo remote_expr("gvim1", "b:current_syntax")
-<
-
-remote_foreground({server}) *remote_foreground()*
- Move the Vim server with the name {server} to the foreground.
- The {server} argument is a string, also see |{server}|.
- This works like: >
- remote_expr({server}, "foreground()")
-< Except that on Win32 systems the client does the work, to work
- around the problem that the OS doesn't always allow the server
- to bring itself to the foreground.
- Note: This does not restore the window if it was minimized,
- like foreground() does.
- This function is not available in the |sandbox|.
- {only in the Win32 GUI and the Win32 console version}
-
-
-remote_peek({serverid} [, {retvar}]) *remote_peek()*
- Returns a positive number if there are available strings
- from {serverid}. Copies any reply string into the variable
- {retvar} if specified. {retvar} must be a string with the
- name of a variable.
- Returns zero if none are available.
- Returns -1 if something is wrong.
- See also |clientserver|.
- This function is not available in the |sandbox|.
- Examples: >
- :let repl = ""
- :echo "PEEK: " .. remote_peek(id, "repl") .. ": " .. repl
-
-remote_read({serverid}, [{timeout}]) *remote_read()*
- Return the oldest available reply from {serverid} and consume
- it. Unless a {timeout} in seconds is given, it blocks until a
- reply is available.
- See also |clientserver|.
- This function is not available in the |sandbox|.
- Example: >
- :echo remote_read(id)
-<
- *remote_send()* *E241*
-remote_send({server}, {string} [, {idvar}])
- Send the {string} to {server}. The {server} argument is a
- string, also see |{server}|.
-
- The string is sent as input keys and the function returns
- immediately. At the Vim server the keys are not mapped
- |:map|.
-
- If {idvar} is present, it is taken as the name of a variable
- and a {serverid} for later use with remote_read() is stored
- there.
-
- See also |clientserver| |RemoteReply|.
- This function is not available in the |sandbox|.
-
- Note: Any errors will be reported in the server and may mess
- up the display.
- Examples: >
- :echo remote_send("gvim", ":DropAndReply " .. file, "serverid") ..
- \ remote_read(serverid)
-
- :autocmd NONE RemoteReply *
- \ echo remote_read(expand("<amatch>"))
- :echo remote_send("gvim", ":sleep 10 | echo " ..
- \ 'server2client(expand("<client>"), "HELLO")<CR>')
-<
- *remote_startserver()* *E941* *E942*
-remote_startserver({name})
- Become the server {name}. This fails if already running as a
- server, when |v:servername| is not empty.
-
remove({list}, {idx} [, {end}]) *remove()*
Without {end}: Remove the item at {idx} from |List| {list} and
return the item.
@@ -6648,21 +6534,6 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Can also be used as a |method|: >
GetPattern()->searchpos()
-server2client({clientid}, {string}) *server2client()*
- Send a reply string to {clientid}. The most recent {clientid}
- that sent a string can be retrieved with expand("<client>").
- Note:
- Returns zero for success, -1 for failure.
- This id has to be stored before the next command can be
- received. I.e. before returning from the received command and
- before calling any commands that waits for input.
- See also |clientserver|.
- Example: >
- :echo server2client(expand("<client>"), "HELLO")
-
-< Can also be used as a |method|: >
- GetClientId()->server2client(string)
-<
serverlist() *serverlist()*
Returns a list of server addresses, or empty if all servers
were stopped. |serverstart()| |serverstop()|
@@ -6672,7 +6543,9 @@ serverlist() *serverlist()*
serverstart([{address}]) *serverstart()*
Opens a socket or named pipe at {address} and listens for
|RPC| messages. Clients can send |API| commands to the address
- to control Nvim. Returns the address string.
+ to control Nvim.
+
+ Returns the address string.
If {address} does not contain a colon ":" it is interpreted as
a named pipe or Unix domain socket path.
@@ -6694,14 +6567,11 @@ serverstart([{address}]) *serverstart()*
If no address is given, it is equivalent to: >
:call serverstart(tempname())
-< |$NVIM_LISTEN_ADDRESS| is set to {address} if not already set.
-
serverstop({address}) *serverstop()*
Closes the pipe or socket at {address}.
Returns TRUE if {address} is valid, else FALSE.
- If |$NVIM_LISTEN_ADDRESS| is stopped it is unset.
If |v:servername| is stopped it is set to the next available
- address returned by |serverlist()|.
+ address in |serverlist()|.
setbufline({buf}, {lnum}, {text}) *setbufline()*
Set line {lnum} to {text} in buffer {buf}. This works like
@@ -8281,19 +8151,15 @@ tempname() *tempname()* *temp-file-name*
termopen({cmd} [, {opts}]) *termopen()*
Spawns {cmd} in a new pseudo-terminal session connected
- to the current buffer. {cmd} is the same as the one passed to
- |jobstart()|. This function fails if the current buffer is
- modified (all buffer contents are destroyed).
-
- The {opts} dict is similar to the one passed to |jobstart()|,
- but the `pty`, `width`, `height`, and `TERM` fields are
- ignored: `height`/`width` are taken from the current window
- and `$TERM` is set to "xterm-256color".
+ to the current (unmodified) buffer. Parameters and behavior
+ are the same as |jobstart()| except "pty", "width", "height",
+ and "TERM" are ignored: "height" and "width" are taken from
+ the current window.
Returns the same values as |jobstart()|.
- See |terminal| for more information.
-
-test_ functions are documented here: |test-functions-details|
+ Terminal environment is initialized as in ||jobstart-env|,
+ except $TERM is set to "xterm-256color". Full behavior is
+ described in |terminal|.
tan({expr}) *tan()*
Return the tangent of {expr}, measured in radians, as a |Float|
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index f24bf06feb..13644cf208 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -6,9 +6,8 @@
Nvim *deprecated*
-The items listed below are "deprecated". This means they will be removed in
-the future. They should not be used in new scripts, and old scripts should be
-updated.
+The items listed below are deprecated: they will be removed in the future.
+They should not be used in new scripts, and old scripts should be updated.
==============================================================================
@@ -25,8 +24,12 @@ Commands ~
*:wviminfo* Deprecated alias to |:wshada| command.
Environment Variables ~
-*$NVIM_LISTEN_ADDRESS* Deprecated in favor of |--listen|. If both are given,
- $NVIM_LISTEN_ADDRESS is ignored.
+*$NVIM_LISTEN_ADDRESS* $NVIM_LISTEN_ADDRESS is a deprecated way to set the
+ |--listen| address of Nvim, and also had a conflicting
+ purpose as a way to detect a parent Nvim (use |$NVIM|
+ for that). It is unset by |terminal| and |jobstart()|
+ (unless explicitly given by the "env" option).
+ Ignored if --listen is given.
Events ~
*BufCreate* Use |BufAdd| instead.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index c6319c717a..3fd0d96f21 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2138,9 +2138,19 @@ v:scrollstart String describing the script or function that caused the
*v:servername* *servername-variable*
v:servername Primary listen-address of the current Nvim instance, the first
item returned by |serverlist()|. Can be set by |--listen| or
- |$NVIM_LISTEN_ADDRESS| at startup. |serverstart()| |serverstop()|
+ |$NVIM_LISTEN_ADDRESS| (deprecated) at startup.
+ See also |serverstart()| |serverstop()|.
Read-only.
+ *$NVIM*
+ $NVIM is set by |terminal| and |jobstart()|, and is thus
+ a hint that the current environment is a subprocess of Nvim.
+ Example: >
+ if $NVIM
+ echo nvim_get_chan_info(v:parent)
+ endif
+
+< Note the contents of $NVIM may change in the future.
v:searchforward *v:searchforward* *searchforward-variable*
Search direction: 1 after a forward search, 0 after a
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index f55c959a03..71ff0b2be5 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -750,7 +750,9 @@ omnifunc({findstart}, {base}) *vim.lsp.omnifunc()*
set_log_level({level}) *vim.lsp.set_log_level()*
Sets the global log level for LSP logging.
- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR"
+ Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR",
+ "OFF"
+
Level numbers begin with "TRACE" at 0
Use `lsp.log_levels` for reverse lookup.
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index ed4cc77369..534a40ff4f 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -1012,6 +1012,7 @@ Log levels are one of the values defined in `vim.log.levels`:
vim.log.levels.INFO
vim.log.levels.TRACE
vim.log.levels.WARN
+ vim.log.levels.OFF
------------------------------------------------------------------------------
LUA-VIMSCRIPT BRIDGE *lua-vimscript*
@@ -1326,6 +1327,17 @@ defer_fn({fn}, {timeout}) *vim.defer_fn()*
Return: ~
timer luv timer object
+deprecate({name}, {alternative}, {version}, {plugin}) *vim.deprecate()*
+ Display a deprecation notification to the user.
+
+ Parameters: ~
+ {name} string Deprecated function.
+ {alternative} string|nil Preferred alternative function.
+ {version} string Version in which the deprecated
+ function will be removed.
+ {plugin} string|nil Plugin name that the function
+ will be removed from. Defaults to "Nvim".
+
inspect({object}, {options}) *vim.inspect()*
Return a human-readable representation of the given object.
diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt
index 0e2b048541..49e29111c6 100644
--- a/runtime/doc/nvim_terminal_emulator.txt
+++ b/runtime/doc/nvim_terminal_emulator.txt
@@ -25,23 +25,23 @@ Start *terminal-start*
There are several ways to create a terminal buffer:
-- Invoke the |:terminal| command.
-- Call the |termopen()| function.
-- Edit a file with a name matching `term://(.{-}//(\d+:)?)?\zs.*`.
- For example:
->
+- Run the |:terminal| command.
+- Call the |nvim_open_term()| or |termopen()| function.
+- Edit a "term://" buffer. Examples: >
:edit term://bash
:vsplit term://top
-<
- Note: The "term://" pattern is handled by a BufReadCmd handler, so the
- |autocmd-nested| modifier is required to use it in an autocmd. >
+
+< Note: To open a "term://" buffer from an autocmd, the |autocmd-nested|
+ modifier is required. >
autocmd VimEnter * ++nested split term://sh
-< This is only mentioned for reference; use |:terminal| instead.
+< (This is only mentioned for reference; use |:terminal| instead.)
When the terminal starts, the buffer contents are updated and the buffer is
named in the form of `term://{cwd}//{pid}:{cmd}`. This naming scheme is used
by |:mksession| to restore a terminal buffer (by restarting the {cmd}).
+The terminal environment is initialized as in |jobstart-env|.
+
==============================================================================
Input *terminal-input*
diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt
index 8014199dc5..eb12fd38a0 100644
--- a/runtime/doc/ui.txt
+++ b/runtime/doc/ui.txt
@@ -627,6 +627,10 @@ tabs.
`botline` is set to one more than the line count of the buffer, if
there are filler lines past the end.
+["win_extmark", grid, win, ns_id, mark_id, row, col]
+ Updates the position of an extmark which is currently visible in a
+ window. Only emitted if the mark has the `ui_watched` attribute.
+
==============================================================================
Popupmenu Events *ui-popupmenu*
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 8e372b806c..119467de16 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -58,6 +58,7 @@ vim.log = {
INFO = 2;
WARN = 3;
ERROR = 4;
+ OFF = 5;
}
}
@@ -735,6 +736,22 @@ function vim._cs_remote(rcid, server_addr, connect_error, args)
}
end
+--- Display a deprecation notification to the user.
+---
+---@param name string Deprecated function.
+---@param alternative string|nil Preferred alternative function.
+---@param version string Version in which the deprecated function will
+--- be removed.
+---@param plugin string|nil Plugin name that the function will be removed
+--- from. Defaults to "Nvim".
+function vim.deprecate(name, alternative, version, plugin)
+ local message = name .. ' is deprecated'
+ plugin = plugin or "Nvim"
+ message = alternative and (message .. ', use ' .. alternative .. ' instead.') or message
+ message = message .. ' See :h deprecated\nThis function will be removed in ' .. plugin .. ' version ' .. version
+ vim.notify_once(message, vim.log.levels.WARN)
+end
+
require('vim._meta')
return vim
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 911950171f..32f4f825c1 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -784,19 +784,19 @@ local extension = {
zsh = "zsh",
vala = "vala",
E = function() vim.fn["dist#ft#FTe"]() end,
- EU = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- EW = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- EX = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- EXU = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- EXW = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
+ EU = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ EW = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ EX = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ EXU = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ EXW = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
PL = function() vim.fn["dist#ft#FTpl"]() end,
- R = function() vim.fn["dist#ft#FTr"]() end,
+ R = function(path, bufnr) require("vim.filetype.detect").r(bufnr) end,
asm = function() vim.fn["dist#ft#FTasm"]() end,
bas = function() vim.fn["dist#ft#FTbas"]() end,
bi = function() vim.fn["dist#ft#FTbas"]() end,
bm = function() vim.fn["dist#ft#FTbas"]() end,
bash = function() vim.fn["dist#ft#SetFileTypeSH"]("bash") end,
- btm = function() vim.fn["dist#ft#FTbtm"]() end,
+ btm = function(path, bufnr) return require("vim.filetype.detect").btm(bufnr) end,
c = function() vim.fn["dist#ft#FTlpc"]() end,
ch = function() vim.fn["dist#ft#FTchange"]() end,
com = function() vim.fn["dist#ft#BindzoneCheck"]('dcl') end,
@@ -808,29 +808,29 @@ local extension = {
e = function() vim.fn["dist#ft#FTe"]() end,
ebuild = function() vim.fn["dist#ft#SetFileTypeSH"]("bash") end,
eclass = function() vim.fn["dist#ft#SetFileTypeSH"]("bash") end,
- ent = function() vim.fn["dist#ft#FTent"]() end,
+ ent = function(path, bufnr) return require("vim.filetype.detect").ent(bufnr) end,
env = function() vim.fn["dist#ft#SetFileTypeSH"](vim.fn.getline(1)) end,
- eu = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- ew = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- ex = function() vim.fn["dist#ft#ExCheck"]() end,
- exu = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- exw = function() vim.fn["dist#ft#EuphoriaCheck"]() end,
- frm = function() vim.fn["dist#ft#FTfrm"]() end,
+ eu = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ ew = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ ex = function(path, bufnr) return require("vim.filetype.detect").ex(bufnr) end,
+ exu = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ exw = function(path, bufnr) return require("vim.filetype.detect").euphoria(bufnr) end,
+ frm = function(path, bufnr) require("vim.filetype.detect").frm(bufnr) end,
fs = function() vim.fn["dist#ft#FTfs"]() end,
- h = function() vim.fn["dist#ft#FTheader"]() end,
+ h = function(path, bufnr) require("vim.filetype.detect").header(bufnr) end,
htm = function() vim.fn["dist#ft#FThtml"]() end,
html = function() vim.fn["dist#ft#FThtml"]() end,
i = function() vim.fn["dist#ft#FTprogress_asm"]() end,
- idl = function() vim.fn["dist#ft#FTidl"]() end,
+ idl = function(path, bufnr) require("vim.filetype.detect").idl(bufnr) end,
inc = function() vim.fn["dist#ft#FTinc"]() end,
- inp = function() vim.fn["dist#ft#Check_inp"]() end,
+ inp = function(path, bufnr) require("vim.filetype.detect").inp(bufnr) end,
ksh = function() vim.fn["dist#ft#SetFileTypeSH"]("ksh") end,
lst = function() vim.fn["dist#ft#FTasm"]() end,
m = function() vim.fn["dist#ft#FTm"]() end,
mac = function() vim.fn["dist#ft#FTasm"]() end,
- mc = function() vim.fn["dist#ft#McSetf"]() end,
+ mc = function(path, bufnr) require("vim.filetype.detect").mc(bufnr) end,
mm = function() vim.fn["dist#ft#FTmm"]() end,
- mms = function() vim.fn["dist#ft#FTmms"]() end,
+ mms = function(path, bufnr) require("vim.filetype.detect").mms(bufnr) end,
p = function() vim.fn["dist#ft#FTprogress_pascal"]() end,
patch = function(path, bufnr)
local firstline = getline(bufnr, 1)
@@ -844,22 +844,22 @@ local extension = {
pp = function() vim.fn["dist#ft#FTpp"]() end,
pro = function() vim.fn["dist#ft#ProtoCheck"]('idlang') end,
pt = function() vim.fn["dist#ft#FThtml"]() end,
- r = function() vim.fn["dist#ft#FTr"]() end,
- rdf = function() vim.fn["dist#ft#Redif"]() end,
+ r = function(path, bufnr) require("vim.filetype.detect").r(bufnr) end,
+ rdf = function(path, bufnr) require("vim.filetype.detect").redif(bufnr) end,
rules = function() vim.fn["dist#ft#FTRules"]() end,
- sc = function() vim.fn["dist#ft#FTsc"]() end,
- scd = function() vim.fn["dist#ft#FTscd"]() end,
+ sc = function(path, bufnr) require("vim.filetype.detect").sc(bufnr) end,
+ scd = function(path, bufnr) require("vim.filetype.detect").scd(bufnr) end,
sh = function() vim.fn["dist#ft#SetFileTypeSH"](vim.fn.getline(1)) end,
shtml = function() vim.fn["dist#ft#FThtml"]() end,
- sql = function() vim.fn["dist#ft#SQL"]() end,
+ sql = function(path, bufnr) require("vim.filetype.detect").sql(bufnr) end,
stm = function() vim.fn["dist#ft#FThtml"]() end,
tcsh = function() vim.fn["dist#ft#SetFileTypeShell"]("tcsh") end,
tex = function() vim.fn["dist#ft#FTtex"]() end,
- tf = function() vim.fn["dist#ft#FTtf"]() end,
- w = function() vim.fn["dist#ft#FTprogress_cweb"]() end,
- xml = function() vim.fn["dist#ft#FTxml"]() end,
- y = function() vim.fn["dist#ft#FTy"]() end,
- zsql = function() vim.fn["dist#ft#SQL"]() end,
+ tf = function(path, bufnr) require("vim.filetype.detect").tf(bufnr) end,
+ w = function(path, bufnr) require("vim.filetype.detect").progress_cweb(bufnr) end,
+ xml = function(path, bufnr) require("vim.filetype.detect").xml(bufnr) end,
+ y = function(path, bufnr) require("vim.filetype.detect").y(bufnr) end,
+ zsql = function(path, bufnr) require("vim.filetype.detect").sql(bufnr) end,
txt = function(path, bufnr)
--helpfiles match *.txt, but should have a modeline as last line
if not getline(bufnr, -1):match("vim:.*ft=help") then
@@ -933,10 +933,10 @@ local filename = {
["exim.conf"] = "exim",
exports = "exports",
[".fetchmailrc"] = "fetchmail",
- fvSchemes = function() vim.fn["dist#ft#FTfoam"]() end,
- fvSolution = function() vim.fn["dist#ft#FTfoam"]() end,
- fvConstraints = function() vim.fn["dist#ft#FTfoam"]() end,
- fvModels = function() vim.fn["dist#ft#FTfoam"]() end,
+ fvSchemes = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ fvSolution = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ fvConstraints = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ fvModels = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
fstab = "fstab",
mtab = "fstab",
[".gdbinit"] = "gdb",
@@ -1355,7 +1355,7 @@ local pattern = {
["%.zcompdump.*"] = starsetf('zsh'),
["%.zlog.*"] = starsetf('zsh'),
["%.zsh.*"] = starsetf('zsh'),
- [".*%.[1-9]"] = function() vim.fn["dist#ft#FTnroff"]() end,
+ [".*%.[1-9]"] = function(path, bufnr) return require("vim.filetype.detect").nroff(bufnr) end,
[".*%.[aA]"] = function() vim.fn["dist#ft#FTasm"]() end,
[".*%.[sS]"] = function() vim.fn["dist#ft#FTasm"]() end,
[".*%.properties_.._.._.*"] = starsetf('jproperties'),
@@ -1434,14 +1434,14 @@ local pattern = {
["mutt" .. string.rep("[%w_-]", 6)] = "mail",
["neomutt" .. string.rep("[%w_-]", 6)] = "mail",
["/tmp/SLRN[0-9A-Z.]+"] = "mail",
- ["[a-zA-Z0-9].*Dict"] = function() vim.fn["dist#ft#FTfoam"]() end,
- ["[a-zA-Z0-9].*Dict%..*"] = function() vim.fn["dist#ft#FTfoam"]() end,
- ["[a-zA-Z].*Properties"] = function() vim.fn["dist#ft#FTfoam"]() end,
- ["[a-zA-Z].*Properties%..*"] = function() vim.fn["dist#ft#FTfoam"]() end,
- [".*Transport%..*"] = function() vim.fn["dist#ft#FTfoam"]() end,
- [".*/constant/g"] = function() vim.fn["dist#ft#FTfoam"]() end,
- [".*/0/.*"] = function() vim.fn["dist#ft#FTfoam"]() end,
- [".*/0%.orig/.*"] = function() vim.fn["dist#ft#FTfoam"]() end,
+ ["[a-zA-Z0-9].*Dict"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ ["[a-zA-Z0-9].*Dict%..*"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ ["[a-zA-Z].*Properties"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ ["[a-zA-Z].*Properties%..*"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ [".*Transport%..*"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ [".*/constant/g"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ [".*/0/.*"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
+ [".*/0%.orig/.*"] = function(path, bufnr) require("vim.filetype.detect").foam(bufnr) end,
[".*/etc/sensors%.d/[^.].*"] = starsetf('sensors'),
[".*%.git/.*"] = function(path, bufnr)
local firstline = getline(bufnr, 1)
@@ -1490,7 +1490,7 @@ local function normalize_path(path, as_pattern)
if as_pattern then
-- Escape Lua's metacharacters when $HOME is used in a pattern.
-- The rest of path should already be properly escaped.
- normal = vim.env.HOME:gsub('[-^$()%%.%[%]+?]', '%%%0') .. normal:sub(2)
+ normal = vim.pesc(vim.env.HOME) .. normal:sub(2)
else
normal = vim.env.HOME .. normal:sub(2)
end
diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua
new file mode 100644
index 0000000000..787b335251
--- /dev/null
+++ b/runtime/lua/vim/filetype/detect.lua
@@ -0,0 +1,413 @@
+local M = {}
+
+---@private
+local function getlines(bufnr, start_lnum, end_lnum, opts)
+ if not end_lnum then
+ -- Return a single line as a string
+ return vim.api.nvim_buf_get_lines(bufnr, start_lnum - 1, start_lnum, false)[1]
+ end
+
+ local lines = vim.api.nvim_buf_get_lines(bufnr, start_lnum - 1, end_lnum, false)
+ opts = opts or {}
+ return opts.concat and (table.concat(lines) or "") or lines
+end
+
+---@private
+local function findany(s, patterns)
+ for _, v in ipairs(patterns) do
+ if s:find(v) then
+ return true
+ end
+ end
+ return false
+end
+
+-- luacheck: push no unused args
+-- luacheck: push ignore 122
+
+function M.asm(path, bufnr) end
+
+function M.asm_syntax(path, bufnr) end
+
+function M.bas(path, bufnr) end
+
+function M.bindzone(path, bufnr) end
+
+function M.btm(bufnr)
+ if vim.g.dosbatch_syntax_for_btm and vim.g.dosbatch_syntax_for_btm ~= 0 then
+ vim.bo[bufnr].filetype = "dosbatch"
+ else
+ vim.bo[bufnr].filetype = "btm"
+ end
+end
+
+-- Returns true if file content looks like RAPID
+local function is_rapid(bufnr, extension)
+ if extension == "cfg" then
+ local line = getlines(bufnr, 1):lower()
+ return findany(line, { "eio:cfg", "mmc:cfg", "moc:cfg", "proc:cfg", "sio:cfg", "sys:cfg" })
+ end
+ local first = "^%s*module%s+%S+%s*"
+ -- Called from mod, prg or sys functions
+ for _, line in ipairs(getlines(bufnr, 1, -1)) do
+ if not line:find("^%s*$") then
+ return findany(line:lower(), { "^%s*%%%%%%", first .. "(", first .. "$" })
+ end
+ end
+ -- Only found blank lines
+ return false
+end
+
+function M.cfg(bufnr)
+ if vim.g.filetype_cfg then
+ vim.bo[bufnr].filetype = vim.g.filetype_cfg
+ elseif is_rapid(bufnr, "cfg") then
+ vim.bo[bufnr].filetype = "rapid"
+ else
+ vim.bo[bufnr].filetype = "cfg"
+ end
+end
+
+function M.change(path, bufnr) end
+
+function M.csh(path, bufnr) end
+
+function M.dat(path, bufnr) end
+
+function M.dep3patch(path, bufnr) end
+
+function M.dtrace(path, bufnr) end
+
+function M.e(path, bufnr) end
+
+-- This function checks for valid cl syntax in the first five lines.
+-- Look for either an opening comment, '#', or a block start, '{'.
+-- If not found, assume SGML.
+function M.ent(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 5)) do
+ if line:find("^%s*[#{]") then
+ vim.bo[bufnr].filetype = "cl"
+ return
+ elseif not line:find("^%s*$") then
+ -- Not a blank line, not a comment, and not a block start,
+ -- so doesn't look like valid cl code.
+ break
+ end
+ end
+ vim.bo[bufnr].filetype = "dtd"
+end
+
+function M.euphoria(bufnr)
+ if vim.g.filetype_euphoria then
+ vim.bo[bufnr].filetype = vim.g.filetype_euphoria
+ else
+ vim.bo[bufnr].filetype = "euphoria3"
+ end
+end
+
+function M.ex(bufnr)
+ if vim.g.filetype_euphoria then
+ vim.bo[bufnr].filetype = vim.g.filetype_euphoria
+ else
+ for _, line in ipairs(getlines(bufnr, 1, 100)) do
+ -- TODO: in the Vim regex, \> is used to match the end of the word, can this be omitted?
+ if findany(line, { "^%-%-", "^ifdef", "^include" }) then
+ vim.bo[bufnr].filetype = "euphoria3"
+ return
+ end
+ end
+ vim.bo[bufnr].filetype = "elixir"
+ end
+end
+
+-- This function checks the first 15 lines for appearance of 'FoamFile'
+-- and then 'object' in a following line.
+-- In that case, it's probably an OpenFOAM file
+function M.foam(bufnr)
+ local foam_file = false
+ for _, line in ipairs(getlines(bufnr, 1, 15)) do
+ if line:find("^FoamFile") then
+ foam_file = true
+ elseif foam_file and line:find("^%s*object") then
+ vim.bo[bufnr].filetype = "foam"
+ return
+ end
+ end
+end
+
+function M.frm(bufnr)
+ if vim.g.filetype_frm then
+ vim.bo[bufnr].filetype = vim.g.filetype_frm
+ else
+ -- Always ignore case
+ local lines = getlines(bufnr, 1, 5, { concat = true }):lower()
+ if findany(lines, { "vb_name", "begin vb%.form", "begin vb%.mdiform" }) then
+ vim.bo[bufnr].filetype = "vb"
+ else
+ vim.bo[bufnr].filetype = "form"
+ end
+ end
+end
+
+function M.fs(path, bufnr) end
+
+function M.header(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 200)) do
+ if findany(line, { "^@interface", "^@end", "^@class" }) then
+ if vim.g.c_syntax_for_h then
+ vim.bo[bufnr].filetype = "objc"
+ else
+ vim.bo[bufnr].filetype = "objcpp"
+ end
+ return
+ end
+ end
+ if vim.g.c_syntax_for_h then
+ vim.bo[bufnr].filetype = "c"
+ elseif vim.g.ch_syntax_for_h then
+ vim.bo[bufnr].filetype = "ch"
+ else
+ vim.bo[bufnr].filetype = "cpp"
+ end
+end
+
+function M.idl(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 50)) do
+ -- Always ignore case
+ line = line:lower()
+ if findany(line, { '^%s*import%s+"unknwn"%.idl', '^%s*import%s+"objidl"%.idl' }) then
+ vim.bo[bufnr].filetype = "msidl"
+ return
+ end
+ end
+ vim.bo[bufnr].filetype = "idl"
+end
+
+function M.inc(path, bufnr) end
+
+function M.inp(bufnr)
+ if getlines(bufnr, 1):find("^%*") then
+ vim.bo[bufnr].filetype = "abaqus"
+ else
+ for _, line in ipairs(getlines(bufnr, 1, 500)) do
+ if line:lower():find("^header surface data") then
+ vim.bo[bufnr].filetype = "trasys"
+ return
+ end
+ end
+ end
+end
+
+function M.lpc(path, bufnr) end
+
+function M.lprolog(path, bufnr) end
+
+function M.m(path, bufnr) end
+
+-- Rely on the file to start with a comment.
+-- MS message text files use ';', Sendmail files use '#' or 'dnl'
+function M.mc(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 20)) do
+ if findany(line:lower(), { "^%s*#", "^%s*dnl" }) then
+ -- Sendmail .mc file
+ vim.bo[bufnr].filetype = "m4"
+ return
+ elseif line:find("^%s*;") then
+ vim.bo[bufnr].filetype = "msmessages"
+ return
+ end
+ end
+ -- Default: Sendmail .mc file
+ vim.bo[bufnr].filetype = "m4"
+end
+
+function M.mm(path, bufnr) end
+
+function M.mms(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 20)) do
+ if findany(line, { "^%s*%%", "^%s*//", "^%*" }) then
+ vim.bo[bufnr].filetype = "mmix"
+ return
+ elseif line:find("^%s*#") then
+ vim.bo[bufnr].filetype = "make"
+ return
+ end
+ end
+ vim.bo[bufnr].filetype = "mmix"
+end
+
+function M.mod(path, bufnr) end
+
+-- This function checks if one of the first five lines start with a dot. In
+-- that case it is probably an nroff file: 'filetype' is set and 1 is returned.
+function M.nroff(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 5)) do
+ if line:find("^%.") then
+ vim.bo[bufnr].filetype = "nroff"
+ return 1
+ end
+ end
+ return 0
+end
+
+function M.perl(path, bufnr) end
+
+function M.pl(path, bufnr) end
+
+function M.pp(path, bufnr) end
+
+function M.prg(path, bufnr) end
+
+function M.progress_asm(path, bufnr) end
+
+function M.progress_cweb(bufnr)
+ if vim.g.filetype_w then
+ vim.bo[bufnr].filetype = vim.g.filetype_w
+ else
+ if getlines(bufnr, 1):find("^&ANALYZE") or getlines(bufnr, 3):find("^&GLOBAL%-DEFINE") then
+ vim.bo[bufnr].filetype = "progress"
+ else
+ vim.bo[bufnr].filetype = "cweb"
+ end
+ end
+end
+
+function M.progress_pascal(path, bufnr) end
+
+function M.proto(path, bufnr) end
+
+function M.r(bufnr)
+ local lines = getlines(bufnr, 1, 50)
+ -- TODO: \< / \> which match the beginning / end of a word
+ -- Rebol is easy to recognize, check for that first
+ if table.concat(lines):lower():find("rebol") then
+ vim.bo[bufnr].filetype = "rebol"
+ return
+ end
+
+ for _, line in ipairs(lines) do
+ -- R has # comments
+ if line:find("^%s*#") then
+ vim.bo[bufnr].filetype = "r"
+ return
+ end
+ -- Rexx has /* comments */
+ if line:find("^%s*/%*") then
+ vim.bo[bufnr].filetype = "rexx"
+ return
+ end
+ end
+
+ -- Nothing recognized, use user default or assume R
+ if vim.g.filetype_r then
+ vim.bo[bufnr].filetype = vim.g.filetype_r
+ else
+ -- Rexx used to be the default, but R appears to be much more popular.
+ vim.bo[bufnr].filetype = "r"
+ end
+end
+
+function M.redif(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 5)) do
+ if line:lower():find("^template%-type:") then
+ vim.bo[bufnr].filetype = "redif"
+ end
+ end
+end
+
+function M.rules(path, bufnr) end
+
+-- This function checks the first 25 lines of file extension "sc" to resolve
+-- detection between scala and SuperCollider
+function M.sc(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 25)) do
+ if findany(line, { "[A-Za-z0-9]*%s:%s[A-Za-z0-9]", "var%s<", "classvar%s<", "%^this.*", "|%w*|", "%+%s%w*%s{", "%*ar%s" }) then
+ vim.bo[bufnr].filetype = "supercollider"
+ return
+ end
+ end
+ vim.bo[bufnr].filetype = "scala"
+end
+
+-- This function checks the first line of file extension "scd" to resolve
+-- detection between scdoc and SuperCollider
+function M.scd(bufnr)
+ local first = "^%S+%(%d[0-9A-Za-z]*%)"
+ local opt = [[%s+"[^"]*"]]
+ local line = getlines(bufnr, 1)
+ if findany(line, { first .. "$", first .. opt .. "$", first .. opt .. opt .. "$" }) then
+ vim.bo[bufnr].filetype = "scdoc"
+ else
+ vim.bo[bufnr].filetype = "supercollider"
+ end
+end
+
+function M.sh(path, bufnr) end
+
+function M.shell(path, bufnr) end
+
+function M.sql(bufnr)
+ if vim.g.filetype_sql then
+ vim.bo[bufnr].filetype = vim.g.filetype_sql
+ else
+ vim.bo[bufnr].filetype = "sql"
+ end
+end
+
+function M.src(path, bufnr) end
+
+function M.sys(path, bufnr) end
+
+function M.tex(path, bufnr) end
+
+-- Determine if a *.tf file is TF mud client or terraform
+function M.tf(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, -1)) do
+ -- Assume terraform file on a non-empty line (not whitespace-only)
+ -- and when the first non-whitespace character is not a ; or /
+ if not line:find("^%s*$") and not line:find("^%s*[;/]") then
+ vim.bo[bufnr].filetype = "terraform"
+ return
+ end
+ end
+ vim.bo[bufnr].filetype = "tf"
+end
+
+function M.xml(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 100)) do
+ line = line:lower()
+ local is_docbook4 = line:find("<!doctype.*docbook")
+ local is_docbook5 = line:find([[ xmlns="http://docbook.org/ns/docbook"]])
+ if is_docbook4 or is_docbook5 then
+ vim.b[bufnr].docbk_type = "xml"
+ vim.b[bufnr].docbk_ver = is_docbook4 and 4 or 5
+ vim.bo[bufnr].filetype = "docbk"
+ return
+ end
+ if line:find([[xmlns:xbl="http://www.mozilla.org/xbl"]]) then
+ vim.bo[bufnr].filetype = "xbl"
+ return
+ end
+ end
+ vim.bo[bufnr].filetype = "xml"
+end
+
+function M.y(bufnr)
+ for _, line in ipairs(getlines(bufnr, 1, 100)) do
+ if line:find("^%s*%%") then
+ vim.bo[bufnr].filetype = "yacc"
+ return
+ end
+ -- TODO: in the Vim regex, \> is used to match the end of the word after "class",
+ -- can this be omitted?
+ if findany(line, { "^%s*#", "^%class", "^%s*#%s*include" }) then
+ vim.bo[bufnr].filetype = "racc"
+ end
+ end
+ vim.bo[bufnr].filetype = "yacc"
+end
+
+-- luacheck: pop
+-- luacheck: pop
+
+return M
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 19ee75a1b6..00f1c26692 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1790,13 +1790,14 @@ end
--
-- Can be used to lookup the number from the name or the
-- name from the number.
--- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR"
+-- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
-- Level numbers begin with "TRACE" at 0
lsp.log_levels = log.levels
--- Sets the global log level for LSP logging.
---
---- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR"
+--- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
+---
--- Level numbers begin with "TRACE" at 0
---
--- Use `lsp.log_levels` for reverse lookup.
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 6a8d6dcad7..28a236cc7e 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -251,7 +251,7 @@ end
---@param client_id number
---@private
function M.save(diagnostics, bufnr, client_id)
- vim.notify_once('vim.lsp.diagnostic.save is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.save', 'vim.diagnostic.set', '0.8' )
local namespace = M.get_namespace(client_id)
vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id))
end
@@ -265,7 +265,7 @@ end
--- If nil, diagnostics of all clients are included.
---@return table with diagnostics grouped by bufnr (bufnr: Diagnostic[])
function M.get_all(client_id)
- vim.notify_once('vim.lsp.diagnostic.get_all is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_all', 'vim.diagnostic.get', '0.8' )
local result = {}
local namespace
if client_id then
@@ -287,7 +287,7 @@ end
--- Else, return just the diagnostics associated with the client_id.
---@param predicate function|nil Optional function for filtering diagnostics
function M.get(bufnr, client_id, predicate)
- vim.notify_once('vim.lsp.diagnostic.get is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get', 'vim.diagnostic.get', '0.8' )
predicate = predicate or function() return true end
if client_id == nil then
local all_diagnostics = {}
@@ -349,7 +349,7 @@ end
---@param severity DiagnosticSeverity
---@param client_id number the client id
function M.get_count(bufnr, severity, client_id)
- vim.notify_once('vim.lsp.diagnostic.get_count is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_count', 'vim.diagnostic.get', '0.8' )
severity = severity_lsp_to_vim(severity)
local opts = { severity = severity }
if client_id ~= nil then
@@ -366,7 +366,7 @@ end
---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Previous diagnostic
function M.get_prev(opts)
- vim.notify_once('vim.lsp.diagnostic.get_prev is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_prev', 'vim.diagnostic.get_prev', '0.8' )
if opts then
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -384,7 +384,7 @@ end
---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Previous diagnostic position
function M.get_prev_pos(opts)
- vim.notify_once('vim.lsp.diagnostic.get_prev_pos is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_prev_pos', 'vim.diagnostic.get_prev_pos', '0.8' )
if opts then
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -401,7 +401,7 @@ end
---
---@param opts table See |vim.lsp.diagnostic.goto_next()|
function M.goto_prev(opts)
- vim.notify_once('vim.lsp.diagnostic.goto_prev is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.goto_prev', 'vim.diagnostic.goto_prev', '0.8' )
if opts then
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -419,7 +419,7 @@ end
---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Next diagnostic
function M.get_next(opts)
- vim.notify_once('vim.lsp.diagnostic.get_next is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_next', 'vim.diagnostic.get_next', '0.8' )
if opts then
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -437,7 +437,7 @@ end
---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Next diagnostic position
function M.get_next_pos(opts)
- vim.notify_once('vim.lsp.diagnostic.get_next_pos is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_next_pos', 'vim.diagnostic.get_next_pos', '0.8' )
if opts then
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -452,7 +452,7 @@ end
---
---@deprecated Prefer |vim.diagnostic.goto_next()|
function M.goto_next(opts)
- vim.notify_once('vim.lsp.diagnostic.goto_next is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.goto_next', 'vim.diagnostic.goto_next', '0.8' )
if opts then
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -476,7 +476,7 @@ end
--- - severity_limit (DiagnosticSeverity):
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
function M.set_signs(diagnostics, bufnr, client_id, _, opts)
- vim.notify_once('vim.lsp.diagnostic.set_signs is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.set_signs', nil , '0.8' )
local namespace = M.get_namespace(client_id)
if opts and not opts.severity and opts.severity_limit then
opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
@@ -497,7 +497,7 @@ end
--- - severity_limit (DiagnosticSeverity):
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
function M.set_underline(diagnostics, bufnr, client_id, _, opts)
- vim.notify_once('vim.lsp.diagnostic.set_underline is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.set_underline', nil , '0.8' )
local namespace = M.get_namespace(client_id)
if opts and not opts.severity and opts.severity_limit then
opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
@@ -519,7 +519,7 @@ end
--- - severity_limit (DiagnosticSeverity):
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
function M.set_virtual_text(diagnostics, bufnr, client_id, _, opts)
- vim.notify_once('vim.lsp.diagnostic.set_virtual_text is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.set_virtual_text', nil , '0.8' )
local namespace = M.get_namespace(client_id)
if opts and not opts.severity and opts.severity_limit then
opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
@@ -538,7 +538,7 @@ end
---@return an array of [text, hl_group] arrays. This can be passed directly to
--- the {virt_text} option of |nvim_buf_set_extmark()|.
function M.get_virtual_text_chunks_for_line(bufnr, _, line_diags, opts)
- vim.notify_once('vim.lsp.diagnostic.get_virtual_text_chunks_for_line is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.get_virtual_text_chunks_for_line', nil, '0.8' )
return vim.diagnostic._get_virt_text_chunks(diagnostic_lsp_to_vim(line_diags, bufnr), opts)
end
@@ -556,7 +556,7 @@ end
---@param position table|nil The (0,0)-indexed position
---@return table {popup_bufnr, win_id}
function M.show_position_diagnostics(opts, buf_nr, position)
- vim.notify_once('vim.lsp.diagnostic.show_position_diagnostics is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.show_position_diagnostics', 'vim.diagnostic.open_float', '0.8' )
opts = opts or {}
opts.scope = "cursor"
opts.pos = position
@@ -580,7 +580,7 @@ end
---@param client_id number|nil the client id
---@return table {popup_bufnr, win_id}
function M.show_line_diagnostics(opts, buf_nr, line_nr, client_id)
- vim.notify_once('vim.lsp.diagnostic.show_line_diagnostics is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.show_line_diagnostics', 'vim.diagnostic.open_float', '0.8' )
opts = opts or {}
opts.scope = "line"
opts.pos = line_nr
@@ -604,7 +604,7 @@ end
--- client. The default is to redraw diagnostics for all attached
--- clients.
function M.redraw(bufnr, client_id)
- vim.notify_once('vim.lsp.diagnostic.redraw is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.redraw', 'vim.diagnostic.show', '0.8' )
bufnr = get_bufnr(bufnr)
if not client_id then
return vim.lsp.for_each_buffer_client(bufnr, function(client)
@@ -632,7 +632,7 @@ end
--- - {workspace}: (boolean, default true)
--- - Set the list with workspace diagnostics
function M.set_qflist(opts)
- vim.notify_once('vim.lsp.diagnostic.set_qflist is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.set_qflist', 'vim.diagnostic.setqflist', '0.8' )
opts = opts or {}
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -664,7 +664,7 @@ end
--- - {workspace}: (boolean, default false)
--- - Set the list with workspace diagnostics
function M.set_loclist(opts)
- vim.notify_once('vim.lsp.diagnostic.set_loclist is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.set_loclist', 'vim.diagnostic.setloclist', '0.8' )
opts = opts or {}
if opts.severity then
opts.severity = severity_lsp_to_vim(opts.severity)
@@ -692,7 +692,7 @@ end
-- send diagnostic information and the client will still process it. The
-- diagnostics are simply not displayed to the user.
function M.disable(bufnr, client_id)
- vim.notify_once('vim.lsp.diagnostic.disable is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.disable', 'vim.diagnostic.disable', '0.8' )
if not client_id then
return vim.lsp.for_each_buffer_client(bufnr, function(client)
M.disable(bufnr, client.id)
@@ -713,7 +713,7 @@ end
--- client. The default is to enable diagnostics for all attached
--- clients.
function M.enable(bufnr, client_id)
- vim.notify_once('vim.lsp.diagnostic.enable is deprecated. See :h deprecated', vim.log.levels.WARN)
+ vim.deprecate('vim.lsp.diagnostic.enable', 'vim.diagnostic.enable', '0.8' )
if not client_id then
return vim.lsp.for_each_buffer_client(bufnr, function(client)
M.enable(bufnr, client.id)
diff --git a/runtime/lua/vim/lsp/log.lua b/runtime/lua/vim/lsp/log.lua
index e0b5653587..fff42fd011 100644
--- a/runtime/lua/vim/lsp/log.lua
+++ b/runtime/lua/vim/lsp/log.lua
@@ -8,7 +8,7 @@ local log = {}
-- 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"
+-- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
-- Level numbers begin with "TRACE" at 0
log.levels = vim.deepcopy(vim.log.levels)
@@ -25,27 +25,47 @@ do
end
local logfilename = path_join(vim.fn.stdpath('cache'), 'lsp.log')
+ -- TODO: Ideally the directory should be created in open_logfile(), right
+ -- before opening the log file, but open_logfile() can be called from libuv
+ -- callbacks, where using fn.mkdir() is not allowed.
+ vim.fn.mkdir(vim.fn.stdpath('cache'), "p")
+
--- Returns the log filename.
---@returns (string) log filename
function log.get_filename()
return logfilename
end
- vim.fn.mkdir(vim.fn.stdpath('cache'), "p")
- local logfile = assert(io.open(logfilename, "a+"))
-
- local log_info = vim.loop.fs_stat(logfilename)
- if log_info and log_info.size > 1e9 then
- local warn_msg = string.format(
- "LSP client log is large (%d MB): %s",
- log_info.size / (1000 * 1000),
- logfilename
- )
- vim.notify(warn_msg)
+ local logfile, openerr
+ ---@private
+ --- Opens log file. Returns true if file is open, false on error
+ local function open_logfile()
+ -- Try to open file only once
+ if logfile then return true end
+ if openerr then return false end
+
+ logfile, openerr = io.open(logfilename, "a+")
+ if not logfile then
+ local err_msg = string.format("Failed to open LSP client log file: %s", openerr)
+ vim.notify(err_msg, vim.log.levels.ERROR)
+ return false
+ end
+
+ local log_info = vim.loop.fs_stat(logfilename)
+ if log_info and log_info.size > 1e9 then
+ local warn_msg = string.format(
+ "LSP client log is large (%d MB): %s",
+ log_info.size / (1000 * 1000),
+ logfilename
+ )
+ vim.notify(warn_msg)
+ end
+
+ -- Start message for logging
+ logfile:write(string.format("[START][%s] LSP logging initiated\n", os.date(log_date_format)))
+ return true
end
- -- Start message for logging
- logfile:write(string.format("[START][%s] LSP logging initiated\n", os.date(log_date_format)))
for level, levelnr in pairs(log.levels) do
-- Also export the log level on the root object.
log[level] = levelnr
@@ -63,23 +83,26 @@ do
-- ```
--
-- This way you can avoid string allocations if the log level isn't high enough.
- log[level:lower()] = function(...)
- local argc = select("#", ...)
- if levelnr < current_log_level then return false end
- if argc == 0 then return true end
- local info = debug.getinfo(2, "Sl")
- local header = string.format("[%s][%s] ...%s:%s", level, os.date(log_date_format), string.sub(info.short_src, #info.short_src - 15), info.currentline)
- local parts = { header }
- for i = 1, argc do
- local arg = select(i, ...)
- if arg == nil then
- table.insert(parts, "nil")
- else
- table.insert(parts, format_func(arg))
+ if level ~= "OFF" then
+ log[level:lower()] = function(...)
+ local argc = select("#", ...)
+ if levelnr < current_log_level then return false end
+ if argc == 0 then return true end
+ if not open_logfile() then return false end
+ local info = debug.getinfo(2, "Sl")
+ local header = string.format("[%s][%s] ...%s:%s", level, os.date(log_date_format), string.sub(info.short_src, #info.short_src - 15), info.currentline)
+ local parts = { header }
+ for i = 1, argc do
+ local arg = select(i, ...)
+ if arg == nil then
+ table.insert(parts, "nil")
+ else
+ table.insert(parts, format_func(arg))
+ end
end
+ logfile:write(table.concat(parts, '\t'), "\n")
+ logfile:flush()
end
- logfile:write(table.concat(parts, '\t'), "\n")
- logfile:flush()
end
end
end
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 77ab1d4224..72dfb3cd76 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -456,7 +456,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
-- Remove final line if needed
local fix_eol = has_eol_text_edit
- fix_eol = fix_eol and (api.nvim_buf_get_option(bufnr, 'eol') or (api.nvim_buf_get_option(bufnr, 'fixeol') and not api.nvim_buf_get_option('binary')))
+ fix_eol = fix_eol and (api.nvim_buf_get_option(bufnr, 'eol') or (api.nvim_buf_get_option(bufnr, 'fixeol') and not api.nvim_buf_get_option(bufnr, 'binary')))
fix_eol = fix_eol and get_line(bufnr, max - 1) == ''
if fix_eol then
vim.api.nvim_buf_set_lines(bufnr, -2, -1, false, {})