init.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. require 'libpaths'
  2. local assert = assert
  3. local debug = debug
  4. local pcall = pcall
  5. local type = type
  6. local ipairs = ipairs
  7. local os = os
  8. function paths.is_win()
  9. return paths.uname():match('Windows')
  10. end
  11. function paths.is_mac()
  12. return paths.uname():match('Darwin')
  13. end
  14. if paths.is_win() then
  15. paths.home = os.getenv('HOMEDRIVE') or 'C:'
  16. paths.home = paths.home .. ( os.getenv('HOMEPATH') or '\\' )
  17. else
  18. paths.home = os.getenv('HOME') or '.'
  19. end
  20. function paths.files(s, f)
  21. local d = paths.dir(s)
  22. local n = 0
  23. if type(f) == 'string' then
  24. local pattern = f
  25. f = function(file) return file:find(pattern) end
  26. elseif f and type(f) ~= 'function' then
  27. error("Expecting optional arg 2 to be function or string. Got : "..torch.type(f))
  28. end
  29. f = f or function(file) return true end
  30. local n = 0
  31. return function()
  32. while true do
  33. n = n + 1
  34. if d == nil or n > #d then
  35. return nil
  36. elseif f(d[n]) then
  37. return d[n]
  38. end
  39. end
  40. end
  41. end
  42. function paths.iterdirs(s)
  43. return paths.files(s,
  44. function(dir)
  45. return paths.dirp(paths.concat(s, dir)) and dir ~= '.' and dir ~= '..'
  46. end)
  47. end
  48. function paths.iterfiles(s)
  49. return paths.files(s,
  50. function(file)
  51. return paths.filep(paths.concat(s, file)) and file ~= '.' and file ~= '..'
  52. end)
  53. end
  54. function paths.thisfile(arg, depth)
  55. local s = debug.getinfo(depth or 2).source
  56. if type(s) ~= "string" then
  57. s = nil
  58. elseif s:match("^@") then -- when called from a file
  59. s = paths.concat(s:sub(2))
  60. elseif s:match("^qt[.]") then -- when called from a qtide editor
  61. local function z(s) return qt[s].fileName:tostring() end
  62. local b, f = pcall(z, s:sub(4));
  63. if b and f and f ~= "" then s = f else s = nil end
  64. end
  65. if type(arg) == "string" then
  66. if s then s = paths.concat(paths.dirname(s), arg) else s = arg end
  67. end
  68. return s
  69. end
  70. function paths.dofile(f, depth)
  71. local s = paths.thisfile(nil, 1 + (depth or 2))
  72. if s and s ~= "" then
  73. f = paths.concat(paths.dirname(s),f)
  74. end
  75. return dofile(f)
  76. end
  77. function paths.rmall(d, more)
  78. if more ~= 'yes' then
  79. return nil, "missing second argument ('yes')"
  80. elseif paths.filep(d) then
  81. return os.remove(d)
  82. elseif paths.dirp(d) then
  83. for f in paths.files(d) do
  84. if f ~= '.' and f ~= '..' then
  85. local ff = paths.concat(d, f)
  86. local r0,r1,r2 = paths.rmall(ff, more)
  87. if not r0 then
  88. return r0,r1,ff
  89. end
  90. end
  91. end
  92. return paths.rmdir(d)
  93. else
  94. return nil, "not a file or directory", d
  95. end
  96. end
  97. function paths.findprogram(...)
  98. for _,exe in ipairs{...} do
  99. if paths.is_win() then
  100. if not exe:match('[.]exe$') then
  101. exe = exe .. '.exe'
  102. end
  103. local path, k, x = os.getenv("PATH") or "."
  104. for dir in path:gmatch('[^;]+') do
  105. x = paths.concat(dir, exe)
  106. if paths.filep(x) then return x end
  107. end
  108. local function clean(s)
  109. if s:match('^"') then return s:match('[^"]+') else return s end
  110. end
  111. k = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' .. exe
  112. x = paths.getregistryvalue('HKEY_CURRENT_USER', k, '')
  113. if type(x) == 'string' then return clean(x) end
  114. x = paths.getregistryvalue('HKEY_LOCAL_MACHINE', k, '')
  115. if type(x) == 'string' then return clean(x) end
  116. k = 'Applications\\' .. exe .. '\\shell\\open\\command'
  117. x = paths.getregistryvalue('HKEY_CLASSES_ROOT', k, '')
  118. if type(x) == 'string' then return clean(x) end
  119. else
  120. local path = os.getenv("PATH") or "."
  121. for dir in path:gmatch('[^:]+') do
  122. local x = paths.concat(dir, exe)
  123. if paths.filep(x) then return x end
  124. end
  125. end
  126. end
  127. return nil
  128. end
  129. return paths