docs: bufadd(), fnameescape() guidance #40378

This commit is contained in:
Justin M. Keyes authored and GitHub committed 2026-06-23 10:08:50 -04:00
1 parent ceaf2baa60
commit 8e3b216d0b
9 files changed
+122 -92

No files matched your search

+1 -1
View File
@@ -2890,7 +2890,7 @@ nvim_cmd({cmd}, {opts}) *nvim_cmd()*
Executes an Ex command `cmd`, specified as a Dict with the same structure
as returned by |nvim_parse_cmd()|.
Use `magic={…=false}` to disable special chars: >lua
Use `magic={…=false}` to disable special chars (see also |open-file|): >lua
vim.api.nvim_cmd({
cmd = 'edit',
args = { '%foo"|bar#baz"' },
+45 -24
View File
@@ -330,13 +330,11 @@ current file name.
Besides the things mentioned here, more special items for where a filename is
expected are mentioned at |cmdline-special|.
Note for systems other than Unix: When using a command that accepts a single
file name (like ":edit file") spaces in the file name are allowed, but
trailing spaces are ignored. This is useful on systems that regularly embed
spaces in file names (like MS-Windows). Example: The command ":e Long File
Name " will edit the file "Long File Name". When using a command that accepts
more than one file name (like ":next file1 file2") embedded spaces must be
escaped with a backslash.
When using a command that accepts a single file name (like ":edit file")
spaces in the file name are allowed, but trailing spaces are ignored.
Example: The command ":e Long File Name " will edit the file "Long File
Name". When using a command that accepts more than one file name (like ":next
file1 file2") embedded spaces must be escaped with a backslash.
*wildcard* *wildcards*
Wildcards in {file} are expanded, but as with file completion, 'wildignore'
@@ -361,18 +359,18 @@ Note there are some commands where this works slightly differently, see
|file-searching|.
Example: >
:n **/*.txt
Finds files:
aaa.txt ~
subdir/bbb.txt ~
a/b/c/d/ccc.txt ~
Finds files: >
aaa.txt
subdir/bbb.txt
a/b/c/d/ccc.txt
When non-wildcard characters are used right before or after "**" these are
only matched in the top directory. They are not used for directories further
down in the tree. For example: >
:n /usr/inc**/types.h
Finds files:
/usr/include/types.h ~
/usr/include/sys/types.h ~
/usr/inc/old/types.h ~
Finds files: >
/usr/include/types.h
/usr/include/sys/types.h
/usr/inc/old/types.h
Note that the path with "/sys" is included because it does not need to match
"/inc". Thus it's like matching "/usr/inc*/*/*...", not
"/usr/inc*/inc*/inc*".
@@ -558,7 +556,7 @@ Before editing binary, executable or Vim script files you should set the
option. This will avoid the use of 'fileformat'. Without this you risk that
single <NL> characters are unexpectedly replaced with <CR><NL>.
END OF LINE AND END OF FILE *eol-and-eof*
END-OF-LINE AND END-OF-FILE *eol-and-eof*
Vim has several options to control the file format:
'fileformat' the <EOL> style: Unix, DOS, Mac
@@ -596,6 +594,28 @@ If you want to preserve the fileformat exactly as-is, including any final
<EOL> and final CTRL-Z: >
setl nofixeol
OPENING FILES PROGRAMMATICALLY *buffer-open* *open-file*
When a plugin already has a literal filepath (e.g. from a picker, LSP result,
or filesystem scan) and just wants to open it, |:edit| is the wrong tool: its
argument is subject to |cmdline-special| expansion, |wildcard| expansion, etc.
|fnameescape()| escapes only some of these, and may depend on 'isfname'.
Instead, to open a filepath literally, use `bufadd(vim.fs.normalize(…))`: >lua
local buf = vim.fn.bufadd(vim.fs.normalize(path))
vim.fn.bufload(buf) -- Trigger BufReadPre/BufReadPost/FileType.
vim.bo[buf].buflisted = true -- Show in ":ls".
vim.api.nvim_win_set_buf(0, buf) -- Show in current window.
Alternatively, |nvim_cmd()| and |vim.cmd()| accept a structured form whose
`args` are tokenized verbatim. But the argument still goes through |:edit|'s
filename-expansion phase, so some parts of `path` are still expanded: >lua
vim.cmd{ cmd = 'edit',
args = { path },
magic = { file = false, bar = false },
}
<
==============================================================================
3. The argument list *argument-list* *arglist*
@@ -1347,15 +1367,16 @@ use has("browsefilter"): >
==============================================================================
7. The current directory *current-directory*
You can use |:cd|, |:tcd| and |:lcd| to change to another directory, so you
will not have to type that directory name in front of the file names. It also
makes a difference for executing external commands, e.g. ":!ls" or ":te ls".
There are three current-directory "scopes": global, tab and window. You can
use |:cd|, |:tcd| and |:lcd| to change to another directory. This affects
anything that operates on relative paths, e.g. ":edit ./foo.txt" or shell
commands like ":!ls" or ":te ls".
There are three current-directory "scopes": global, tab and window. The
window-local working directory takes precedence over the tab-local
working directory, which in turn takes precedence over the global
working directory. If a local working directory (tab or window) does not
exist, the next-higher scope in the hierarchy applies.
Use |getcwd()| to get the effective directory from the current scope. The
window-local working directory takes precedence over the tab-local working
directory, which in turn takes precedence over the global working directory.
If a local working directory (tab or window) does not exist, the next-higher
scope in the hierarchy applies.
*:cd* *E747* *E472*
:cd[!] On non-Unix systems when 'cdhome' is off: Print the
+3 -3
View File
@@ -19,11 +19,11 @@ This is not a comprehensive encyclopedia of all available features. Think of
it as a survival kit: the bare minimum needed to comfortably get started on
using Lua in Nvim.
See |lua-plugin| for guidance on developing Lua plugins.
See |luaref| and |lua-concepts| for details on the Lua programming language.
- See |lua-plugin| for guidance on developing Lua plugins.
- See |luaref| and |lua-concepts| for details on the Lua programming language.
------------------------------------------------------------------------------
Some words on the API *lua-guide-api*
About the API *lua-guide-api*
The purpose of this guide is to introduce the different ways of interacting
with Nvim through Lua (the "API"). This API consists of three different
+7 -2
View File
@@ -12,8 +12,8 @@ Introduction *lua-plugin*
This document provides guidance for developing Nvim Lua plugins.
See |lua-guide| for guidance on using Lua to configure and operate Nvim.
See |luaref| and |lua-concepts| for details on the Lua programming language.
- See |lua-guide| for guidance on using Lua to configure and operate Nvim.
- See |luaref| and |lua-concepts| for details on the Lua programming language.
==============================================================================
Creating your first plugin *lua-plugin-new*
@@ -243,6 +243,11 @@ A plugin tailored to Rust development might have initialization in
print('Hello')
end, { buf = bufnr })
<
==============================================================================
Opening files *lua-plugin-open-file*
To robustly open a file, see |open-file|.
==============================================================================
Configuration *lua-plugin-config*
+21 -20
View File
@@ -593,18 +593,18 @@ browsedir({title}, {initdir}) *browsedir()*
(`0|1`)
bufadd({name}) *bufadd()*
Add a buffer to the buffer list with name {name} (must be a
String).
If a buffer for file {name} already exists, return that buffer
number. Otherwise return the buffer number of the newly
created buffer. When {name} is an empty string then a new
buffer is always created.
The buffer will not have 'buflisted' set and not be loaded
yet. To add some text to the buffer use this: >vim
let bufnr = bufadd('someName')
call bufload(bufnr)
call setbufline(bufnr, 1, ['some', 'text'])
< Returns 0 on error.
Adds buffer {name} to the buffer list literally: no special
chars or expansion are applied (including "~"). Returns the
new (or existing matching) buffer number, or 0 on error.
The buffer is not loaded and 'buflisted' is not set. When
{name} is an empty string, a new buffer is always created.
Example (Lua): >lua
local b = vim.fn.bufadd(vim.fs.normalize('someName'))
vim.bo[b].buflisted = true
vim.fn.bufload(b)
<
Parameters: ~
• {name} (`string`)
@@ -2722,14 +2722,15 @@ fmod({expr1}, {expr2}) *fmod()*
Return: ~
(`any`)
fnameescape({string}) *fnameescape()*
Lua: Prefer |nvim_cmd()| or |vim.cmd()| with structured
arguments to avoid Ex filename escaping.
fnameescape({filepath}) *fnameescape()*
Escapes {filepath} for use as a command argument.
Escape {string} for use as file name command argument. All
characters that have a special meaning, such as `'%'` and `'|'`
are escaped with a backslash. For most systems the characters
escaped are: >
(Note: To open a literal filepath programmatically use
`bufadd(vim.fs.normalize(…))`, see |open-file|.)
All characters that have a special meaning, such as `'%'` and
`'|'` are escaped with a backslash. For most systems the
characters escaped are: >
\t\n *?[{`$\\%#'\"|!<
< For systems where a backslash appears in a filename, it
depends on the value of 'isfname'. A leading '+' and '>' is
@@ -2744,7 +2745,7 @@ fnameescape({string}) *fnameescape()*
<
Parameters: ~
• {string} (`string`)
• {filepath} (`string`)
Return: ~
(`string`)
+1 -1
View File
@@ -849,7 +849,7 @@ function vim.api.nvim_clear_autocmds(opts) end
--- Executes an Ex command `cmd`, specified as a Dict with the same structure as returned by
--- `nvim_parse_cmd()`.
---
--- Use `magic={…=false}` to disable special chars:
--- Use `magic={…=false}` to disable special chars (see also `open-file`):
--- ```lua
--- vim.api.nvim_cmd({
--- cmd = 'edit',
+21 -19
View File
@@ -496,18 +496,18 @@ function vim.fn.browse(save, title, initdir, default) end
--- @return 0|1
function vim.fn.browsedir(title, initdir) end
--- Add a buffer to the buffer list with name {name} (must be a
--- String).
--- If a buffer for file {name} already exists, return that buffer
--- number. Otherwise return the buffer number of the newly
--- created buffer. When {name} is an empty string then a new
--- buffer is always created.
--- The buffer will not have 'buflisted' set and not be loaded
--- yet. To add some text to the buffer use this: >vim
--- let bufnr = bufadd('someName')
--- call bufload(bufnr)
--- call setbufline(bufnr, 1, ['some', 'text'])
--- <Returns 0 on error.
--- Adds buffer {name} to the buffer list literally: no special
--- chars or expansion are applied (including "~"). Returns the
--- new (or existing matching) buffer number, or 0 on error.
---
--- The buffer is not loaded and 'buflisted' is not set. When
--- {name} is an empty string, a new buffer is always created.
---
--- Example (Lua): >lua
--- local b = vim.fn.bufadd(vim.fs.normalize('someName'))
--- vim.bo[b].buflisted = true
--- vim.fn.bufload(b)
--- <
---
--- @param name string
--- @return integer
@@ -2418,12 +2418,14 @@ function vim.fn.floor(expr) end
--- @return any
function vim.fn.fmod(expr1, expr2) end
--- Lua: Prefer |nvim_cmd()| or |vim.cmd()| with structured arguments to avoid Ex filename escaping.
--- Escapes {filepath} for use as a command argument.
---
--- Escape {string} for use as file name command argument. All
--- characters that have a special meaning, such as `'%'` and `'|'`
--- are escaped with a backslash. For most systems the characters
--- escaped are: >
--- (Note: To open a literal filepath programmatically use
--- `bufadd(vim.fs.normalize(…))`, see |open-file|.)
---
--- All characters that have a special meaning, such as `'%'` and
--- `'|'` are escaped with a backslash. For most systems the
--- characters escaped are: >
--- \t\n *?[{`$\\%#'\"|!<
--- <For systems where a backslash appears in a filename, it
--- depends on the value of 'isfname'. A leading '+' and '>' is
@@ -2437,9 +2439,9 @@ function vim.fn.fmod(expr1, expr2) end
--- edit \+some\ str\%nge\|name
--- <
---
--- @param string string
--- @param filepath string
--- @return string
function vim.fn.fnameescape(string) end
function vim.fn.fnameescape(filepath) end
--- Lua: Prefer |vim.fs.dirname()|, |vim.fs.basename()|, |vim.fs.abspath()|, and |vim.fs.normalize()| for common path modifiers; modifier coverage differs.
---
+1 -1
View File
@@ -324,7 +324,7 @@ end:
/// Executes an Ex command `cmd`, specified as a Dict with the same structure as returned by
/// |nvim_parse_cmd()|.
///
/// Use `magic={…=false}` to disable special chars:
/// Use `magic={…=false}` to disable special chars (see also |open-file|):
/// ```lua
/// vim.api.nvim_cmd({
/// cmd = 'edit',
+22 -21
View File
@@ -671,18 +671,18 @@ M.funcs = {
args = 1,
base = 1,
desc = [=[
Add a buffer to the buffer list with name {name} (must be a
String).
If a buffer for file {name} already exists, return that buffer
number. Otherwise return the buffer number of the newly
created buffer. When {name} is an empty string then a new
buffer is always created.
The buffer will not have 'buflisted' set and not be loaded
yet. To add some text to the buffer use this: >vim
let bufnr = bufadd('someName')
call bufload(bufnr)
call setbufline(bufnr, 1, ['some', 'text'])
<Returns 0 on error.
Adds buffer {name} to the buffer list literally: no special
chars or expansion are applied (including "~"). Returns the
new (or existing matching) buffer number, or 0 on error.
The buffer is not loaded and 'buflisted' is not set. When
{name} is an empty string, a new buffer is always created.
Example (Lua): >lua
local b = vim.fn.bufadd(vim.fs.normalize('someName'))
vim.bo[b].buflisted = true
vim.fn.bufload(b)
<
]=],
name = 'bufadd',
params = { { 'name', 'string' } },
@@ -3028,10 +3028,14 @@ M.funcs = {
args = 1,
base = 1,
desc = [=[
Escape {string} for use as file name command argument. All
characters that have a special meaning, such as `'%'` and `'|'`
are escaped with a backslash. For most systems the characters
escaped are: >
Escapes {filepath} for use as a command argument.
(Note: To open a literal filepath programmatically use
`bufadd(vim.fs.normalize(…))`, see |open-file|.)
All characters that have a special meaning, such as `'%'` and
`'|'` are escaped with a backslash. For most systems the
characters escaped are: >
\t\n *?[{`$\\%#'\"|!<
<For systems where a backslash appears in a filename, it
depends on the value of 'isfname'. A leading '+' and '>' is
@@ -3047,12 +3051,9 @@ M.funcs = {
]=],
fast = true,
name = 'fnameescape',
params = { { 'string', 'string' } },
params = { { 'filepath', 'string' } },
returns = 'string',
signature = 'fnameescape({string})',
see_lua = {
'|nvim_cmd()| or |vim.cmd()| with structured arguments to avoid Ex filename escaping',
},
signature = 'fnameescape({filepath})',
},
fnamemodify = {
args = 2,