Structure of Lua plugins

I’m working on converting some of my VimL 8 plugins to Lua finally, and while I understand Lua/Fennel at it’s core I am quite confused how to actually bring it all together to make a plugin. In particular I have a handful of things I would like help with

  1. User config: I want users to be able to modify the plugin clearly, and while I understand the concept of the init file exporting functions and tables for users, I’m quite confused how I, the developer, am supposed to work with the configs. I can’t seem to simply call the config table inside other Lua files:
-- file 1
local M = {}
M.config = {
  blah = blah,
  blah = blah
return M

-- file 2
local configs = myplugin.file1.config -- fails
local configs = require("myplugin.file1").config -- can't parse table

I’m not sure what I’m missing here, and I’ve looked around in other plugins and got very confused as to how they did this themselves. Also excuse any minor syntax errors, tried a lot so I might have forgotten the right bits there

  1. Testing In the same session: While I can test the fennel side just fine, I do need to be able to test the user Lua side easier and setting up a new NeoVim session every time drastically reduces how fast I can work. With VimL 8 I could just simply source the files needed, but I can’t seem to do that here

This setup should work:

~/.config/nvim/    (or anywhere in runtimepath)


local M = {}
M.config = {
  blah = blah,
  blah = blah
return M


local configs = require("myplugin.file1").config

Maybe the problem is that you were missing the init.lua in the first myplugin directory? As far as I know, Lua always needs an init.lua file in order to flag a directory as a module. You can also put code directly in myplugin/init.lua, in which case it will be available under require('myplugin').

Note that I actually can’t find where this is written in the Lua 5.1 docs. My understanding of this is from reading other people’s code and making educated guesses from how things work in Python. But I have several distinct modules configured this way and it all works fine.

That didn’t seem to help me. I put my config table in the init.lua file, yet when I require it in another file with local configs = require("myplugin.init").config, if I try to get data from it, NeoVim complains that I’m indexing an upvalue of all things

You would write require('myplugin'), not require('myplugin.init').

The init.lua file is the top level myplugin module.

I’m confused, I tried that and its saying loop or previous error loading module ... when I require the init file inside the file I want to source the config info from. My file tree is something like this:


Can you show the contents of those files as well? If you copied and pasted my example files it would have worked, so something must be different in your setup.

Also, did you mess with the Lua package path? That could also prevent the init.lua from being used. See here: Lua - Question on modules - Stack Overflow

-- init.lua
local M = {}
M.config = {
  fileExt = { "obl", 
  test = true
M.setup = function(userOpts)
  return print("hello")
return M
-- file that sources from init
local i = (require("obluavim")).config
local getLog
  local output = i.fileExt
  return print(output)

What’s utils.getLog(), in the first file? Is local getLog supposed to be a function definition, in the 2nd file? What are these 2 files named? It looks like you might have a circular dependency.