Neovim lua unable to load config from different file - lua

I am unable to load config when using require. Form below you can see that I added 2 files under the lua directory
lua/bufferline.lua
lua/plugins/bufferline.lua
I am tried loading both via
-- Bufferline
use {
"akinsho/bufferline.nvim",
tag = "v3.*",
requires = 'nvim-tree/nvim-web-devicons',
config = [[require("bufferline")]]
-- config = [[require("plugins/bufferline")]]
} -- buffer list with icons
And both failed to load the config changes. But adding the config inline in the plugins.lua the config shows up when restring.
Please check below for my files
lua directory structure
> tree
├── bufferline.lua
├── colorscheme.lua
├── keymaps.lua
├── options.lua
├── plugins
│   └── bufferline.lua
├── plugins.lua
init.lua
require "options"
require "keymaps"
require "plugins"
require "colorscheme"
plugins.lua
--
-- Automatically install packer
local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
if fn.empty(fn.glob(install_path)) > 0 then
PACKER_BOOTSTRAP = fn.system {
"git",
"clone",
"--depth",
"1",
"https://github.com/wbthomason/packer.nvim",
install_path,
}
print "Installing packer close and reopen Neovim..."
vim.cmd [[packadd packer.nvim]]
end
-- Autocommand that reloads neovim whenever you save the plugins.lua file
vim.cmd [[
augroup packer_user_config
autocmd!
autocmd BufWritePost plugins.lua source <afile> | PackerSync
augroup end
]]
-- Use a protected call so we don't error out on first use
local status_ok, packer = pcall(require, "packer")
if not status_ok then
return
end
-- Have packer use a popup window
packer.init {
display = {
open_fn = function()
return require("packer.util").float { border = "rounded" }
end,
},
}
-- Install your plugins here
return packer.startup(function(use)
use "wbthomason/packer.nvim" -- Have packer manage itself
use "nvim-lua/popup.nvim" -- An implementation of the Popup API from vim in Neovim
use "nvim-lua/plenary.nvim" -- Useful lua functions used ny lots of plugins
-- Bufferline
use {
"akinsho/bufferline.nvim",
tag = "v3.*",
requires = 'nvim-tree/nvim-web-devicons',
config = [[require("bufferline")]]
-- config = [[require("plugins/bufferline")]]
} -- buffer list with icons
-- require("bufferline").setup{
-- options = {
-- numbers = "buffer_id",
-- always_show_bufferline = true,
-- separator_style = "thin"
-- }
-- }
use "christoomey/vim-tmux-navigator" -- navigate between tmux and nvim
--
-- Automatically set up your configuration after cloning packer.nvim
-- Put this at the end after all plugins
if PACKER_BOOTSTRAP then
require("packer").sync()
end
end)

