In my app I have a structure similar to the following:
app (baseDirectory)
|
+-> config
|
+-> Levels
When using corona I am trying to autoload all files in the Levels directory. Below is how I am currently doing it. Note: This does work on Windows just not mac.
local dirPath = system.pathForFile('config/Levels')
for file in lfs.dir(dirPath) do
if (file ~= '.' and file ~= '..') then
-- require the file
end
end
Now if I use the following it works on Mac but not the 'config/Levels'.
local dirPath = system.pathForFile('config')
I'm not sure if this is a bug or if I am doing something wrong. I would assume since it works on Windows but not on Mac that it would be a bug.
So in conclusion how can I get the following to work with the above directory structure
local dirPath = system.pathForFile('config/Levels')
After much debugging I have figured out the solution for Mac. Below is my function for getting files in a directory. Works for both Windows and Mac.
Must have a file named main.lua in the baseDirectory.
-- path is relative to the baseDirectory
function getFiles(path)
local filenames = { }
local baseDir = system.pathForFile('main.lua'):gsub("main.lua", "")
for file in lfs.dir(baseDir .. path) do
if (file ~= '.' and file ~= '..') then
table.insert(filenames, file)
end
end
if (#filenames == 0) then return false end
return filenames
end
The problem is system.pathForFile('directory/subdirectory') does not work on Mac as it is strictly looking for a file. As long as it can find some file in the baseDirectory you can append on the relative path to retrieve all files in the intended directory.
One solution is to change "Levels" in "levels".
Maybe it is case sensitive.
Second solution is to not use "levels" directory inside config folder.
Here is how I suggest to organize your files:
app (baseDirectory)
|
+-> • configLevels
• configPlayer
• configOther
Related
I decided to spring-clean and update my nvim config files/plugins, and thought I’d make proper use of the after/plug folder.
While setting up LSP (with mason, mason-lspconfig, and lspconfig), I wanted to move all the lsp language server settings out from after/plugin/lsp/init.lua to their own files (now in after/plugin/lsp/settings).
The problem is I don’t seem to be able to require them into the init.lua file.
Things I’ve tried to no avail:
require(‘after/plugin/lsp/settings/sumneko_lua.lua’)
require(vim.fn.stdpath("config") .. "/after/plugin/lsp/settings/sumneko_lua”)
require(vim.fn.expand('%:h').. ‘/settings/sumneko_lua’)
The attempt using expand works when I resource the file in nvim; but causes an error when starting nvim.
I understand that all the files in after/plugin are automagically sourced at startup. So if I had a file shared.lua:
local M = {}
function M.greet()
vim.notify("Hello!”)
end
return M
in the same folder as after/plugin/lsp/init.lua, how can I get access to the greet() function from init.lua?
Any pointers would be greatly appreciated.
It turned out to be quite a simple solution in the end: I simply updated the paths to be searched in init.lua
-- nvim/init.lua
-- Allow require to look in after/plugin folder
local home_dir = os.getenv("HOME”)
package.path = home_dir .. "/.config/nvim/after/plugin/?.lua;" .. package.path
And then I can require any file inside the after/plugin folder
e.g - require(‘lsp/settings/sumneko’) or require(‘lsp/shared’).greet()
I need a list of directory in LUA
Suppose I have a directory path as "C:\Program Files"
I need a list of all the folders in that particular path and how to search any particular folder in that list.
Example
Need a list of all the folder in path "C:\Program Files"
Below are folder name in the above path
test123
test4567
folder 123
folder 456
folder 456 789
Need to get the above in a list and then have to search for a particular string like folder 456 in folder 456 789 only.
Have Tried below code. Something I am missing below:-
local function Loc_Lines( str )
--
local ret= {} -- 0 lines
while str do
local _,_,line,tail= string.find( str, "(.-)\n(.+)" )
table.insert( ret, line or str )
str= tail
Print (str)
end
return ret
end
local function Loc_ShellCommand( cmd )
--
local str= nil
--
local f= io.popen( cmd ) -- no command still returns a handle :(
if f then
str= f:read'*a'
Print(str)
f:close()
end
if str=="" then -- take no output as a failure (we can't tell..)
Print("hi")
str= nil
end
-- Remove terminating linefeed, if any (eases up one-line analysis)
--
if str then
if string.sub( str, -1 ) == '\n' then
str= string.sub( str, 1, -2 )
end
end
return str
end
local function Loc_DirCmd( cmd )
Print(cmd)
local str= Loc_ShellCommand( cmd )
return Loc_Lines(str)
end
local function Loc_DirList( dirname )
local ret= {}
local lookup= {}
local tbl= Loc_DirCmd( "dir /AD /B "..dirname ) -- only dirs
-- Add slash to every dir line
--
for i,v in ipairs(tbl) do
table.insert( ret, v..'\\' )
lookup[v]= true
end
-- Return with forward slashes
--
if true then
for i=1,table.getn(ret) do
ret[i]= string.gsub( ret[i], '\\', '/' )
Print (ret[i])
end
end
return ret
end
Loc_DirList("C:\\Program Files\\")
I hate having to install libraries (especially those that want me to use installer packages to install them). If you're looking for a clean solution for a directory listing on an absolute path in Lua, look no further.
Building on the answer that sylvanaar provided, I created a function that returns an array of all the files for a given directory (absolute path required). This is my preferred implementation, as it works on all my machines.
-- Lua implementation of PHP scandir function
function scandir(directory)
local i, t, popen = 0, {}, io.popen
local pfile = popen('ls -a "'..directory..'"')
for filename in pfile:lines() do
i = i + 1
t[i] = filename
end
pfile:close()
return t
end
If you are using Windows, you'll need to have a bash client installed so that the 'ls' command will work - alternately, you can use the dir command that sylvanaar provided:
'dir "'..directory..'" /b /ad'
Take the easy way, install lfs. Then use the following constructs to find what you need:
require'lfs'
for file in lfs.dir[[C:\Program Files]] do
if lfs.attributes(file,"mode") == "file" then print("found file, "..file)
elseif lfs.attributes(file,"mode")== "directory" then print("found dir, "..file," containing:")
for l in lfs.dir("C:\\Program Files\\"..file) do
print("",l)
end
end
end
notice that a backslash equals [[\]] equals "\\", and that in windows / is also allowed if not used on the cmd itself (correct me if I'm wrong on this one).
for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end
*For Windows
Outputs:
Adobe
Bitcasa
Bonjour
Business Objects
Common Files
DVD Maker
IIS
Internet Explorer
iPod
iTunes
Java
Microsoft Device Emulator
Microsoft Help Viewer
Microsoft IntelliPoint
Microsoft IntelliType Pro
Microsoft Office
Microsoft SDKs
Microsoft Security Client
Microsoft SQL Server
Microsoft SQL Server Compact Edition
Microsoft Sync Framework
Microsoft Synchronization Services
Microsoft Visual Studio 10.0
Microsoft Visual Studio 9.0
Microsoft.NET
MSBuild
...
Each time through the loop you are given a new folder name. I chose to print it as an example.
I don't like installing libraries either and am working on an embedded device with less memory power then a pc. I found out that using 'ls' command lead to an out of memory. So I created a function that uses 'find' to solve the problem.
This way it was possible to keep memory usage steady and loop all the 30k files.
function dirLookup(dir)
local p = io.popen('find "'..dir..'" -type f') --Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
for file in p:lines() do --Loop through all files
print(file)
end
end
IIRC, getting the directory listing isn't possible with stock Lua. You need to write some glue code yourself, or use LuaFileSystem. The latter is most likely the path of least resistance for you. A quick scan of the docs shows lfs.dir() which will provide you with an iterator you can use to get the directories you are looking for. At that point, you can then do your string comparison to get the specific directories you need.
You also install and use the 'paths' module. Then you can easily do this as follow:
require 'paths'
currentPath = paths.cwd() -- Current working directory
folderNames = {}
for folderName in paths.files(currentPath) do
if folderName:find('$') then
table.insert(folderNames, paths.concat(currentPath, folderName))
end
end
print (folderNames)
-- This will print all folder names
Optionally, you can also look for file names with a specific extension by replacing fileName:find('$') with fileName:find('txt' .. '$')
If you're running on a Unix-based machine you can get a numerically-sorted list of files using the following code:
thePath = '/home/Your_Directory'
local handle = assert(io.popen('ls -1v ' .. thePath))
local allFileNames = string.split(assert(handle:read('*a')), '\n')
print (allFileNames[1]) -- This will print the first file name
The second code also excludes files such as '.' and '..'. So it's good to go!
Don't parse ls, it's evil! Use find with zero-terminated strings instead (on linux):
function scandir(directory)
local i, t = 0, {}
local pfile = assert(io.popen(("find '%s' -maxdepth 1 -print0"):format(directory), 'r'))
local list = pfile:read('*a')
pfile:close()
for filename in s:gmatch('[^\0]+')
i = i + 1
t[i] = filename
end
return t
end
WARNING: however, as an acceped answer this apporach could be exploited if directory name contain ' in it. Only one safe solution is to use lfs or other special library.
Few fixes of val says Reinstate Monica solution:
function scandir(directory)
local pfile = assert(io.popen(("find '%s' -mindepth 1 -maxdepth 1 -type d -printf '%%f\\0'"):format(directory), 'r'))
local list = pfile:read('*a')
pfile:close()
local folders = {}
for filename in string.gmatch(list, '[^%z]+') do
table.insert(folders, filename)
end
return folders
end
Now it filters by folders, excludes dir itself and prints only names.
I have never previously worked with lua programming but I have to run a package written in lua language. This package is a command line linux interface and I don't have to know lua programming. In this package I only need to replace some addresses in lua files with my own address and dataset or file names to be able to run the program. But I came across a problem in running a lua file. In this file I replaced the following piece of code:
dofile 'Csv.lua'
local proteinFile = Csv(opt.dataset..".node","r")
local proteinString = proteinFile:readall()
ppFeature = {}
pNumber = {}
for i=1, #proteinString do
local fileName = opt.dataset..'/'..proteinString[i][1]
if file_exists( fileName ) then
local proFile = Csv( fileName, 'r', '\t')
local profile = proFile:readall()
with this one:
dofile 'Csv.lua'
local proteinFile = Csv("/storage/users/ssalmanian/DPPI/myTrain.node","r")
local proteinString = proteinFile:readall()
ppFeature = {}
pNumber = {}
for i=1, #proteinString do
local fileName = '/storage/users/ssalmanian/DPPI/myTrain/proteinString[i][1]'
if file_exists( fileName ) then
local proFile = Csv( fileName, 'r', '\t')
local profile = proFile:readall()
and I got error.
Necessary input files before running the command include a file and a folder with names the same as the -dataset:
A)The suffix of the file is ‘.node’ (myTrain.node). This file has one column which contains names of all proteins.
B) Profile folder with the same name as -dataset (myTrain). This folder contains profiles of all proteins.
The name of the profiles inside this folder is the same as the protein names in ‘.node’ file.
I was wondering if someone could let me know what's wrong with it and which piece of code must be replaced with the following:
local fileName = opt.dataset..'/'..proteinString[i][1]
Thanks.
EDIT:
The package is DPPI package and I tried to run creat_crop.lua code to create two files myTrain_profile_crop_512.t7 and myTrain_number_crop_512.t7 using the following command in a CUDA server :
th creat_crop.lua -dataset myTrain
That creat_crop.lua code is dependent in calling Csv.lua code and needs myTrain.node file and myTrain folder. Here I have added my WinSCP page and the error I get .
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
I need a list of directory in LUA
Suppose I have a directory path as "C:\Program Files"
I need a list of all the folders in that particular path and how to search any particular folder in that list.
Example
Need a list of all the folder in path "C:\Program Files"
Below are folder name in the above path
test123
test4567
folder 123
folder 456
folder 456 789
Need to get the above in a list and then have to search for a particular string like folder 456 in folder 456 789 only.
Have Tried below code. Something I am missing below:-
local function Loc_Lines( str )
--
local ret= {} -- 0 lines
while str do
local _,_,line,tail= string.find( str, "(.-)\n(.+)" )
table.insert( ret, line or str )
str= tail
Print (str)
end
return ret
end
local function Loc_ShellCommand( cmd )
--
local str= nil
--
local f= io.popen( cmd ) -- no command still returns a handle :(
if f then
str= f:read'*a'
Print(str)
f:close()
end
if str=="" then -- take no output as a failure (we can't tell..)
Print("hi")
str= nil
end
-- Remove terminating linefeed, if any (eases up one-line analysis)
--
if str then
if string.sub( str, -1 ) == '\n' then
str= string.sub( str, 1, -2 )
end
end
return str
end
local function Loc_DirCmd( cmd )
Print(cmd)
local str= Loc_ShellCommand( cmd )
return Loc_Lines(str)
end
local function Loc_DirList( dirname )
local ret= {}
local lookup= {}
local tbl= Loc_DirCmd( "dir /AD /B "..dirname ) -- only dirs
-- Add slash to every dir line
--
for i,v in ipairs(tbl) do
table.insert( ret, v..'\\' )
lookup[v]= true
end
-- Return with forward slashes
--
if true then
for i=1,table.getn(ret) do
ret[i]= string.gsub( ret[i], '\\', '/' )
Print (ret[i])
end
end
return ret
end
Loc_DirList("C:\\Program Files\\")
I hate having to install libraries (especially those that want me to use installer packages to install them). If you're looking for a clean solution for a directory listing on an absolute path in Lua, look no further.
Building on the answer that sylvanaar provided, I created a function that returns an array of all the files for a given directory (absolute path required). This is my preferred implementation, as it works on all my machines.
-- Lua implementation of PHP scandir function
function scandir(directory)
local i, t, popen = 0, {}, io.popen
local pfile = popen('ls -a "'..directory..'"')
for filename in pfile:lines() do
i = i + 1
t[i] = filename
end
pfile:close()
return t
end
If you are using Windows, you'll need to have a bash client installed so that the 'ls' command will work - alternately, you can use the dir command that sylvanaar provided:
'dir "'..directory..'" /b /ad'
Take the easy way, install lfs. Then use the following constructs to find what you need:
require'lfs'
for file in lfs.dir[[C:\Program Files]] do
if lfs.attributes(file,"mode") == "file" then print("found file, "..file)
elseif lfs.attributes(file,"mode")== "directory" then print("found dir, "..file," containing:")
for l in lfs.dir("C:\\Program Files\\"..file) do
print("",l)
end
end
end
notice that a backslash equals [[\]] equals "\\", and that in windows / is also allowed if not used on the cmd itself (correct me if I'm wrong on this one).
for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end
*For Windows
Outputs:
Adobe
Bitcasa
Bonjour
Business Objects
Common Files
DVD Maker
IIS
Internet Explorer
iPod
iTunes
Java
Microsoft Device Emulator
Microsoft Help Viewer
Microsoft IntelliPoint
Microsoft IntelliType Pro
Microsoft Office
Microsoft SDKs
Microsoft Security Client
Microsoft SQL Server
Microsoft SQL Server Compact Edition
Microsoft Sync Framework
Microsoft Synchronization Services
Microsoft Visual Studio 10.0
Microsoft Visual Studio 9.0
Microsoft.NET
MSBuild
...
Each time through the loop you are given a new folder name. I chose to print it as an example.
I don't like installing libraries either and am working on an embedded device with less memory power then a pc. I found out that using 'ls' command lead to an out of memory. So I created a function that uses 'find' to solve the problem.
This way it was possible to keep memory usage steady and loop all the 30k files.
function dirLookup(dir)
local p = io.popen('find "'..dir..'" -type f') --Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
for file in p:lines() do --Loop through all files
print(file)
end
end
IIRC, getting the directory listing isn't possible with stock Lua. You need to write some glue code yourself, or use LuaFileSystem. The latter is most likely the path of least resistance for you. A quick scan of the docs shows lfs.dir() which will provide you with an iterator you can use to get the directories you are looking for. At that point, you can then do your string comparison to get the specific directories you need.
You also install and use the 'paths' module. Then you can easily do this as follow:
require 'paths'
currentPath = paths.cwd() -- Current working directory
folderNames = {}
for folderName in paths.files(currentPath) do
if folderName:find('$') then
table.insert(folderNames, paths.concat(currentPath, folderName))
end
end
print (folderNames)
-- This will print all folder names
Optionally, you can also look for file names with a specific extension by replacing fileName:find('$') with fileName:find('txt' .. '$')
If you're running on a Unix-based machine you can get a numerically-sorted list of files using the following code:
thePath = '/home/Your_Directory'
local handle = assert(io.popen('ls -1v ' .. thePath))
local allFileNames = string.split(assert(handle:read('*a')), '\n')
print (allFileNames[1]) -- This will print the first file name
The second code also excludes files such as '.' and '..'. So it's good to go!
Don't parse ls, it's evil! Use find with zero-terminated strings instead (on linux):
function scandir(directory)
local i, t = 0, {}
local pfile = assert(io.popen(("find '%s' -maxdepth 1 -print0"):format(directory), 'r'))
local list = pfile:read('*a')
pfile:close()
for filename in s:gmatch('[^\0]+')
i = i + 1
t[i] = filename
end
return t
end
WARNING: however, as an acceped answer this apporach could be exploited if directory name contain ' in it. Only one safe solution is to use lfs or other special library.
Few fixes of val says Reinstate Monica solution:
function scandir(directory)
local pfile = assert(io.popen(("find '%s' -mindepth 1 -maxdepth 1 -type d -printf '%%f\\0'"):format(directory), 'r'))
local list = pfile:read('*a')
pfile:close()
local folders = {}
for filename in string.gmatch(list, '[^%z]+') do
table.insert(folders, filename)
end
return folders
end
Now it filters by folders, excludes dir itself and prints only names.