os.execute not working with love2d - lua

I'm trying to use os.execute(), but I'm getting this problem:
attempt to call field 'execute' (a nil value)
I've done os = require 'os' but when I do: os.execute("mkdir" .. var) it's giving me the above error.
From what I've worked out, it's because it's not calling in all of the stuff from os, but I've looked and I can't figure out how to call in everything from os. In python i'd do from os import * but I don't know the code for lua. I've tried using package.loadlib('os', 'execute') but that didn't work. :/
EDIT: I did a separate test with love2D, and it worked. so I can't see why this isn't working...

are you sure you don't have code somewhere that is overwritting/reassigning the os.execute function in the problem script? do you have any local table objects named os?

try this:
require 'os';
if package.loaded['os'] and type(package.loaded['os']) == "table" then
local os = package.loaded['os'];
--from here use the local os variable to call anything inside os.
--main block of code
end
I hope this works for you.

Related

How can I reload my Neovim config written in lua with a shortcut?

I want to reload my neovim configuration files with just a couple of keystrokes instead of having to restart the app. I was able to do this when using an init.vim with the following command:
nnoremap <leader>sv <cmd>source $MYVIMRC<CR>
$MYVIMRC points correctly to my config entry point.
The problem is that I switched to using lua, and now I can't do the same. I have read the docs and tried variants of the following without success:
util.nnoremap("<leader>sv", "<cmd>luafile $MYVIMRC<CR>")
Finally, I found a solution doing this:
function load(name)
local path = vim.fn.stdpath('config') .. '/lua/' .. name .. '.lua'
dofile(path)
end
load('plugins')
load('config/mapping')
load('lsp/init')
Which is buggy and feels wrong.
Is there any way to do this? I read the example in vimpeccable, but I want to see the other available options since I would rather not install another plugin.
I know that plenary includes a function to reload modules, but I don't understand how to use it. A complete example of that would be good too since I already use plenary in my config.
I am a new Neovim user, so I guess my solution may not work for some edge cases.
This function flushes the module of current buffer:
local cfg = vim.fn.stdpath('config')
Flush = function()
local s = vim.api.nvim_buf_get_name(0)
if string.match(s, '^' .. cfg .. '*') == nil then
return
end
s = string.sub(s, 6 + string.len(cfg), -5)
local val = string.gsub(s, '%/', '.')
package.loaded[val] = nil
end
You can call it whenever you write to a buffer with this autocommand:
autocmd BufWrite *.lua,*vim call v:lua.Flush()
This way, after you execute :source $MYVIMRC it will also reload changed Lua modules.

How to run a function without using any functions defined in the script in Lua

I am trying to loadstring a string and run it as a function. Here is my problem:
a = "hello"
loadstring("print(a)")()
I dont want the code above to use any vars/funcs outside of it. My goal is to make the script above print nil since a isnt defined inside the loadstring.
Sorry if the question is very brief. It was hard to explain my problem.
Your variable a lives in the global environment. To keep your chunk from seeing it, you need to give it a different environment. In Lua 5.1, you'd do that like this:
a = "hello"
local chunk = loadstring("print(a)")
setfenv(chunk, {print = print})
chunk()
In Lua 5.2 or newer, you'd do that like this:
a = "hello"
load("print(a)", nil, "t", {print = print})()
It's important to note that print isn't magic. It won't be in the new environment unless you put it there explicitly, like I did.

is it possible to call require from C

I have a module compiled in a shared object (I followed the library part of this article https://chsasank.github.io/lua-c-wrapping.html) and I want to load it from C not from the interpreter.
Is it possible ? If so how to do it ?
Yes, it's possible, as require is a function stored in a global environment. Lua does the same in standalone interpreter when it needs to process the -l option, see the dolibrary function.
You do this the same way as with any other global function - in simplest case calling lua_getglobal(), then pushing the name of the file to require, and calling lua_call/lua_pcall/whatever.
I know that I am late, but someone else may struggle with this right now (like I just did).
This is a simple way of doing "require" from C:
int reqRes = luaL_dostring(L, "local t=require('myLib') return (t~=nil)");
if (reqRes==0)
//success
else
//failed
Unfortunately, right now, I'm using Lua 5.1 and "dolibrary" function doesn't exist, I >tried to take some part of the code and it crashes :\ So, for now, I use luaL_dostring(L, >"require 'libMyWrappings'"); libMyWrappings must be in the same directory as the c >program, and I can't use a path to indicate the lib. – Aminos Jan 22 at 11:45
I just ran into the same issue, it has to do when the package library is loaded
{LUA_LOADLIBNAME, luaopen_package}
needs to happen before you try and call it

ROBLOX Studio: How do I run this Lua Bytecode VM?

For me, I want to learn how VM's work and if they can only be ran on Mac. I've found a bytecode vm (from lua) in roblox studio as one of the scripts. I'm very confused on how to use it, its nothing like i've used before. Here it is:
https://web.roblox.com/library/117513593/EpicLua-Lua-5-1-VM
Also if you could tell me more about VM's that would also help me during this process.
Looks like it's plug-and-play.
Require the module in a script/command line on Roblox. It will return a function which you can call with a string and desired environment (optional), which again returns a function you can run to run the string-code.
Example:
local LoadString = require(module)
local func = LoadString("print('Hello world!')")
func() -- prints "Hello world!"

Calling back to a main file from a dofile in lua

Say i have two files:
One is called mainFile.lua:
function altDoFile(name)
dofile(debug.getinfo(1).source:sub(debug.getinfo(1).source:find(".*\\")):sub(2)..name)
end
altDoFile("libs/caller.lua")
function callBack()
print "called back"
end
doCallback()
The other called caller.lua, located in a libs folder:
function doCallback()
print "performing call back"
_G["callBack"]()
end
The output of running the first file is then:
"performing call back"
Then nothing more, i'm missing a line!
Why is callBack never getting executed? is this intended behavior, and how do i get around it?
The fact that the function is getting called from string is important, so that can't be changed.
UPDATE:
I have tested it further, and the _G["callBack"] does resolve to a function (type()) but it still does not get called
Why not just use dofile?
It seems that the purpose of altDoFile is to replace the running script's filename with the script you want to call thereby creating an absolute path. In this case the path for caller.lua is a relative path so you shouldn't need to change anything for Lua to load the file.
Refactoring your code to this:
dofile("libs/caller.lua")
function callBack()
print "called back"
end
doCallback()
Seems to give the result you are looking for:
$ lua mainFile.lua
performing call back
called back
Just as a side note, altDoFile throws an error if the path does not contain a \ character. Windows uses the backslash for path names, but other operating systems like Linux and MacOS do not.
In my case running your script on Linux throws an error because string.find returns nill instead of an index.
lua: mainFile.lua:2: bad argument #1 to 'sub' (number expected, got nil)
If you need to know the working path of the main script, why not pass it as a command line argument:
C:\LuaFiles> lua mainFile.lua C:/LuaFiles
Then in Lua:
local working_path = arg[1] or '.'
dofile(working_path..'/libs/caller.lua')
If you just want to be able to walk back up one directory, you can also modify the loader
package.path = ";../?.lua" .. package.path;
So then you could run your file by doing:
require("caller")
dofile "../Untitled/SensorLib.lua" --use backpath librarys
Best Regards
K.

Resources