Skip to content
\n

This works fine, however it would be nicer to not load all lua versions and instead load \"/usr/share/lua/5.4\" directly, while ignoring only the directory \"/usr/share/lua/5.4/<mymodule>\".

\n

For my other use-case I have some scripts lying around where there are many sub directories. Maybe I have a root file called scan.lua or something like that, and I just want to get modules from the LuaRocks tree, but not from any the sub-directories. The following config does not work as intended.

\n
{\n    \"workspace.library\": [ \"/usr/share/lua\" ],\n    \"runtime.path\": [ \"5.4/?.lua\", \"5.4/?/init.lua\" ],\n    \"workspace.ignoreDir\": [ \"*\", \"!5.4\", \"!scan.lua\" ]\n}
\n

This doesn't work as my require path never finds the modules from the luarocks tree. If I remove the \"*\" from \"workspace.ignoreDir\" then it does find the require paths, but it will also search all the sub-directories.

\n

So is there a way to specify an absolute path in \"workspace.ignoreDir\"? Or do you have another workaround I haven't thought of?

\n

Thanks in advance =)

","upvoteCount":1,"answerCount":2,"acceptedAnswer":{"@type":"Answer","text":"

The enhanced absolute path approach

\n

library path matching

\n\n

ignoreDir sub path extraction

\n\n

example usage

\n\n
{\n    \"workspace.library\": [ \"C:\\\\Users\\\\TomLau\\\\lib\" ],\n    \"workspace.ignoreDir\": [\"C:\\\\Users\\\\TomLau\\\\lib\\\\mylib\"]\n}
\n

=> extracted pattern will be /mylib

\n\n
{\n    \"workspace.library\": [ \"C:\\\\Users\\\\TomLau\\\\lib\" ],\n    \"workspace.ignoreDir\": [\"C:\\\\Users\\\\TomLau\\\\lib\\\\**\\\\mylib\"]\n}
\n

=> extracted pattern will be /**/mylib, which is equal to matching any mylib file or folder

\n
The Patch\n

\n

From 7d9d29c622848c16ef7c2843f3e348b0e77bfa89 Mon Sep 17 00:00:00 2001\nFrom: Tom Lau <[email protected]>\nDate: Thu, 3 Jul 2025 09:46:00 +0800\nSubject: [PATCH] feat: support per library ignoreDir when library path prefix\n matched\n\n---\n script/workspace/workspace.lua | 40 ++++++++++++++++++++++++++++++++--\n 1 file changed, 38 insertions(+), 2 deletions(-)\n\ndiff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua\nindex d5868342..c19cf2f8 100644\n--- a/script/workspace/workspace.lua\n+++ b/script/workspace/workspace.lua\n@@ -216,9 +216,37 @@ function m.getLibraryMatchers(scp)\n             pattern[#pattern+1] = path\n         end\n     end\n+    local libraryPatterns = {}\n     for _, path in ipairs(config.get(scp.uri, 'Lua.workspace.ignoreDir')) do\n         log.debug('Ignore directory:', path)\n-        pattern[#pattern+1] = path\n+        -- check for library specific ignoreDir\n+        local isLibrarySpecific = false\n+        for _, libraryPath in ipairs(config.get(scp.uri, 'Lua.workspace.library')) do\n+            if path:sub(1, #libraryPath) == libraryPath -- prefix matched\n+            and (\n+                libraryPath:match('[\\\\/]$') -- either library path ends with dir separator\n+                or path:sub(#libraryPath+1):match('^[\\\\/]') -- or the subPath starts with dir separator\n+            )\n+            then\n+                -- prefix matched, remove the prefix\n+                -- convert windows path separator `\\` to `/`\n+                -- and make sure the subPath starts with a `/`\n+                local subPath = path:sub(#libraryPath+1):gsub('\\\\', '/')\n+                if subPath:sub(1, 1) ~= '/' then\n+                    subPath = '/' .. subPath\n+                end\n+                local absLibraryPath = m.getAbsolutePath(scp.uri, libraryPath)\n+                if absLibraryPath then\n+                    isLibrarySpecific = true\n+                    local libraryPathKey = files.normalize(absLibraryPath)\n+                    libraryPatterns[libraryPathKey] = libraryPatterns[libraryPathKey] or {}\n+                    table.insert(libraryPatterns[libraryPathKey], subPath)\n+                end\n+            end\n+        end\n+        if not isLibrarySpecific then\n+            pattern[#pattern+1] = path\n+        end\n     end\n \n     local librarys = {}\n@@ -239,8 +267,16 @@ function m.getLibraryMatchers(scp)\n     local matchers = {}\n     for path in pairs(librarys) do\n         if fs.exists(fs.path(path)) then\n+            local patterns = libraryPatterns[path]\n+            if patterns then\n+                -- append default pattern\n+                util.arrayMerge(patterns, pattern)\n+            else\n+                -- use default pattern\n+                patterns = pattern\n+            end\n             local nPath = fs.absolute(fs.path(path)):string()\n-            local matcher = glob.gitignore(pattern, {\n+            local matcher = glob.gitignore(patterns, {\n                 root       = path,\n                 ignoreCase = platform.os == 'windows',\n             }, globInteferFace)\n-- \n2.47.1.windows.2\n\n
\n

\n
","upvoteCount":0,"url":"https://github.com/LuaLS/lua-language-server/discussions/3213#discussioncomment-13668100"}}}
Discussion options

You must be logged in to vote

The enhanced absolute path approach

library path matching

  • first check for prefix match
  • then to avoid a shorter folder name matching a longer one, requires either
    • library path ends with directory separator / or \
    • or the sub path after removing the prefix, starts with directory separator / or \

ignoreDir sub path extraction

  • after matching with a library path, first remove the library path prefix
  • then convert all \ to / so as to form a valid gitignore pattern
  • finally make sure that it is formatted with a leading /
    => because we want this pattern to start matching from the library path root

example usage

  • standard absolute path
{
    "workspace.library": [ "C:\\Users\\TomLau\\lib" ],
…

Replies: 2 comments 15 replies

Comment options

You must be logged in to vote
9 replies
@tomlau10
Comment options

@sewbacca
Comment options

@tomlau10
Comment options

@sewbacca
Comment options

@tomlau10
Comment options

Comment options

You must be logged in to vote
6 replies
@sewbacca
Comment options

@tomlau10
Comment options

@tomlau10
Comment options

Answer selected by sewbacca
@sewbacca
Comment options

@tomlau10
Comment options

@tomlau10
Comment options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants