forked from qt-creator/qt-creator
On macOS, files in Contents/PlugIns/ need to be codesigned individually. Since Lua plugins are not really binaries, per Apple's documentation that is to be avoided (and we currently only sign executables there). Just move Lua plugins generally to the resources directory, like we do for other scripts like the debugger Python scripts, and load them from there. Change-Id: Idabd6b7c0c7c6e842b1752488cb7073f00e7be49 Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
236 lines
6.3 KiB
Lua
236 lines
6.3 KiB
Lua
-- Copyright (C) 2024 The Qt Company Ltd.
|
|
-- SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
local LSP = require('LSP')
|
|
local mm = require('MessageManager')
|
|
local Utils = require('Utils')
|
|
local S = require('Settings')
|
|
local Gui = require('Gui')
|
|
local a = require('async')
|
|
local fetch = require('Fetch').fetch
|
|
local Install = require('Install')
|
|
|
|
Settings = {}
|
|
|
|
local function createCommand()
|
|
local cmd = { Settings.binary.expandedValue:nativePath() }
|
|
if Settings.showNode.value then
|
|
table.insert(cmd, '--shownode=true')
|
|
end
|
|
if Settings.showSource.value then
|
|
table.insert(cmd, '--showsource=true')
|
|
end
|
|
if Settings.developMode.value then
|
|
table.insert(cmd, '--develop=true')
|
|
end
|
|
|
|
return cmd
|
|
end
|
|
local function filter(tbl, callback)
|
|
for i = #tbl, 1, -1 do
|
|
if not callback(tbl[i]) then
|
|
table.remove(tbl, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function installOrUpdateServer()
|
|
local data = a.wait(fetch({
|
|
url = "https://qtccache.qt.io/LuaLanguageServer/LatestRelease",
|
|
convertToTable = true
|
|
}))
|
|
|
|
if type(data) == "table" and #data > 0 then
|
|
local r = data[1]
|
|
local lspPkgInfo = Install.packageInfo("lua-language-server")
|
|
if not lspPkgInfo or lspPkgInfo.version ~= r.tag_name then
|
|
local osTr = { mac = "darwin", windows = "win32", linux = "linux" }
|
|
local archTr = { unknown = "", x86 = "ia32", x86_64 = "x64", itanium = "", arm = "", arm64 = "arm64" }
|
|
local os = osTr[Utils.HostOsInfo.os]
|
|
local arch = archTr[Utils.HostOsInfo.architecture]
|
|
|
|
local expectedFileName = "lua-language-server-" .. r.tag_name .. "-" .. os .. "-" .. arch
|
|
|
|
filter(r.assets, function(asset)
|
|
return string.find(asset.name, expectedFileName, 1, true) == 1
|
|
end)
|
|
|
|
if #r.assets == 0 then
|
|
print("No assets found for this platform")
|
|
return
|
|
end
|
|
local res, err = a.wait(Install.install(
|
|
"Do you want to install the lua-language-server?", {
|
|
name = "lua-language-server",
|
|
url = r.assets[1].browser_download_url,
|
|
version = r.tag_name
|
|
}))
|
|
|
|
if not res then
|
|
mm.writeFlashing("Failed to install lua-language-server: " .. err)
|
|
return
|
|
end
|
|
|
|
lspPkgInfo = Install.packageInfo("lua-language-server")
|
|
print("Installed:", lspPkgInfo.name, "version:", lspPkgInfo.version, "at", lspPkgInfo.path)
|
|
end
|
|
|
|
local binary = "bin/lua-language-server"
|
|
if Utils.HostOsInfo.isWindowsHost() then
|
|
binary = "bin/lua-language-server.exe"
|
|
end
|
|
|
|
Settings.binary:setValue(lspPkgInfo.path:resolvePath(binary))
|
|
Settings:apply()
|
|
return
|
|
end
|
|
|
|
if type(data) == "string" then
|
|
print("Failed to fetch:", data)
|
|
else
|
|
print("No lua-language-server release found.")
|
|
end
|
|
end
|
|
IsTryingToInstall = false
|
|
|
|
local function setupClient()
|
|
Client = LSP.Client.create({
|
|
name = 'Lua Language Server',
|
|
cmd = createCommand,
|
|
transport = 'stdio',
|
|
languageFilter = {
|
|
patterns = { '*.lua' },
|
|
mimeTypes = { 'text/x-lua' }
|
|
},
|
|
settings = Settings,
|
|
startBehavior = "RequiresFile",
|
|
onStartFailed = function()
|
|
a.sync(function()
|
|
if IsTryingToInstall == true then
|
|
mm.writeFlashing("RECURSION!");
|
|
return
|
|
end
|
|
IsTryingToInstall = true
|
|
installOrUpdateServer()
|
|
IsTryingToInstall = false
|
|
end)()
|
|
end
|
|
})
|
|
|
|
Client.on_instance_start = function()
|
|
print("Instance has started")
|
|
end
|
|
|
|
Client:registerMessage("$/status/report", function(params)
|
|
mm.writeFlashing(params.params.text .. ": " .. params.params.tooltip);
|
|
end)
|
|
end
|
|
|
|
local function using(tbl)
|
|
local result = _G
|
|
for k, v in pairs(tbl) do result[k] = v end
|
|
return result
|
|
end
|
|
local function layoutSettings()
|
|
--- "using namespace Gui"
|
|
local _ENV = using(Gui)
|
|
|
|
local layout = Form {
|
|
Settings.binary, br,
|
|
Settings.developMode, br,
|
|
Settings.showSource, br,
|
|
Settings.showNode, br,
|
|
Row {
|
|
PushButton {
|
|
text = "Update Lua Language Server",
|
|
onClicked = function() a.sync(installOrUpdateServer)() end,
|
|
},
|
|
st
|
|
}
|
|
}
|
|
return layout
|
|
end
|
|
|
|
local function binaryFromPkg()
|
|
local lspPkgInfo = Install.packageInfo("lua-language-server")
|
|
if lspPkgInfo then
|
|
local binary = "bin/lua-language-server"
|
|
if Utils.HostOsInfo.isWindowsHost() then
|
|
binary = "bin/lua-language-server.exe"
|
|
end
|
|
local binaryPath = lspPkgInfo.path:resolvePath(binary)
|
|
if binaryPath:isExecutableFile() == true then
|
|
return binaryPath
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function findBinary()
|
|
local binary = binaryFromPkg()
|
|
if binary then
|
|
return binary
|
|
end
|
|
|
|
-- Search for the binary in the PATH
|
|
local serverPath = Utils.FilePath.fromUserInput("lua-language-server")
|
|
local absolute = a.wait(serverPath:searchInPath()):resolveSymlinks()
|
|
if absolute:isExecutableFile() == true then
|
|
return absolute
|
|
end
|
|
return serverPath
|
|
end
|
|
|
|
local function setupAspect()
|
|
---@class Settings: AspectContainer
|
|
Settings = S.AspectContainer.create({
|
|
autoApply = false,
|
|
layouter = layoutSettings,
|
|
});
|
|
|
|
Settings.binary = S.FilePathAspect.create({
|
|
settingsKey = "LuaCopilot.Binary",
|
|
displayName = "Binary",
|
|
labelText = "Binary:",
|
|
toolTip = "The path to the lua-language-server binary.",
|
|
expectedKind = S.Kind.ExistingCommand,
|
|
defaultPath = findBinary(),
|
|
})
|
|
|
|
Settings.developMode = S.BoolAspect.create({
|
|
settingsKey = "LuaCopilot.DevelopMode",
|
|
displayName = "Enable Develop Mode",
|
|
labelText = "Enable Develop Mode:",
|
|
toolTip = "Turns on the develop mode of the language server.",
|
|
defaultValue = false,
|
|
labelPlacement = S.LabelPlacement.InExtraLabel,
|
|
})
|
|
|
|
Settings.showSource = S.BoolAspect.create({
|
|
settingsKey = "LuaCopilot.ShowSource",
|
|
displayName = "Show Source",
|
|
labelText = "Show Source:",
|
|
toolTip = "Display the internal data of the hovering token.",
|
|
defaultValue = false,
|
|
labelPlacement = S.LabelPlacement.InExtraLabel,
|
|
})
|
|
|
|
Settings.showNode = S.BoolAspect.create({
|
|
settingsKey = "LuaCopilot.ShowNode",
|
|
displayName = "Show Node",
|
|
labelText = "Show Node:",
|
|
toolTip = "Display the internal data of the hovering token.",
|
|
defaultValue = false,
|
|
labelPlacement = S.LabelPlacement.InExtraLabel,
|
|
})
|
|
return Settings
|
|
end
|
|
local function setup(parameters)
|
|
setupAspect()
|
|
setupClient()
|
|
end
|
|
|
|
return {
|
|
setup = function() a.sync(setup)() end,
|
|
}
|