Files
qt-creator/share/qtcreator/lua-plugins/rustls/init.lua
Eike Ziller f5dde31558 Move the shipped Lua plugins to the resources directory
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>
2024-06-20 07:40:46 +00:00

197 lines
5.0 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 Process = require('Process')
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() }
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/RustLanguageServer/LatestReleases",
convertToTable = true,
}))
if type(data) == "table" and #data > 1 then
local r = data[1]
if r.prerelease then
r = data[2]
end
local lspPkgInfo = Install.packageInfo("rust-analyzer")
if not lspPkgInfo or lspPkgInfo.version ~= r.tag_name then
local osTr = { mac = "apple-darwin", windows = "pc-windows-msvc", linux = "unknown-linux-gnu" }
local archTr = { unknown = "", x86 = "", x86_64 = "x86_64", itanium = "", arm = "", arm64 = "aarch64" }
local extTr = { mac = "gz", windows = "zip", linux = "gz" }
local os = osTr[Utils.HostOsInfo.os]
local arch = archTr[Utils.HostOsInfo.architecture]
local ext = extTr[Utils.HostOsInfo.os]
local expectedFileName = "rust-analyzer-" .. arch .. "-" .. os .. "." .. ext
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 rust-analyzer?", {
name = "rust-analyzer",
url = r.assets[1].browser_download_url,
version = r.tag_name
}))
if not res then
mm.writeFlashing("Failed to install rust-analyzer: " .. err)
return
end
lspPkgInfo = Install.packageInfo("rust-analyzer")
print("Installed:", lspPkgInfo.name, "version:", lspPkgInfo.version, "at", lspPkgInfo.path)
end
local binary = "rust-analyzer"
if Utils.HostOsInfo.isWindowsHost() then
binary = "rust-analyzer.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 rust-analyzer release found.")
end
end
IsTryingToInstall = false
local function setupClient()
Client = LSP.Client.create({
name = 'Rust Language Server',
cmd = createCommand,
transport = 'stdio',
languageFilter = {
patterns = { '*.rs' },
mimeTypes = { 'text/rust' }
},
settings = Settings,
startBehavior = "RequiresProject",
onStartFailed = function()
a.sync(function()
if IsTryingToInstall == true then
return
end
IsTryingToInstall = true
installOrUpdateServer()
IsTryingToInstall = false
end)()
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,
Row {
PushButton {
text = "Try to install Rust language server",
onClicked = function() a.sync(installOrUpdateServer)() end,
br,
},
st
}
}
return layout
end
local function binaryFromPkg()
local lspPkgInfo = Install.packageInfo("rust-analyzer")
if lspPkgInfo then
local binary = "rust-analyzer"
if Utils.HostOsInfo.isWindowsHost() then
binary = "rust-analyzer.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("rust-analyzer")
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 = "Rustls.Binary",
displayName = "Binary",
labelText = "Binary:",
toolTip = "The path to the rust analyzer binary.",
expectedKind = S.Kind.ExistingCommand,
defaultPath = findBinary(),
})
return Settings
end
local function setup(parameters)
setupAspect()
setupClient()
end
return {
setup = function() a.sync(setup)() end,
}