Goal
We need a plugin that implements some game specific behavior of Lua things, like Set/Get generation, auto class naming/detection.
OnSetText implementation
An example of a simple plugin that
- Expands preprocessor macro DEFINE_BASECLASS.
- Automatically classifies scripted ents by folder/filename and solves "duplicate field" inside the sent file.
---@class gmod_hands: ENT
local ENT = {}
... original file code with ENT usage
However, I don't want to use it in this form, because it's working with text, and it's reached the edge of its possibilities. For example, you can see that the first character of sent file is displayed in green, because I am injecting a fake class there.
Implementing a NetworkVar and AccessorFunc already seems impossible with a text.
---@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 scopeFolders = {
{ "EFFECT", "effects" },
{ "SWEP", "weapons" },
{ "ENT", "entities" }
}
---@param uri string
---@return string?, string?
local function GetScopedClass(uri)
for _, scope in ipairs(scopeFolders) do
-- gamemode based uri:
-- .../gamemodes/my_gamemode/entities/entities/ent_class_name/any.lua
-- .../gamemodes/my_gamemode/entities/entities/ent_class_name.lua
local class = uri:match("%Wentities/" .. scope[2] .. "/([^/]+)/?[^/]*%.lua$")
if not class then
-- addon or root based uri:
-- .../addons/my_addon/lua/entities/ent_class_name/any.lua
-- .../addons/my_addon/lua/entities/ent_class_name.lua
class = uri:match("%Wlua/" .. scope[2] .. "/([^/]+)/?[^/]*%.lua$")
end
if class then
return scope[1], class
end
end
end
---@param uri string # The uri of file
---@param text string # The content of file
---@return diff[]?
function OnSetText(uri, text)
---@type diff[]
local diffs = {}
-- Detect "scripted" scope by folder and localize its global table to @class annotation.
local scope, class = GetScopedClass(uri)
if scope then
diffs[#diffs + 1] = {
start = 1,
finish = 1,
text = ([[
---@class %s: %s
local %s = {}
%s]]):format(class, scope, scope, text:sub(1, 1))
}
end
-- Replace preprocessor keyword DEFINE_BASECLASS.
for start, finish, b, c in text:gmatch("()DEFINE_BASECLASS()") do
diffs[#diffs + 1] = {
---@cast start integer
start = start,
finish = finish - 1,
text = "local BaseClass = baseclass.Get",
}
end
if #diffs == 0 then
return nil
end
return diffs
end
Completed features
Refs
Plugin samples
OnSetText
https://github.com/goldenstein64/lualogging-definitions/blob/13aabcde86b98c3bd3d2cacc0121f288496db045/plugin.lua
https://github.com/goldenstein64/pl-definitions/blob/54bf99b9d6394f6e9bab0fb2029ecf908db9a8cc/plugin.lua
https://github.com/serg3295/nodeMCU-emmylua/blob/232b42845e2f7a32ef8837417b409f5db666ecdf/plugin.lua
https://github.com/RavenfieldCommunity/RavenscriptIDEA/blob/7525a2eb431d27199e8c17aeceb872b1d559c4aa/plugin.lua
https://github.com/ProjectTH/fivem-lls-addon/blob/c93a8d64d0b541feda6b09b86961a7d62db2ee6d/plugin.lua
ResolveRequire
https://github.com/Periapsises/Starfall-LLS/blob/de36268b6218dca73b492176e8ef013b31bf3d6c/plugin.lua
OnCompileFunctionParam, ResolveRequire
https://github.com/Wild-W/smbx2-lunalua-luacats/blob/417401f1e6ade91809067bb2afac84f90109ab08/plugin.lua
OnTransformAst
https://github.com/LuaCATS/dontstarve/blob/42a8810744bb00266d733f9ed84b56b91fe74e94/plugin/dontstave.lua
https://github.com/DeadlyBossMods/LuaLS-Config/blob/main/Plugin/Mod-Class-Plugin.lua
Custom diagnostics:
LuaLS/lua-language-server#2511
https://github.com/DeadlyBossMods/LuaLS-Config/blob/main/Plugin/Event-Diagnostic.lua
TODO
I haven't had time for further research yet 😪
Goal
We need a plugin that implements some game specific behavior of Lua things, like Set/Get generation, auto class naming/detection.
OnSetText implementation
An example of a simple plugin that
However, I don't want to use it in this form, because it's working with text, and it's reached the edge of its possibilities. For example, you can see that the first character of sent file is displayed in green, because I am injecting a fake class there.
Implementing a NetworkVar and AccessorFunc already seems impossible with a text.
Completed features
OnTransformAst/VM.OnCompileFunctionParam.self:NetworkVar(...)andself.NetworkVar(self, ...)for stack defined arguments, not localized one.Doesn't support
BaseClass.SetupDataTables(self).Refs
Plugin samples
OnSetText
https://github.com/goldenstein64/lualogging-definitions/blob/13aabcde86b98c3bd3d2cacc0121f288496db045/plugin.lua
https://github.com/goldenstein64/pl-definitions/blob/54bf99b9d6394f6e9bab0fb2029ecf908db9a8cc/plugin.lua
https://github.com/serg3295/nodeMCU-emmylua/blob/232b42845e2f7a32ef8837417b409f5db666ecdf/plugin.lua
https://github.com/RavenfieldCommunity/RavenscriptIDEA/blob/7525a2eb431d27199e8c17aeceb872b1d559c4aa/plugin.lua
https://github.com/ProjectTH/fivem-lls-addon/blob/c93a8d64d0b541feda6b09b86961a7d62db2ee6d/plugin.lua
ResolveRequire
https://github.com/Periapsises/Starfall-LLS/blob/de36268b6218dca73b492176e8ef013b31bf3d6c/plugin.lua
OnCompileFunctionParam, ResolveRequire
https://github.com/Wild-W/smbx2-lunalua-luacats/blob/417401f1e6ade91809067bb2afac84f90109ab08/plugin.lua
OnTransformAst
https://github.com/LuaCATS/dontstarve/blob/42a8810744bb00266d733f9ed84b56b91fe74e94/plugin/dontstave.lua
https://github.com/DeadlyBossMods/LuaLS-Config/blob/main/Plugin/Mod-Class-Plugin.lua
Custom diagnostics:
LuaLS/lua-language-server#2511
https://github.com/DeadlyBossMods/LuaLS-Config/blob/main/Plugin/Event-Diagnostic.lua
TODO
self: ent_myentinstead ofself: Entity?T|Entity(cannot castent_notdefined|EntitytoEntity).BaseClass.SetupDataTables(self)I haven't had time for further research yet 😪