packer.nvim icon indicating copy to clipboard operation
packer.nvim copied to clipboard

ftdetect files are sourced twice

Open ATM-Jahid opened this issue 4 years ago • 14 comments

  • nvim --version:
NVIM v0.5.1
Build type: Release
LuaJIT 2.0.5
Compilation: /usr/bin/cc -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -O2 -DNDEBUG -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/build/neovim/src/neovim-0.5.1/build/config -I/build/neovim/src/neovim-0.5.1/src -I/usr/include -I/build/neovim/src/neovim-0.5.1/build/src/nvim/auto -I/build/neovim/src/neovim-0.5.1/build/include
Compiled by builduser

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:
git version 2.34.0
  • Operating system/version:
OS: Arch Linux x86_64
Kernel: 5.15.2-arch1-1

Steps to reproduce

Install plugins having ftdetect folders. The plugins can be in start or opt directories of packer.nvim. Running nvim --startuptime log will list the sourced files.

Actual behaviour

The files in ftdetect folders are sourced twice. My guess is neovim is sourcing these files the first time and then packer is doing it again.

nvim --startuptime log
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 ---

Expected behaviour

Sourcing necessary files only once.

packer files

Plugin specification file(s)
return require('packer').startup(function(use)
	use 'wbthomason/packer.nvim'
	use 'lewis6991/impatient.nvim'

	use {
		'nvim-treesitter/nvim-treesitter',
		run = ':TSUpdate',
		config = function()
			require('nvim-treesitter.configs').setup {
				highlight = {enable = true}
			}
		end,
	}
	use {
		'nvim-treesitter/playground',
		cmd = 'TSPlaygroundToggle',
	}

	use {
		'nvim-telescope/telescope.nvim',
		cmd = 'Telescope',
		requires = {{'nvim-lua/plenary.nvim', opt = true}},
		wants = {'plenary.nvim'},
	}

	use {
		'lervag/vimtex',
		ft = 'tex',
		config = function()
			vim.g.vimtex_view_method = 'zathura'
		end,
	}
end)

packer compiled file
-- 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 = <line1>, l2 = <line2>, bang = <q-bang>, args = <q-args>, mods = "<mods>" }, _G.packer_plugins)]])
pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file Telescope lua require("packer.load")({'telescope.nvim'}, { cmd = "Telescope", l1 = <line1>, l2 = <line2>, bang = <q-bang>, args = <q-args>, mods = "<mods>" }, _G.packer_plugins)]])
time([[Defining lazy-load commands]], false)

vim.cmd [[augroup packer_load_aucmds]]
vim.cmd [[au!]]
  -- Filetype lazy-loads
time([[Defining lazy-load filetype autocommands]], true)
vim.cmd [[au FileType tex ++once lua require("packer.load")({'vimtex'}, { ft = "tex" }, _G.packer_plugins)]]
time([[Defining lazy-load filetype autocommands]], false)
vim.cmd("augroup END")
vim.cmd [[augroup filetypedetect]]
time([[Sourcing ftdetect script at: /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/cls.vim]], true)
vim.cmd [[source /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/cls.vim]]
time([[Sourcing ftdetect script at: /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/cls.vim]], false)
time([[Sourcing ftdetect script at: /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tex.vim]], true)
vim.cmd [[source /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tex.vim]]
time([[Sourcing ftdetect script at: /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tex.vim]], false)
time([[Sourcing ftdetect script at: /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tikz.vim]], true)
vim.cmd [[source /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tikz.vim]]
time([[Sourcing ftdetect script at: /home/atomsky/.local/share/nvim/site/pack/packer/opt/vimtex/ftdetect/tikz.vim]], false)
vim.cmd("augroup END")
if should_profile then save_profiles() end

end)

if not no_errors then
  vim.api.nvim_command('echohl ErrorMsg | echom "Error in packer_compiled: '..error_msg..'" | echom "Please check your config for correctness" | echohl None')
end

ATM-Jahid avatar Nov 17 '21 06:11 ATM-Jahid

@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 avatar Nov 17 '21 10:11 akinsho

@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 avatar Nov 17 '21 15:11 ATM-Jahid

@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.

akinsho avatar Nov 17 '21 16:11 akinsho

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 avatar Nov 28 '21 10:11 HiPhish

@HiPhish To clarify, you have this issue even with a version of Neovim after the upstream patch you linked?

wbthomason avatar Nov 30 '21 20:11 wbthomason

@wbthomason Yes, my exact version is 0.5.1 with LuaJIT 2.1.0-beta3, from the Void repos.

HiPhish avatar Nov 30 '21 21:11 HiPhish

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 avatar Nov 30 '21 21:11 wbthomason

@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

HiPhish avatar Nov 30 '21 22:11 HiPhish

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 avatar Dec 28 '22 07:12 amano-kenji

@amano-kenji That only happens when you lazy-load, or also on normal loads?

wbthomason avatar Jan 11 '23 01:01 wbthomason

normal loads don't cause the issue. Only lazy-load through ft does.

amano-kenji avatar Jan 11 '23 05:01 amano-kenji

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 ftdetects 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.

wbthomason avatar Jan 11 '23 06:01 wbthomason

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.

amano-kenji avatar Jan 11 '23 08:01 amano-kenji

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):

  • the second autocommand (created when packer sources the ftdetect file) calls DetectJanet
  • DetectJanet sets the filetype to janet
  • This triggers the FileType event packer defined to lazy-load janet.vim
  • While resolving that event, Neovim sources 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 it
  • You get an error

In 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.

wbthomason avatar Jan 11 '23 21:01 wbthomason