Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,10 @@
"**/wikis/*/*/*/*/*.lua": "${dirname(-4)}: ${dirname(-5)}/${dirname(-6)}/${dirname}/${filename}",
"**/wikis/*/*/*/*/*/*.lua": "${dirname(-4)}: ${dirname(-5)}/${dirname(-6)}/${dirname(-7)}/${dirname}/${filename}",
"**/*.lua": "${dirname}: ${filename}"
}
},
"Lua.runtime.special": {
"Lua.import": "require",
"Lua.requireIfExists": "require",
"mw.loadData": "require"
},
}
93 changes: 45 additions & 48 deletions lua/plugins/sumneko_plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,64 @@
-- The setting "Lua.runtime.plugin" needs to be set to "plugins/sumneko_plugin.lua"
-- See more at https://github.com/sumneko/lua-language-server/wiki/Plugin

local liquipedia = {}

local importFunctions = {}
importFunctions.functions = {'require', 'mw%.loadData', 'Lua%.import', 'Lua%.requireIfExists'}

---Transforms a MediaWiki module name, e.g. `Module:Array`, into a lua repository name, e.g. `Array`
---@param name string
---@return string
function importFunctions.luaifyModuleName(name)
local normModuleName = name
:gsub('Module:', '')-- Remove starting Module:
local IS_WINDOWS = package.config:sub(1,1) ~= '/'

return normModuleName
end

function importFunctions._row(name)
local normModuleName = importFunctions.luaifyModuleName(name)

return ' ---@module \'' .. normModuleName .. '\''
end
---@param repoRoot string # Documentation of this parameter is unclear. Seems to be repo root
---@param name string # Argument of require()
---@param source string # The source file uri
---@return string[]?
-- luacheck: push ignore
function ResolveRequire(repoRoot, name, source)
-- luacheck: pop
local fileName = importFunctions.luaifyModuleName(name)

function importFunctions.annotate(text, funcName, diffs)
for module, positionEndOfRow in text:gmatch(funcName .. '%s*%(?%s*[\'"](.-)[\'"]%s*%)?.-()\r?\n') do
table.insert(diffs,
{start = positionEndOfRow, finish = positionEndOfRow - 1, text = importFunctions._row(module)}
)
-- Extract the base path (up to and including /lua/) from the source URI.
-- Also try to extract the wiki name when the source is under /wikis/<wiki>/.
-- Files outside of /wikis/ (e.g. spec/, definitions/) default to commons.
local basePath = source:match('^(file://.-/lua)[/$]')
if not basePath then
return nil
end
end

function liquipedia.annotate(text, diffs)
for _, funcName in pairs(importFunctions.functions) do
importFunctions.annotate(text, funcName, diffs)
-- See the unescaping of : below
local ioPath = basePath:gsub('%%20', ' ')
if IS_WINDOWS then
-- On Windows, the file URI starts with file:///C:/path/to/repo, so we need to remove the extra slash
-- Also need to unescape the :, otherwise %3 would be treated as a capture group result in later patterns
ioPath = ioPath:gsub('%%3A', ':')
ioPath = ioPath:gsub('^file:///', '')
else
ioPath = ioPath:gsub('^file://', '')
end
end

---@class diff
---@field start integer # The number of bytes at the beginning of the replacement
---@field finish integer # The number of bytes at the end of the replacement
---@field text string # What to replace
local targetWiki = source:match('^file://.-/lua/wikis/([^/]+)/')

-- luacheck: push ignore
-- setting non-standard global variable 'OnSetText' (but it's mandatory)
---@param uri string # The uri of file
---@param text string # The content of file
---@return nil|diff[]
---@diagnostic disable-next-line: global-element
function OnSetText(uri, text)
-- luacheck: pop ignore
if text:sub(1, 3) ~= '---' then
return nil
local function getFileForWiki(wiki)
if not wiki then
return
end
local pathSuffix = '/wikis/' .. wiki .. '/' .. fileName .. '.lua'
local wikiFile = io.open(ioPath .. pathSuffix, 'r')
if not wikiFile then
return
end
wikiFile:close()
return {basePath .. pathSuffix}
end

if text:sub(1, 8) == '---@meta' then
return nil
end

local diffs = {}
return getFileForWiki(targetWiki) or getFileForWiki('commons') or nil
end

liquipedia.annotate(text, diffs)
---Transforms a MediaWiki module name, e.g. `Module:Array`, into a lua repository name, e.g. `Array`
---@param name string
---@return string
function importFunctions.luaifyModuleName(name)
local normModuleName = name
:gsub('Module:', '')-- Remove starting Module:

return diffs
return normModuleName
end

return importFunctions
Loading