Open ATM-Jahid opened 2 years ago
@ATM-Jahid I believe this has been raised elsewhere before but for the life of me I can't remember the issue name or number, but it is a known problem
@akinsho #648 is somewhat similar, but it's about ftplugin
folders loading twice, not ftdetect
folders. I don't know if this is what you are referring to.
Is there any plan to fix this problem? I can try to help if there's nobody else working on it.
@ATM-Jahid it's probably that one then. No one is already working on it as far as I know, so feel free to take a look.
Similar issue: https://github.com/neovim/neovim/issues/15272
I have the same issue on 0.5.1, the file is sourced exactly twice, so any autocommand is defined exactly twice as well.
@HiPhish To clarify, you have this issue even with a version of Neovim after the upstream patch you linked?
@wbthomason Yes, my exact version is 0.5.1 with LuaJIT 2.1.0-beta3, from the Void repos.
Interesting, thanks. From @ATM-Jahid's trace in the initial report, it looks like the duplicate-sourced ftdetect
files are only the treesitter
files (which is confusing as that's not even lazy-loaded in the given config, and doesn't seem to be sourced in the compiled file). Does that match your experience? Or is it every ftdetect
file?
@wbthomason I noticed it in my guile.vim plugin which would append .guile
to the file type twice. Here is the file in question: https://gitlab.com/HiPhish/guile.vim/-/blob/master/ftdetect/scheme.vim
As you can see I was forced to insert a hack to prevent the double-append from happening. Here are the autocommands which are installed:
:au BufRead,BufNewFile *scm
--- Autocommands ---
filetypedetect BufReadPost
*scm if guile#detect() | call s:adjust_ft() | endif
*scm if guile#detect() | call s:adjust_ft() | endif
filetypedetect BufNewFile
*scm if guile#detect() | call s:adjust_ft() | endif
*scm if guile#detect() | call s:adjust_ft() | endif
I think https://github.com/janet-lang/janet.vim/issues/10 is caused by this.
packer/load.lua somehow triggers sourcing of ftdetect files.
@amano-kenji That only happens when you lazy-load, or also on normal loads?
normal loads don't cause the issue. Only lazy-load through ft
does.
Ah. I think I've figured out the cause, but I'm not sure what the right solution is.
packer
sources ftdetect
scripts in packer_compiled.lua
because this may be necessary to lazy-load on a filetype: https://github.com/wbthomason/packer.nvim/blob/master/lua/packer/compile.lua#L798:L806
However, core also sources ftdetect
scripts for opt
plugins, here: https://github.com/neovim/neovim/blob/master/src/nvim/runtime.c#L1005-L1012. This is also reasonable, because plugins that define filetypes and are not lazy-loaded by filetype may need those scripts sourced when they get loaded.
If packer
could signal that the ftdetect
scripts had already been loaded, then we could avoid this, but I'm not sure there's a mechanism for that. Another workaround could be to have packer
make "dummy" ftdetect
scripts for packer_compiled
, but this is very hard to get right, since we'd have to figure out what the originals are doing in order to know what defines the relevant filetype. This is probably out of scope.
Honestly, I'm inclined to suggest that the real solution is for plugin authors who write ftdetect
scripts to ensure that they are idempotent and don't cause problems by being sourced multiple times - this is logical for what a ftdetect
script is meant to do, and is why this issue hasn't caused more serious/widespread problems before, because most ftdetect
s have this property (I believe). However, that's an onus on the plugin maintainers, and I might be off-base in my beliefs about it being reasonable to require.
Why is https://github.com/janet-lang/janet.vim/blob/master/ftdetect/janet.vim not idempotent?
By the way, I haven't learned vimscript, yet.
No worries. Technically, it's not idempotent because the autocommands are added again every time the file is sourced, but this is standard practice for ftdetect
(per :h ftdetect
) and isn't causing this issue.
The error in the linked janet-lang
issue stems from the function being redefined. This is a bit more annoying, and I'm not sure of the exact fix - it happens because of this chain of events (I think):
packer
sources the ftdetect
file) calls DetectJanet
DetectJanet
sets the filetype to janet
FileType
event packer
defined to lazy-load janet.vim
ftdetect
again. The use of the !
after fun
should redefine DetectJanet
, but we're still in a call to DetectJanet
because we haven't finished resolving setting the filetype (and the associated autocommands), so we can't redefine itIn this particular case, the real solution is to not lazy-load - you don't need it. Lazy-loading is a tool for dealing with plugins that have a heavy configuration or that aren't correctly written and do a lot of setup before they're needed, and - by quickly skimming the repo - janet.vim
doesn't match either of these cases. It puts its main logic in syntax/
and ftplugin/
, both of which will already only be sourced for janet
files.
nvim --version
:Features: +acl +iconv +tui See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim" fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
git version 2.34.0
OS: Arch Linux x86_64 Kernel: 5.15.2-arch1-1
times in msec clock self+sourced self: sourced script clock elapsed: other lines
000.018 000.018: --- NVIM STARTING --- 000.439 000.422: locale set 000.855 000.416: inits 1 000.875 000.020: window checked 000.879 000.004: parsing arguments 000.939 000.061: expanding arguments 000.999 000.059: inits 2 001.548 000.549: init highlight 001.550 000.002: waiting for UI 002.717 001.168: done waiting for UI 002.744 000.027: init screen for UI 002.938 000.020 000.020: sourcing /usr/share/nvim/archlinux.vim 002.945 000.064 000.044: sourcing /etc/xdg//nvim/sysinit.vim 009.744 006.762 006.762: sourcing /home/atomsky/.config/nvim/init.lua 009.758 000.188: sourcing vimrc file(s) 015.867 000.021 000.021: sourcing /usr/share/vim/vimfiles/ftdetect/PKGBUILD.vim 015.914 000.020 000.020: sourcing /usr/share/vim/vimfiles/ftdetect/conkyrc.vim 016.306 000.024 000.024: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/elixir.vim 016.340 000.015 000.015: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/fennel.vim 016.373 000.015 000.015: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/fish.vim 016.404 000.013 000.013: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gdresource.vim 016.430 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gdscript.vim 016.463 000.013 000.013: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/glimmer.vim 016.494 000.011 000.011: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gomod.vim 016.535 000.021 000.021: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/graphql.vim 016.572 000.018 000.018: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/hcl.vim 016.600 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/heex.vim 016.629 000.011 000.011: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/hjson.vim 016.661 000.014 000.014: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/json5.vim 016.691 000.013 000.013: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/julia.vim 016.727 000.016 000.016: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/ledger.vim 016.758 000.011 000.011: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/nix.vim 016.799 000.015 000.015: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/ql.vim 016.847 000.027 000.027: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/query.vim 016.882 000.016 000.016: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/surface.vim 016.911 000.012 000.012: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/teal.vim 016.939 000.011 000.011: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/tlaplus.vim 016.980 000.023 000.023: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/yang.vim 017.012 000.014 000.014: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/zig.vim 017.427 007.632 007.258: sourcing /usr/share/nvim/runtime/filetype.vim 017.645 000.035 000.035: sourcing /usr/share/nvim/runtime/ftplugin.vim 017.850 000.028 000.028: sourcing /usr/share/nvim/runtime/indent.vim 018.385 000.267 000.267: sourcing /usr/share/nvim/runtime/syntax/syncolor.vim 018.637 000.569 000.302: sourcing /usr/share/nvim/runtime/syntax/synload.vim 018.723 000.703 000.134: sourcing /usr/share/nvim/runtime/syntax/syntax.vim 019.702 000.380 000.380: sourcing /usr/share/nvim/runtime/plugin/gzip.vim 019.739 000.013 000.013: sourcing /usr/share/nvim/runtime/plugin/health.vim 019.844 000.089 000.089: sourcing /usr/share/nvim/runtime/plugin/man.vim 020.333 000.186 000.186: sourcing /usr/share/nvim/runtime/pack/dist/opt/matchit/plugin/matchit.vim 020.423 000.555 000.368: sourcing /usr/share/nvim/runtime/plugin/matchit.vim 020.581 000.140 000.140: sourcing /usr/share/nvim/runtime/plugin/matchparen.vim 020.985 000.383 000.383: sourcing /usr/share/nvim/runtime/plugin/netrwPlugin.vim 021.177 000.013 000.013: sourcing /home/atomsky/.local/share/nvim/rplugin.vim 021.184 000.159 000.146: sourcing /usr/share/nvim/runtime/plugin/rplugin.vim 021.302 000.099 000.099: sourcing /usr/share/nvim/runtime/plugin/shada.vim 021.357 000.025 000.025: sourcing /usr/share/nvim/runtime/plugin/spellfile.vim 021.517 000.134 000.134: sourcing /usr/share/nvim/runtime/plugin/tarPlugin.vim 021.626 000.079 000.079: sourcing /usr/share/nvim/runtime/plugin/tohtml.vim 021.670 000.018 000.018: sourcing /usr/share/nvim/runtime/plugin/tutor.vim 021.857 000.166 000.166: sourcing /usr/share/nvim/runtime/plugin/zipPlugin.vim 022.681 000.723 000.723: sourcing /usr/share/vim/vimfiles/plugin/fzf.vim 026.472 000.026 000.026: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/cls.vim 026.536 000.022 000.022: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tex.vim 026.587 000.020 000.020: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tikz.vim 026.594 003.793 003.725: sourcing /home/atomsky/.config/nvim/plugin/packer_compiled.lua 026.803 001.890: loading plugins 028.597 001.618 001.618: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/plugin/nvim-treesitter.vim 028.973 000.028 000.028: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/elixir.vim 029.014 000.012 000.012: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/fennel.vim 029.052 000.015 000.015: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/fish.vim 029.089 000.014 000.014: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gdresource.vim 029.120 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gdscript.vim 029.149 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/glimmer.vim 029.183 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gomod.vim 029.219 000.015 000.015: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/graphql.vim 029.257 000.016 000.016: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/hcl.vim 029.290 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/heex.vim 029.320 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/hjson.vim 029.350 000.009 000.009: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/json5.vim 029.379 000.009 000.009: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/julia.vim 029.417 000.014 000.014: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/ledger.vim 029.447 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/nix.vim 029.481 000.011 000.011: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/ql.vim 029.520 000.018 000.018: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/query.vim 029.551 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/surface.vim 029.609 000.012 000.012: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/teal.vim 029.642 000.010 000.010: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/tlaplus.vim 029.672 000.009 000.009: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/yang.vim 029.701 000.009 000.009: sourcing /home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/zig.vim 029.867 001.177: loading packages 030.041 000.174: loading after plugins 030.054 000.013: inits 3 032.292 002.238: reading ShaDa 032.550 000.258: opening buffers 032.593 000.043: BufEnter autocommands 032.596 000.004: editing files in windows 032.673 000.076: VimEnter autocommands 032.675 000.002: UIEnter autocommands 032.677 000.002: before starting main loop 033.224 000.547: first screen update 033.227 000.003: --- NVIM STARTED ---
packer compiled file
```lua -- Automatically generated packer.nvim plugin loader code if vim.api.nvim_call_function('has', {'nvim-0.5'}) ~= 1 then vim.api.nvim_command('echohl WarningMsg | echom "Invalid Neovim version for packer.nvim! | echohl None"') return end vim.api.nvim_command('packadd packer.nvim') local no_errors, error_msg = pcall(function() local time local profile_info local should_profile = false if should_profile then local hrtime = vim.loop.hrtime profile_info = {} time = function(chunk, start) if start then profile_info[chunk] = hrtime() else profile_info[chunk] = (hrtime() - profile_info[chunk]) / 1e6 end end else time = function(chunk, start) end end local function save_profiles(threshold) local sorted_times = {} for chunk_name, time_taken in pairs(profile_info) do sorted_times[#sorted_times + 1] = {chunk_name, time_taken} end table.sort(sorted_times, function(a, b) return a[2] > b[2] end) local results = {} for i, elem in ipairs(sorted_times) do if not threshold or threshold and elem[2] > threshold then results[i] = elem[1] .. ' took ' .. elem[2] .. 'ms' end end _G._packer = _G._packer or {} _G._packer.profile_output = results end time([[Luarocks path setup]], true) local package_path_str = "/home/atomsky/.cache/nvim/packer_hererocks/2.0.5/share/lua/5.1/?.lua;/home/atomsky/.cache/nvim/packer_hererocks/2.0.5/share/lua/5.1/?/init.lua;/home/atomsky/.cache/nvim/packer_hererocks/2.0.5/lib/luarocks/rocks-5.1/?.lua;/home/atomsky/.cache/nvim/packer_hererocks/2.0.5/lib/luarocks/rocks-5.1/?/init.lua" local install_cpath_pattern = "/home/atomsky/.cache/nvim/packer_hererocks/2.0.5/lib/lua/5.1/?.so" if not string.find(package.path, package_path_str, 1, true) then package.path = package.path .. ';' .. package_path_str end if not string.find(package.cpath, install_cpath_pattern, 1, true) then package.cpath = package.cpath .. ';' .. install_cpath_pattern end time([[Luarocks path setup]], false) time([[try_loadstring definition]], true) local function try_loadstring(s, component, name) local success, result = pcall(loadstring(s)) if not success then vim.schedule(function() vim.api.nvim_notify('packer.nvim: Error running ' .. component .. ' for ' .. name .. ': ' .. result, vim.log.levels.ERROR, {}) end) end return result end time([[try_loadstring definition]], false) time([[Defining packer_plugins]], true) _G.packer_plugins = { ["impatient.nvim"] = { loaded = true, path = "/home/atomsky/.local/share/nvim/site/pack/packer/start/impatient.nvim", url = "https://github.com/lewis6991/impatient.nvim" }, ["nvim-treesitter"] = { config = { "\27LJ\1\2i\0\0\3\0\6\0\t4\0\0\0%\1\1\0>\0\2\0027\0\2\0003\1\4\0003\2\3\0:\2\5\1>\0\2\1G\0\1\0\14highlight\1\0\0\1\0\1\venable\2\nsetup\28nvim-treesitter.configs\frequire\0" }, loaded = true, path = "/home/atomsky/.local/share/nvim/site/pack/packer/start/nvim-treesitter", url = "https://github.com/nvim-treesitter/nvim-treesitter" }, ["packer.nvim"] = { loaded = true, path = "/home/atomsky/.local/share/nvim/site/pack/packer/start/packer.nvim", url = "https://github.com/wbthomason/packer.nvim" }, playground = { commands = { "TSPlaygroundToggle" }, loaded = false, needs_bufread = true, only_cond = false, path = "/home/atomsky/.local/share/nvim/site/pack/packer/opt/playground", url = "https://github.com/nvim-treesitter/playground" }, ["plenary.nvim"] = { loaded = false, needs_bufread = false, path = "/home/atomsky/.local/share/nvim/site/pack/packer/opt/plenary.nvim", url = "https://github.com/nvim-lua/plenary.nvim" }, ["telescope.nvim"] = { commands = { "Telescope" }, loaded = false, needs_bufread = true, only_cond = false, path = "/home/atomsky/.local/share/nvim/site/pack/packer/opt/telescope.nvim", url = "https://github.com/nvim-telescope/telescope.nvim", wants = { "plenary.nvim" } }, vimtex = { config = { "\27LJ\1\2<\0\0\2\0\4\0\0054\0\0\0007\0\1\0%\1\3\0:\1\2\0G\0\1\0\fzathura\23vimtex_view_method\6g\bvim\0" }, loaded = false, needs_bufread = true, only_cond = false, path = "/home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex", url = "https://github.com/lervag/vimtex" } } time([[Defining packer_plugins]], false) -- Config for: nvim-treesitter time([[Config for nvim-treesitter]], true) try_loadstring("\27LJ\1\2i\0\0\3\0\6\0\t4\0\0\0%\1\1\0>\0\2\0027\0\2\0003\1\4\0003\2\3\0:\2\5\1>\0\2\1G\0\1\0\14highlight\1\0\0\1\0\1\venable\2\nsetup\28nvim-treesitter.configs\frequire\0", "config", "nvim-treesitter") time([[Config for nvim-treesitter]], false) -- Command lazy-loads time([[Defining lazy-load commands]], true) pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSPlaygroundToggle lua require("packer.load")({'playground'}, { cmd = "TSPlaygroundToggle", l1 =