aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/notes.md5
-rw-r--r--CMakeLists.txt6
-rw-r--r--runtime/doc/lua.txt43
-rw-r--r--runtime/doc/various.txt6
-rw-r--r--runtime/filetype.lua2
-rw-r--r--runtime/lua/vim/filetype.lua88
-rw-r--r--runtime/pack/dist/opt/termdebug/plugin/termdebug.vim3
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/testdir/test_cmdline.vim6
-rw-r--r--src/nvim/testdir/test_quickfix.vim16
-rw-r--r--test/functional/lua/filetype_spec.lua15
11 files changed, 141 insertions, 51 deletions
diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md
index 86f9e8e618..d752f10609 100644
--- a/.github/workflows/notes.md
+++ b/.github/workflows/notes.md
@@ -21,8 +21,9 @@ ${NVIM_VERSION}
### macOS
1. Download **nvim-macos.tar.gz**
-2. Extract: `tar xzvf nvim-macos.tar.gz`
-3. Run `./nvim-macos/bin/nvim`
+2. Run `xattr -c ./nvim-macos.tar.gz` (to avoid "unknown developer" warning)
+3. Extract: `tar xzvf nvim-macos.tar.gz`
+4. Run `./nvim-macos/bin/nvim`
### Linux (x64)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9502190708..097ef041ea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -573,11 +573,7 @@ endif()
message(STATUS "Using Lua interpreter: ${LUA_PRG}")
-if(DEBUG)
- option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" OFF)
-else()
- option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" ON)
-endif()
+option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" ON)
if(COMPILE_LUA AND NOT WIN32)
if(PREFER_LUA)
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 9f8d4a8479..f40b32c469 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -2064,14 +2064,45 @@ add({filetypes}) *vim.filetype.add()*
{filetypes} (table) A table containing new filetype maps
(see example).
-match({name}, {bufnr}) *vim.filetype.match()*
- Find the filetype for the given filename and buffer.
+match({arg}) *vim.filetype.match()*
+ Perform filetype detection.
+
+ The filetype can be detected using one of three methods:
+ 1. Using an existing buffer
+ 2. Using only a file name
+ 3. Using only file contents
+
+ Of these, option 1 provides the most accurate result as it
+ uses both the buffer's filename and (optionally) the buffer
+ contents. Options 2 and 3 can be used without an existing
+ buffer, but may not always provide a match in cases where the
+ filename (or contents) cannot unambiguously determine the
+ filetype.
+
+ Each of the three options is specified using a key to the
+ single argument of this function. Example:
+>
+
+ -- Using a buffer number
+ vim.filetype.match({ buf = 42 })
+
+ -- Using a filename
+ vim.filetype.match({ filename = "main.lua" })
+
+ -- Using file contents
+ vim.filetype.match({ contents = {"#!/usr/bin/env bash"} })
+<
Parameters: ~
- {name} (string) File name (can be an absolute or
- relative path)
- {bufnr} (number|nil) The buffer to set the filetype for.
- Defaults to the current buffer.
+ {arg} (table) Table specifying which matching strategy to
+ use. It is an error to provide more than one
+ strategy. Accepted keys are:
+ • buf (number): Buffer number to use for matching
+ • filename (string): Filename to use for matching.
+ Note that the file need not actually exist in the
+ filesystem, only the name itself is used.
+ • contents (table): An array of lines representing
+ file contents to use for matching.
Return: ~
(string|nil) If a match was found, the matched filetype.
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 562faeaa2c..9eb6470962 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -346,7 +346,11 @@ g8 Print the hex values of the bytes used in the
Only string variables can be used. After the
redirection starts, if the variable is removed or
locked or the variable type is changed, then further
- command output messages will cause errors.
+ command output messages will cause errors. When using
+ a local variable (l:var in a function or s:var in a
+ script) and another `:redir` causes the current one to
+ end, the scope might be different and the assignment
+ fails.
To get the output of one command the |execute()|
function can be used instead of redirection.
diff --git a/runtime/filetype.lua b/runtime/filetype.lua
index b002b8971b..35bb31edce 100644
--- a/runtime/filetype.lua
+++ b/runtime/filetype.lua
@@ -12,7 +12,7 @@ vim.api.nvim_create_augroup('filetypedetect', { clear = false })
vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile' }, {
group = 'filetypedetect',
callback = function(args)
- local ft, on_detect = vim.filetype.match(args.file, args.buf)
+ local ft, on_detect = vim.filetype.match({ buf = args.buf })
if ft then
vim.api.nvim_buf_set_option(args.buf, 'filetype', ft)
if on_detect then
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 6c4894208f..3e86159489 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -2047,7 +2047,7 @@ local pattern = {
end
end, { priority = -math.huge + 1 }),
['XF86Config.*'] = starsetf(function(path, bufnr)
- return require('vim.filetype.detect').xfree86(bufnr)
+ return require('vim.filetype.detect').xfree86()
end),
['%.zcompdump.*'] = starsetf('zsh'),
-- .zlog* and zlog*
@@ -2185,17 +2185,24 @@ end
local function dispatch(ft, path, bufnr, ...)
local on_detect
if type(ft) == 'function' then
- ft, on_detect = ft(path, bufnr, ...)
+ if bufnr then
+ ft, on_detect = ft(path, bufnr, ...)
+ else
+ -- If bufnr is nil (meaning we are matching only against the filename), set it to an invalid
+ -- value (-1) and catch any errors from the filetype detection function. If the function tries
+ -- to use the buffer then it will fail, but this enables functions which do not need a buffer
+ -- to still work.
+ local ok
+ ok, ft, on_detect = pcall(ft, path, -1, ...)
+ if not ok then
+ return
+ end
+ end
end
if type(ft) == 'string' then
return ft, on_detect
end
-
- -- Any non-falsey value (that is, anything other than 'nil' or 'false') will
- -- end filetype matching. This is useful for e.g. the dist#ft functions that
- -- return 0, but set the buffer's filetype themselves
- return ft
end
---@private
@@ -2214,29 +2221,74 @@ local function match_pattern(name, path, tail, pat)
return matches
end
---- Find the filetype for the given filename and buffer.
+--- Perform filetype detection.
+---
+--- The filetype can be detected using one of three methods:
+--- 1. Using an existing buffer
+--- 2. Using only a file name
+--- 3. Using only file contents
+---
+--- Of these, option 1 provides the most accurate result as it uses both the buffer's filename and
+--- (optionally) the buffer contents. Options 2 and 3 can be used without an existing buffer, but
+--- may not always provide a match in cases where the filename (or contents) cannot unambiguously
+--- determine the filetype.
+---
+--- Each of the three options is specified using a key to the single argument of this function.
+--- Example:
+---
+--- <pre>
+--- -- Using a buffer number
+--- vim.filetype.match({ buf = 42 })
---
----@param name string File name (can be an absolute or relative path)
----@param bufnr number|nil The buffer to set the filetype for. Defaults to the current buffer.
+--- -- Using a filename
+--- vim.filetype.match({ filename = "main.lua" })
+---
+--- -- Using file contents
+--- vim.filetype.match({ contents = {"#!/usr/bin/env bash"} })
+--- </pre>
+---
+---@param arg table Table specifying which matching strategy to use. It is an error to provide more
+--- than one strategy. Accepted keys are:
+--- * buf (number): Buffer number to use for matching
+--- * filename (string): Filename to use for matching. Note that the file need not
+--- actually exist in the filesystem, only the name itself is
+--- used.
+--- * contents (table): An array of lines representing file contents to use for
+--- matching.
---@return string|nil If a match was found, the matched filetype.
---@return function|nil A function that modifies buffer state when called (for example, to set some
--- filetype specific buffer variables). The function accepts a buffer number as
--- its only argument.
-function M.match(name, bufnr)
+function M.match(arg)
vim.validate({
- name = { name, 's' },
- bufnr = { bufnr, 'n', true },
+ arg = { arg, 't' },
})
- -- When fired from the main filetypedetect autocommand the {bufnr} argument is omitted, so we use
- -- the current buffer. The {bufnr} argument is provided to allow extensibility in case callers
- -- wish to perform filetype detection on buffers other than the current one.
- bufnr = bufnr or api.nvim_get_current_buf()
+ if not (arg.buf or arg.filename or arg.contents) then
+ error('One of "buf", "filename", or "contents" must be given')
+ end
+
+ if (arg.buf and arg.filename) or (arg.buf and arg.contents) or (arg.filename and arg.contents) then
+ error('Only one of "buf", "filename", or "contents" must be given')
+ end
+
+ local bufnr = arg.buf
+ local name = bufnr and api.nvim_buf_get_name(bufnr) or arg.filename
+ local contents = arg.contents
- name = normalize_path(name)
+ if name then
+ name = normalize_path(name)
+ end
local ft, on_detect
+ if not (bufnr or name) then
+ -- Sanity check: this should not happen
+ assert(contents, 'contents should be non-nil when bufnr and filename are nil')
+ -- TODO: "scripts.lua" content matching
+ return
+ end
+
-- First check for the simple case where the full path exists as a key
local path = vim.fn.resolve(vim.fn.fnamemodify(name, ':p'))
ft, on_detect = dispatch(filename[path], path, bufnr)
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index f76bdebe9b..c4e90eb373 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -2,7 +2,7 @@
"
" Author: Bram Moolenaar
" Copyright: Vim license applies, see ":help license"
-" Last Change: 2022 Jun 22
+" Last Change: 2022 Jun 24
"
" WORK IN PROGRESS - The basics works stable, more to come
" Note: In general you need at least GDB 7.12 because this provides the
@@ -539,6 +539,7 @@ func TermDebugSendCommand(cmd)
endif
sleep 10m
endif
+ " TODO: should we prepend CTRL-U to clear the command?
call chansend(s:gdb_job_id, a:cmd . "\r")
if do_continue
Continue
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index be2df9488e..7b6e954b3a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -469,7 +469,9 @@ void eval_clear(void)
hash_clear(&compat_hashtab);
free_scriptnames();
+# ifdef HAVE_WORKING_LIBINTL
free_locales();
+# endif
// global variables
vars_clear(&globvarht);
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 887c8e1593..8d1746be2f 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -305,7 +305,7 @@ func Test_getcompletion()
call assert_equal([], l)
let l = getcompletion('', 'dir')
- call assert_true(index(l, expand('sautest/')) >= 0)
+ call assert_true(index(l, 'sautest/') >= 0)
let l = getcompletion('NoMatch', 'dir')
call assert_equal([], l)
@@ -415,7 +415,7 @@ func Test_getcompletion()
" Command line completion tests
let l = getcompletion('cd ', 'cmdline')
- call assert_true(index(l, expand('sautest/')) >= 0)
+ call assert_true(index(l, 'sautest/') >= 0)
let l = getcompletion('cd NoMatch', 'cmdline')
call assert_equal([], l)
let l = getcompletion('let v:n', 'cmdline')
@@ -539,7 +539,7 @@ func Test_expand_star_star()
call mkdir('a/b', 'p')
call writefile(['asdfasdf'], 'a/b/fileXname')
call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
- call assert_equal('find '.expand('a/b/fileXname'), getreg(':'))
+ call assert_equal('find a/b/fileXname', getreg(':'))
bwipe!
call delete('a', 'rf')
endfunc
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index e43db4d692..5826666cbb 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -1060,17 +1060,17 @@ func s:dir_stack_tests(cchar)
let qf = g:Xgetlist()
- call assert_equal(expand('dir1/a/habits2.txt'), bufname(qf[1].bufnr))
+ call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
call assert_equal(1, qf[1].lnum)
- call assert_equal(expand('dir1/a/b/habits3.txt'), bufname(qf[3].bufnr))
+ call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
call assert_equal(2, qf[3].lnum)
- call assert_equal(expand('dir1/a/habits2.txt'), bufname(qf[4].bufnr))
+ call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
call assert_equal(7, qf[4].lnum)
- call assert_equal(expand('dir1/c/habits4.txt'), bufname(qf[6].bufnr))
+ call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
call assert_equal(3, qf[6].lnum)
call assert_equal('habits1.txt', bufname(qf[9].bufnr))
call assert_equal(4, qf[9].lnum)
- call assert_equal(expand('dir2/habits5.txt'), bufname(qf[11].bufnr))
+ call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
call assert_equal(5, qf[11].lnum)
let &efm=save_efm
@@ -1300,7 +1300,7 @@ func Test_efm2()
call assert_equal(8, len(l))
call assert_equal(89, l[4].lnum)
call assert_equal(1, l[4].valid)
- call assert_equal(expand('unittests/dbfacadeTest.py'), bufname(l[4].bufnr))
+ call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
call assert_equal('W', l[4].type)
" Test for %o
@@ -2074,11 +2074,11 @@ func Test_two_windows()
laddexpr 'one.txt:3:one one one'
let loc_one = getloclist(one_id)
- call assert_equal(expand('Xone/a/one.txt'), bufname(loc_one[1].bufnr))
+ call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
call assert_equal(3, loc_one[1].lnum)
let loc_two = getloclist(two_id)
- call assert_equal(expand('Xtwo/a/two.txt'), bufname(loc_two[1].bufnr))
+ call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
call assert_equal(5, loc_two[1].lnum)
call win_gotoid(one_id)
diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua
index d0cef53c4b..be57b2db31 100644
--- a/test/functional/lua/filetype_spec.lua
+++ b/test/functional/lua/filetype_spec.lua
@@ -3,6 +3,7 @@ local exec_lua = helpers.exec_lua
local eq = helpers.eq
local clear = helpers.clear
local pathroot = helpers.pathroot
+local command = helpers.command
local root = pathroot()
@@ -23,7 +24,7 @@ describe('vim.filetype', function()
rs = 'radicalscript',
},
})
- return vim.filetype.match('main.rs')
+ return vim.filetype.match({ filename = 'main.rs' })
]])
end)
@@ -37,7 +38,7 @@ describe('vim.filetype', function()
['main.rs'] = 'somethingelse',
},
})
- return vim.filetype.match('main.rs')
+ return vim.filetype.match({ filename = 'main.rs' })
]])
end)
@@ -48,7 +49,7 @@ describe('vim.filetype', function()
['s_O_m_e_F_i_l_e'] = 'nim',
},
})
- return vim.filetype.match('s_O_m_e_F_i_l_e')
+ return vim.filetype.match({ filename = 's_O_m_e_F_i_l_e' })
]])
eq('dosini', exec_lua([[
@@ -59,7 +60,7 @@ describe('vim.filetype', function()
[root .. '/.config/fun/config'] = 'dosini',
},
})
- return vim.filetype.match(root .. '/.config/fun/config')
+ return vim.filetype.match({ filename = root .. '/.config/fun/config' })
]], root))
end)
@@ -72,11 +73,13 @@ describe('vim.filetype', function()
['~/blog/.*%.txt'] = 'markdown',
}
})
- return vim.filetype.match('~/blog/why_neovim_is_awesome.txt')
+ return vim.filetype.match({ filename = '~/blog/why_neovim_is_awesome.txt' })
]], root))
end)
it('works with functions', function()
+ command('new')
+ command('file relevant_to_me')
eq('foss', exec_lua [[
vim.filetype.add({
pattern = {
@@ -87,7 +90,7 @@ describe('vim.filetype', function()
end,
}
})
- return vim.filetype.match('relevant_to_me')
+ return vim.filetype.match({ buf = 0 })
]])
end)
end)