Like the title says the ft option doesn't always work e.g. when I do use {tpope/vim-fireplace, ft='clojure'} it seems to work properly, but when I do use {'slashmili/alchemist.vim', ft = 'elixir'} it won't load alchemist. Log file says Sourcing $HOME/path/to/opt/alchemist but it doesn't load. I also use vim-polyglot if it matters and I tried to load alchemist after polyglot, but the result is the same. My plugins.lua for reference:
vim.api.nvim_command('packadd packer.nvim')
return require('packer').startup(function()
use {'wbthomason/packer.nvim', opt = true}
use 'srcery-colors/srcery-vim'
use 'dracula/vim'
-------------langs-----------
use 'sheerun/vim-polyglot' -- One for all
--------------QoL------------
use 'tpope/vim-surround' -- Surround everything
use 'scrooloose/nerdcommenter' -- Smart comments
use 'honza/vim-snippets'
use 'SirVer/ultisnips'
use 'jiangmiao/auto-pairs' -- Auto pairs
use 'vimwiki/vimwiki'
use {
'luochen1990/rainbow',
ft = {'clojure'},
}
use {
'Yggdroot/indentLine',
ft = {'nim'},
}
use 'easymotion/vim-easymotion'
use 'romgrk/barbar.nvim' -- Best bufferline
use 'glepnir/galaxyline.nvim'
use 'farmergreg/vim-lastplace'
-------------dev tools---------
use 'majutsushi/tagbar' -- too good to be true
use {'jaxbot/browserlink.vim', ft = { 'html','css','javascript' }} -- preview
use {'tpope/vim-fireplace', ft = 'clojure' } -- enables clojure development
use 'kyazdani42/nvim-tree.lua'
use {'slashmili/alchemist.vim', ft = 'elixir'}
---------------git------------
use 'tpope/vim-fugitive' -- this should be illegal
use 'mhinz/vim-signify'
use 'tpope/vim-rhubarb'
--------nvim-lsp---------
use 'neovim/nvim-lspconfig'
use 'nvim-lua/diagnostic-nvim'
use 'nvim-lua/completion-nvim'
use 'nvim-lua/lsp_extensions.nvim'
use 'steelsojka/completion-buffers'
use 'tjdevries/nlua.nvim'
-------------telescope---------
use {
'nvim-lua/telescope.nvim',
requires = {'nvim-lua/popup.nvim', 'nvim-lua/plenary.nvim'}
}
-------------lsputils---------
use {
'RishabhRD/nvim-lsputils',
requires = 'RishabhRD/popfix'
}
--------------misc------------
use {'ron-rs/ron.vim', ft = 'ron'}
use 'nvim-treesitter/nvim-treesitter'
use 'kyazdani42/nvim-web-devicons'
use 'norcalli/nvim-colorizer.lua'
end)
Interesting. Given that you say it works for Clojure, I assume you're using PackerCompile correctly. Could you please post your compiled file here, and I'll take a look to see if I can figure out what's going on?
This is the compiled file. I also checked the indentLine and ron.vim plugins which I use for nim and ron files respectively. They don't work either.
" Automatically generated packer.nvim plugin loader code
if !has('nvim')
finish
endif
lua << END
local plugins = {
["alchemist.vim"] = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/alchemist.vim"
},
["browserlink.vim"] = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/browserlink.vim"
},
indentLine = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/indentLine"
},
["packer.nvim"] = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/packer.nvim"
},
rainbow = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/rainbow"
},
["ron.vim"] = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/ron.vim"
},
["vim-fireplace"] = {
loaded = false,
only_sequence = false,
only_setup = false,
path = "/home/kwstas/.local/share/nvim/site/pack/packer/opt/vim-fireplace"
}
}
local function handle_bufread(names)
for _, name in ipairs(names) do
local path = plugins[name].path
for _, dir in ipairs({ 'ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin' }) do
if #vim.fn.finddir(dir, path) > 0 then
vim.cmd('doautocmd BufRead')
return
end
end
end
end
_packer_load = nil
local function handle_after(name, before)
local plugin = plugins[name]
plugin.load_after[before] = nil
if next(plugin.load_after) == nil then
_packer_load({name}, {})
end
end
_packer_load = function(names, cause)
local some_unloaded = false
for _, name in ipairs(names) do
if not plugins[name].loaded then
some_unloaded = true
break
end
end
if not some_unloaded then return end
local fmt = string.format
local del_cmds = {}
local del_maps = {}
for _, name in ipairs(names) do
if plugins[name].commands then
for _, cmd in ipairs(plugins[name].commands) do
del_cmds[cmd] = true
end
end
if plugins[name].keys then
for _, key in ipairs(plugins[name].keys) do
del_maps[key] = true
end
end
end
for cmd, _ in pairs(del_cmds) do
vim.cmd('silent! delcommand ' .. cmd)
end
for key, _ in pairs(del_maps) do
vim.cmd(fmt('silent! %sunmap %s', key[1], key[2]))
end
for _, name in ipairs(names) do
if not plugins[name].loaded then
vim.cmd('packadd ' .. name)
if plugins[name].config then
for _i, config_line in ipairs(plugins[name].config) do
loadstring(config_line)()
end
end
if plugins[name].after then
for _, after_name in ipairs(plugins[name].after) do
handle_after(after_name, name)
vim.cmd('redraw')
end
end
plugins[name].loaded = true
end
end
handle_bufread(names)
if cause.cmd then
local lines = cause.l1 == cause.l2 and '' or (cause.l1 .. ',' .. cause.l2)
vim.cmd(fmt('%s%s%s %s', lines, cause.cmd, cause.bang, cause.args))
elseif cause.keys then
local keys = cause.keys
local extra = ''
while true do
local c = vim.fn.getchar(0)
if c == 0 then break end
extra = extra .. vim.fn.nr2char(c)
end
if cause.prefix then
local prefix = vim.v.count and vim.v.count or ''
prefix = prefix .. '"' .. vim.v.register .. cause.prefix
if vim.fn.mode('full') == 'no' then
if vim.v.operator == 'c' then
prefix = '' .. prefix
end
prefix = prefix .. vim.v.operator
end
vim.fn.feedkeys(prefix, 'n')
end
-- NOTE: I'm not sure if the below substitution is correct; it might correspond to the literal
-- characters \<Plug> rather than the special <Plug> key.
vim.fn.feedkeys(string.gsub(string.gsub(cause.keys, '^<Plug>', '\\<Plug>') .. extra, '<[cC][rR]>', '\r'))
elseif cause.event then
vim.cmd(fmt('doautocmd <nomodeline> %s', cause.event))
elseif cause.ft then
vim.cmd(fmt('doautocmd <nomodeline> %s FileType %s', 'filetypeplugin', cause.ft))
vim.cmd(fmt('doautocmd <nomodeline> %s FileType %s', 'filetypeindent', cause.ft))
end
end
-- Runtimepath customization
-- Pre-load configuration
-- Setup for: indentLine
loadstring("\27LJ\2\0023\0\0\2\0\4\0\0056\0\0\0009\0\1\0'\1\3\0=\1\2\0K\0\1\0\6|\20indentLine_char\6g\bvim\0")()
-- Setup for: rainbow
loadstring("\27LJ\2\0020\0\0\2\0\3\0\0056\0\0\0009\0\1\0)\1\1\0=\1\2\0K\0\1\0\19rainbow_active\6g\bvim\0")()
-- Post-load configuration
-- Conditional loads
-- Load plugins in order defined by `after`
END
function! s:load(names, cause) abort
call luaeval('_packer_load(_A[1], _A[2])', [a:names, a:cause])
endfunction
" Command lazy-loads
" Keymap lazy-loads
augroup packer_load_aucmds
au!
" Filetype lazy-loads
au FileType javascript ++once call s:load(['browserlink.vim'], { "ft": "javascript" })
au FileType css ++once call s:load(['browserlink.vim'], { "ft": "css" })
au FileType clojure ++once call s:load(['vim-fireplace', 'rainbow'], { "ft": "clojure" })
au FileType elixir ++once call s:load(['alchemist.vim'], { "ft": "elixir" })
au FileType ron ++once call s:load(['ron.vim'], { "ft": "ron" })
au FileType nim ++once call s:load(['indentLine'], { "ft": "nim" })
au FileType html ++once call s:load(['browserlink.vim'], { "ft": "html" })
" Event lazy-loads
augroup END
Interesting - the FileType commands seem to be uniformly and correctly generated. Could you please tell me what :set filetype reports in an Elixir/Ron/Nim file with this configuration? I suspect that the FileType event is never triggering, but alchemist.vim doesn't look like it defines a ftdetect script, and you said you tried loading polyglot first, so I'm not sure why that would happen...
The filetypes for elixir and nim are correct. The filetype for ron is empty which I guess makes sense since it needs the plugin, but when I used vim-plug and did Plug 'ron-rs/ron.vim', {'for': 'ron'} it worked fine. I'm not sure I loaded polyglot first correctly though. I tried using the after option like after = 'sheerun/vim-polyglot' and after = 'vim-polyglot', but none of them worked.
I have tested this with a clean instance of Neovim (no plugins or config) and... this looks like it could be a quirk of :packadd?
This works:
slashmili/alchemist.vim in start:scriptnames reveals that after/plugin/alchemist.vim has been sourcedThis doesn't:
slashmili/alchemist.vim in opt:packadd alchemist.vim:scriptnames reveals that after/plugin/alchemist.vim has not been sourcedIt only seems to affect files in after/plugin. I have no idea if this is the intended behavior or not.
Yeah when I tried without the ft option everything worked fine. Maybe I should fine another workaround.
@bfredl is there any chance the recent changes to native packages could be affecting this?
@nanotee thanks for testing that!
If this is "working as intended" for packadd, then perhaps I should add a manual check + sourcing for after/* files...
dunno, someone else had a similar problem and then it turned out something else was a problem. after/ behaviour is not changed by my recent changes at least :D
Hmm it is a little bit suspicious that packer.nvim is manually doing after/ stuff at all. the core plugin code (already the code inherited from vim) is _supposed_ to handle all that (if it does not I will fix it)
So, unless I'm forgetting something I implemented, we currently aren't doing anything manually with after/. It's just that we might have to add something to manually source files in if this problem reproduces and isn't an issue with packadd.
I was just reading what the "Automatically generated packer.nvim plugin loader code" was doing but maybe I misunderstood it.
Ah - if you're referring to the handle_after function, that's for handling packer's sequence loading keyword, which is (confusingly) also after.
Looks like this is the intended behavior: https://github.com/vim/vim/issues/1994
Unfortunate (but thanks @nanotee for the find!)
packer could add manual handling of after/plugin/, but, as @bfredl mentions, that seems fishy/like maybe a bad idea. Still, given that I disagree with the reasoning in https://github.com/vim/vim/issues/1994 (it may be an anti-pattern, but plugins should still be sourced the same whether or not they're in start or opt), this might be the best way to go.
We (neovim core) are not bound by unfortunate desicions made by vim. We should change opt/ handling in neovim core to respect the existing after/ pattern properly handled by all plugin/package solutions other than brampackages.
Hmm, opt/xx/after/plugin/xx.vim actually work for me when packadd! xx. Is there a complete minimal example of a config where it does not work?
I think the config @nanotee describes here is probably the closest to a complete minimal config demonstrating the behavior.
@bfredl Interestingly, packadd xx on its own in init.vim seems to work, but the following doesn't source files in after/plugin:
autocmd VimEnter * packadd xx
I just ran into an issue with whonore/Coqtail#162 that might also fall under the scope of this issue. Precisely, it is a syntax file which does not get sourced when restricted to only load on its own filetype (using :scriptnames confirms this):
use {'whonore/Coqtail', ft='coq'}
nvim foo.v # no syntax highlighting
nvim foo.coq # no syntax highlighting
But, if I run :setf coq one more time, the highlighting happens.
To compare, doing:
Plug 'whonore/Coqtail', {'for': 'coq'}
works.
To workaround this issue, I created the following file:
" ~/.config/nvim/ftplugin/coq/filetype.vim
setf coq
And it works.
Do you also encounter this error when packadding the plugin manually? i.e. does this seem to be an issue with how packer implements ft vs. how vim-plug implements for, or with how Neovim/Vim implement native packages?
Yeah, packadding manually makes it work. This is what I did:
use for Coqtail:lua
-- use {'whonore/Coqtail', ft='coq'}
:PackerCompile~/.config/nvim/ftplugin/coq/filetype.vim:
packadd Coqtail
That makes it work.
Edit: to clarify, it seems this is not an issue with the Neo/vim package implementation. Rather, a load order issue.
Well, that's unfortunate.
It looks like vim-plug does some explicit sourcing to handle this case (https://github.com/junegunn/vim-plug/blob/master/plug.vim#L387); perhaps packer needs something similar...
Should I make a separate issue for that?
I added a mechanism to fix a related issue in #215; I should be able to extend it to also handle this case.
@Iron-E: I think 993eaad fixes this (at least, I can no longer reproduce your Coqtail issue). Please reopen if you're still seeing problems, and thanks for your patience on this!
Awesome! Glad to see this fixed.
Most helpful comment
We (neovim core) are not bound by unfortunate desicions made by vim. We should change
opt/handling in neovim core to respect the existingafter/pattern properly handled by all plugin/package solutions other than brampackages.