mirror of
https://github.com/neovim/neovim.git
synced 2026-11-06 05:16:52 +00:00
fix(filetype): empty 'filetype' skips :setfiletype #41958
Problem:
After `:restart` a restored buffer can have an empty 'filetype'. Lazy
LSP setup during the read replays FileType via `:doautoall`, which sets
`did_filetype` even though `filetype=''`.
:e foo.md
:restart
:set ft? " filetype=
Solution:
Set `did_filetype` only if 'filetype' is non-empty.
This commit is contained in:
1 parent
d1fd8158de
commit
6ad6dcd5d4
6 files changed
+33
-16
No files matched your search
@@ -462,15 +462,16 @@ reads back as the function (from Lua) or a `"<Lua …>"` hint (Vimscript/RPC).
|
||||
Setting the filetype
|
||||
|
||||
:setf[iletype] [FALLBACK] {filetype} *:setf* *:setfiletype*
|
||||
Set the 'filetype' option to {filetype}, but only if
|
||||
not done yet in a sequence of (nested) autocommands.
|
||||
Set the 'filetype' option to {filetype}, unless it was
|
||||
already set (non-empty) in a sequence of (nested)
|
||||
autocommands.
|
||||
This is short for: >
|
||||
:if !did_filetype()
|
||||
: setlocal filetype={filetype}
|
||||
:endif
|
||||
< This command is used in a filetype.vim file to avoid
|
||||
setting the 'filetype' option twice, causing different
|
||||
settings and syntax files to be loaded.
|
||||
< Used in a filetype.vim file to avoid setting the
|
||||
'filetype' option twice, causing different settings
|
||||
and syntax files to be loaded.
|
||||
|
||||
When the optional FALLBACK argument is present, a
|
||||
later :setfiletype command will override the
|
||||
|
||||
@@ -1743,10 +1743,11 @@ dictwatcherdel({dict}, {pattern}, {callback}) *dictwatcherdel()*
|
||||
|
||||
did_filetype() *did_filetype()*
|
||||
Returns |TRUE| when autocommands are being executed and the
|
||||
FileType event has been triggered at least once. Can be used
|
||||
to avoid triggering the FileType event again in the scripts
|
||||
that detect the file type. |FileType|
|
||||
FileType event triggered at least once for a buffer with
|
||||
a non-empty 'filetype'. Can be used to avoid triggering
|
||||
the FileType event again in the |ftdetect| scripts. |FileType|
|
||||
Returns |FALSE| when `:setf FALLBACK` was used.
|
||||
|
||||
When editing another file, the counter is reset, thus this
|
||||
really checks if the FileType event has been triggered for the
|
||||
current buffer. This allows an autocommand that starts
|
||||
|
||||
Generated
+4
-3
@@ -1528,10 +1528,11 @@ function vim.fn.dictwatcheradd(dict, pattern, callback) end
|
||||
function vim.fn.dictwatcherdel(dict, pattern, callback) end
|
||||
|
||||
--- Returns |TRUE| when autocommands are being executed and the
|
||||
--- FileType event has been triggered at least once. Can be used
|
||||
--- to avoid triggering the FileType event again in the scripts
|
||||
--- that detect the file type. |FileType|
|
||||
--- FileType event triggered at least once for a buffer with
|
||||
--- a non-empty 'filetype'. Can be used to avoid triggering
|
||||
--- the FileType event again in the |ftdetect| scripts. |FileType|
|
||||
--- Returns |FALSE| when `:setf FALLBACK` was used.
|
||||
---
|
||||
--- When editing another file, the counter is reset, thus this
|
||||
--- really checks if the FileType event has been triggered for the
|
||||
--- current buffer. This allows an autocommand that starts
|
||||
|
||||
+2
-2
@@ -1710,8 +1710,8 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
|
||||
nesting++; // see matching decrement below
|
||||
|
||||
// Remember that FileType was triggered. Used for did_filetype().
|
||||
if (event == EVENT_FILETYPE) {
|
||||
// Remember that FileType was triggered, if 'filetype' was actually set. For :setf.
|
||||
if (event == EVENT_FILETYPE && *curbuf->b_p_ft != NUL) {
|
||||
curbuf->b_did_filetype = true;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -1952,10 +1952,11 @@ M.funcs = {
|
||||
did_filetype = {
|
||||
desc = [=[
|
||||
Returns |TRUE| when autocommands are being executed and the
|
||||
FileType event has been triggered at least once. Can be used
|
||||
to avoid triggering the FileType event again in the scripts
|
||||
that detect the file type. |FileType|
|
||||
FileType event triggered at least once for a buffer with
|
||||
a non-empty 'filetype'. Can be used to avoid triggering
|
||||
the FileType event again in the |ftdetect| scripts. |FileType|
|
||||
Returns |FALSE| when `:setf FALLBACK` was used.
|
||||
|
||||
When editing another file, the counter is reset, thus this
|
||||
really checks if the FileType event has been triggered for the
|
||||
current buffer. This allows an autocommand that starts
|
||||
|
||||
@@ -16,4 +16,17 @@ describe('autocmd FileType', function()
|
||||
command('help help')
|
||||
t.eq(1, eval('g:foo'))
|
||||
end)
|
||||
|
||||
it("empty 'filetype' does not prevent FileType event #41711", function()
|
||||
local file = t.tmpname(false) .. '.md'
|
||||
t.write_file(file, '# hi\n')
|
||||
command('filetype on')
|
||||
-- Like vim.lsp.enable() lazy-loaded while the buffer is being read.
|
||||
command('autocmd FileType * :')
|
||||
command('autocmd BufReadPre * ++once doautoall FileType')
|
||||
-- Run :edit in a nested event (mimics :restart session-restore).
|
||||
command(('autocmd User X ++nested edit %s'):format(vim.fn.fnameescape(file)))
|
||||
command('doautocmd User X')
|
||||
t.eq('markdown', eval('&filetype'))
|
||||
end)
|
||||
end)
|
||||
Reference in new issue
Block a user