I think the general problem here is, that you're using the double brackets for the config = option:
config = [[require("bufferline")]]
As far as I know (my lua skills aren't that great) those double brackets ([[) are used to create a raw string in lua, so you're basically giving config a string which, I assume, vim tries to execute it as vimscript-code.
A solution for that is simply stick to lua and convert your config = line to the following:
config = function() require("bufferline") end,
so in total in should look like this:
-- Bufferline
use {
"akinsho/bufferline.nvim",
tag = "v3.*",
requires = 'nvim-tree/nvim-web-devicons',
config = function() require("bufferline") end,
} -- buffer list with icons
Important hint
You may also need to rename your bufferline.lua file because the module-name of the plugin already uses the name bufferline so require("bufferline") will actually get the module but not your bufferline.lua!

Related

Is there a way in lua to define a function that will run if a file is required?

I would like to create a lua function early in a script that will then automatically get called if a matching filename is required but before that require is complete.
effectively it will go
if FILE then
run before FILE is loaded
end
-- some other stuff
require"FILE"
If FILE is never required then the stuff in the if will never run
require is just a function so you can redefine it.
$ cat foo.lua
real_require = require
function require(mod)
if mod == 'string' then
-- do something
print('importing ' .. mod)
end
return real_require(mod)
end
require'string'
$ lua foo.lua
importing string
$

How to source init.lua without restarting neovim

Is there a clean way to reload a neovim init.lua config and all its modules (using the require() function) without restarting neovim?
I've read on another post that :luafile $MYVIMRC was supposed to accomplish just that but it doesn't reload those cached files unfortunately. I'm hoping to setup a keymap like I used to have in my previous init.vim config. Something along the lines of:
local opts = { noremap = true, silent = true }
vim.api.nvim_set_keymap("n", "<leader><CR>", ":luafile $MYVIMRC<CR>", opts)
I'm on nvim v0.8.0.
Try to run this command :
:luafile %
If found an answer from creativenull on this reddit thread that seems to work well. I ended up creating a small module called reload.lua:
function _G.ReloadConfig()
for name,_ in pairs(package.loaded) do
if name:match('^user') and not name:match('nvim-tree') then
package.loaded[name] = nil
end
end
dofile(vim.env.MYVIMRC)
vim.notify("Nvim configuration reloaded!", vim.log.levels.INFO)
end
That gets imported in init.lua:
require 'user.reload'
And for which I added a keymap:
vim.api.nvim_set_keymap("n", "<leader><CR>", "<cmd>lua ReloadConfig()<CR>", { noremap = true, silent = false })
Note 1: in the example above your lua files need to be contained in a user folder: ~/.config/nvim/lua/user/. That's also where reload.lua lives.
Note 2: I think it's possible to use the not name:match('exclude-me') regex syntax to exclude problematic modules.
You can use :luafile <filename> for this.
See :h :luafile for more information.
I am not sure yet. I am using mapping :w | so % to source current file
sourcing file keymap
--update --
this works in only config file
like this hope this help
This solution works for me on Neovim v0.7.2.
-- Add modules here
local modules = {
"user.options",
"user.keymaps",
}
-- Refresh module cache
for k, v in pairs(modules) do
package.loaded[v] = nil
require(v)
end
You can then config your keymap to refresh $MYVIMRC as follows:
vim.api.nvim_set_keymap("n", "<leader><CR>", ":luafile $MYVIMRC<CR>", opts)

How to copy latest file from a directory using lua

I am trying to copy only latest file from a directory using lua file.
Latest file means : depends on modified time/created time.
How can i do this?
Referring to this question: How can I get last modified timestamp in Lua
You might be able to leverage the io.popen function to execute a shell command to get the name of the file. It seems like there's no builtin function that exposes filesystem metadata or stats. Something like this might work:
local name_handle = io.popen("ls -t1 | head -n 1")
local filename = name_handle:read()
I'm not familiar with Lua, but perhaps this helps. I imagine that once you have the name of the newest file you can use the other IO functions to do the copying.
local function get_last_file_name(directory)
local command = 'dir /a-d /o-d /tw /b "'..directory..'" 2>nul:'
-- /tw for last modified file
-- /tc for last created file
local pipe = io.popen(command)
local file_name = pipe:read()
pipe:close()
return file_name
end
local directory = [[C:\path\to\your\directory\]]
local file_name = get_last_file_name(directory)
if file_name then
print(file_name)
-- read the last file
local file = io.open(directory..file_name)
local content = file:read"*a"
file:close()
-- print content of the last file
print(content)
else
print"Directory is empty"
end

require function can't see the module file

So this is my kek13 lua chunk file:
-- modules
-- a package is a collection of modules
local test = {}
function test.add(n1, n2) -- dont put local as the scope of this function
since you already added
-- a local to the 'test' table... doing so will return an error
return n1 + n2
end
function test.hi(name)
return "my name is " .. name
end
return test
.. and this is my kek13Part2Real lua chunk file:
print("===========================")
local dad = require("kek13")
print(dad.hi("A"))
print(dad.add(1, 5))
print("==============================")
require ("kek13")
print(dad.hi("ur mum"))
print(dad.add(2, 2))
print("========================================")
They are in the same folder, at least in the document folder.
The only problem is that this causes an error. Something like lua can't find or see the file. I'm using Zerobrane IDE for this by the way.
require does not check the folder where the calling script is located it.
Use dofile with a path or add the folder containing the desired script to your LUA_PATH environment variable or append it to package.path
This is not how require works. Please read manuals...
https://www.lua.org/manual/5.3/manual.html#pdf-require

Load Lua-files by relative path

If I have a file structure like this:
./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua
From main.lua the file mylib.lua can be loaded with full path require('mylib.mylib'). But inside mylib.lua I would also like to load other necessary modules and I don't feel like always specifying the full path (e.g. mylib.mylib-utils). If I ever decide to move the folder I'm going to have a lot of search and replace. Is there a way to use just the relative part of the path?
UPD. I'm using Lua with Corona SDK, if that matters.
There is a way of deducing the "local path" of a file (more concretely, the string that was used to load the file).
If you are requiring a file inside lib.foo.bar, you might be doing something like this:
require 'lib.foo.bar'
Then you can get the path to the file as the first element (and only) ... variable, when you are outside all functions. In other words:
-- lib/foo/bar.lua
local pathOfThisFile = ... -- pathOfThisFile is now 'lib.foo.bar'
Now, to get the "folder" you need to remove the filename. Simplest way is using match:
local folderOfThisFile = (...):match("(.-)[^%.]+$") -- returns 'lib.foo.'
And there you have it. Now you can prepend that string to other file names and use that to require:
require(folderOfThisFile .. 'baz') -- require('lib.foo.baz')
require(folderOfThisFile .. 'bazinga') -- require('lib.foo.bazinga')
If you move bar.lua around, folderOfThisFile will get automatically updated.
You can do
package.path = './mylib/?.lua;' .. package.path
Or
local oldreq = require
local require = function(s) return oldreq('mylib.' .. s) end
Then
-- do all the requires
require('mylib-utils')
require('mylib-helpers')
require('mylib-other-stuff')
-- and optionally restore the old require, if you did it the second way
require = oldreq
I'm using the following snippet. It should work both for files loaded with require, and for files called via the command line. Then use requireRel instead of require for those you wish to be loaded with a relative path.
local requireRel
if arg and arg[0] then
package.path = arg[0]:match("(.-)[^\\/]+$") .. "?.lua;" .. package.path
requireRel = require
elseif ... then
local d = (...):match("(.-)[^%.]+$")
function requireRel(module) return require(d .. module) end
end
Under the Conky's Lua environment I've managed to include my common.lua (in the same directory) as require(".common"). Note the leading dot . character.
Try this:Here is my findings:
module1= require(".\\moduleName")
module2= dofile("..\\moduleName2.lua")
module3 =loadfile("..\\module3.lua")
To load from current directory. Append a double backslash with a prefix of a fullstop.
To specify a directory above use a prefix of two fullstops and repeat this pattern for any such directory.e.g
module4=require("..\\..\\module4")

Resources