neovim / neovim

Vim-fork focused on extensibility and usability

Home Page:https://neovim.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Source lua files from plugin directories (and ftplugin, colors, etc)

clason opened this issue · comments

Splitting this out from #7895 (comment) since it's a separate issue.

Similarly to init.lua support, neovim should allow lua files in user plugin directories ($XDG_CONFIG_HOME/nvim/plugin, $XDG_CONFIG_HOME/nvim/ftplugin, etc.) as well. This is particularly useful for pure lua plugins installed via native packages (e.g., through https://github.com/wbthomason/packer.nvim), since these packages -- even in /start/ -- are by default not sourced until after init.vim (and, presumably, init.lua once supported) is sourced. This means one would have to either manually packadd each Lua package, or create a vimscript shim in $XDG_CONFIG_HOME/nvim/plugin.

As a starter, it would probably suffice to add a lua version after

source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
that calls
void ex_luafile(exarg_T *const eap)
on each lua file found in the same paths.

@tjdevries

I can't remember if we said that it should take priority over .vim files or just source side-by-side?

plugin/my_plug.vim and plugin/my_plug.lua should both be sourced? (it seems yes, because they get sourced in other directories, and it's not like startup where there is always only "one" startup file).

I think they should be treated independently (init.lua is a special case); the order is indeed a matter for discussion (all lua first? all vim first? alphabetically, with lua/vim first? the second seems easiest for starters).

(To be honest, I think the same argument could be made for init.lua -- I see good reasons to allow for both, as long as the precedence is clear; my gut feeling is "vim first", without being able to give a good example for it.)

I'm interested in this topic as well,

RE: ftplugin

As brought up in #12378 (comment), ftplugin is merely syntactic sugar around autocmd.

augroup filetypeplugin
au FileType * call s:LoadFTPlugin()
func! s:LoadFTPlugin()
if exists("b:undo_ftplugin")
exe b:undo_ftplugin
unlet! b:undo_ftplugin b:did_ftplugin
endif
let s = expand("<amatch>")
if s != ""
if &cpo =~# "S" && exists("b:did_ftplugin")
" In compatible mode options are reset to the global values, need to
" set the local values also when a plugin was already used.
unlet b:did_ftplugin
endif
" When there is a dot it is used to separate filetype names. Thus for
" "aaa.bbb" load "aaa" and then "bbb".
for name in split(s, '\.')
exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim'
endfor
endif
endfunc
augroup END

How it works:

  1. Define a augroup
  2. Define a autocmd that triggers on all filetypes
  3. Invoke function that retrieves the filetype and executes the corresponding ftplugin file using runtime

Extending this logic to search for a .lua file in conjunction to a .vim file can be achieved with minimal code changes.

This is also how https://github.com/tjdevries/astronauta.nvim approaches this.

diff --git a/runtime/ftplugin.vim b/runtime/ftplugin.vim
index a434b93..2877e77 100644
--- a/runtime/ftplugin.vim
+++ b/runtime/ftplugin.vim
@@ -29,6 +29,10 @@ augroup filetypeplugin
       " "aaa.bbb" load "aaa" and then "bbb".
       for name in split(s, '\.')
 	exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim'
+
+	if filereadable('ftplugin/' . name . '.lua')
+	  luafile 'ftplugin/' . name . '.lua'
+	endif
       endfor
     endif
   endfunc

@tjdevries WDYT ?

I think they should be treated independently (init.lua is a special case); the order is indeed a matter for discussion (all lua first? all vim first? alphabetically, with lua/vim first? the second seems easiest for starters).

(To be honest, I think the same argument could be made for init.lua -- I see good reasons to allow for both, as long as the precedence is clear; my gut feeling is "vim first", without being able to give a good example for it.)

I agree that vim first, lua second is what I anticipate to be the expected order. I think it's up to plugin authors and users to ensure these configs don't conflict.