Skip to content

Commit

Permalink
nice, this seems to work now
Browse files Browse the repository at this point in the history
  • Loading branch information
HTGAzureX1212 committed Jan 7, 2024
1 parent 9b5aa44 commit ee6dca7
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 11 deletions.
41 changes: 41 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ repository = "https://github.com/TeamHarTex/rs4lapce"

[dependencies]
anyhow = "1.0.79"
flate2 = "1.0.28"
lapce-plugin = "0.1.2"
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true
14 changes: 11 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(Clone, Debug, Deserialize, Serialize)]
pub(crate) struct PluginConfiguration {
#[serde(default)]
#[serde(rename = "rustAnalyzer")]
pub rust_analyzer: Option<RustAnalyzerConfiguration>,
pub rust_analyzer: Option<Value>,
#[serde(default)]
#[serde(rename = "rustAnalyzerBuilds")]
pub rust_analyzer_builds: Option<RustAnalyzerBuildsConfiguration>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct RustAnalyzerConfiguration {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct RustAnalyzerBuildsConfiguration {
#[serde(default)]
#[serde(rename = "nightly")]
pub nightly: bool,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct RustAnalyzerConfiguration;
106 changes: 99 additions & 7 deletions src/init.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,121 @@
use crate::config::PluginConfiguration;
use anyhow::Result;
use lapce_plugin::psp_types::lsp_types::{InitializeParams, MessageType};
use lapce_plugin::PLUGIN_RPC;
use anyhow::{Error, Result};
use flate2::read::GzDecoder;
use lapce_plugin::psp_types::lsp_types::{DocumentFilter, InitializeParams, MessageType, Url};
use lapce_plugin::{Http, VoltEnvironment, PLUGIN_RPC};
use std::fs::File;
use std::path::PathBuf;
use std::{fs, io};

pub(crate) fn initialize_plugin(params: InitializeParams) -> Result<()> {
let config = params
.initialization_options
.map(|value| serde_json::from_value::<PluginConfiguration>(value))
.transpose()?;

let nightly = if let Some(config) = config
&& let Some(rust_analyzer) = config.rust_analyzer
let nightly = if let Some(config) = &config
&& let Some(rust_analyzer_builds) = &config.rust_analyzer_builds
{
rust_analyzer.nightly
rust_analyzer_builds.nightly
} else {
false
};

PLUGIN_RPC.window_show_message(
MessageType::INFO,
MessageType::LOG,
format!(
"using {} rust-analyzer",
if nightly { "nightly" } else { "stable" }
),
);

let architecture = match VoltEnvironment::architecture()?.as_str() {
"aarch64" => "aarch64",
"x86_64" => "x86_64",
unsupported => {
PLUGIN_RPC.window_show_message(
MessageType::ERROR,
format!("unsupported system architecture: {unsupported}"),
);

return Err(Error::msg(format!(
"unsupported system architecture: {unsupported}"
)));
}
};

let (target_triple, executable_name) = match VoltEnvironment::operating_system()?.as_str() {
"windows" => ("pc-windows-msvc", "rust-analyzer.exe"),
"macos" => ("apple-darwin", "rust-analyzer"),
// FIXME: unknown-linux-musl exists
"linux" => ("unknown-linux-gnu", "rust-analyzer"),
unsupported => {
PLUGIN_RPC.window_show_message(
MessageType::ERROR,
format!("unsupported operating system: {unsupported}"),
);

return Err(Error::msg(format!(
"unsupported operating system: {unsupported}"
)));
}
};

let file_path = PathBuf::from(executable_name);
if !file_path.exists() {
PLUGIN_RPC.window_show_message(MessageType::LOG, String::from("downloading rust-analyzer"));

if let Err(error) = download_rust_analyzer(nightly, &file_path, architecture, target_triple)
{
PLUGIN_RPC.window_show_message(
MessageType::ERROR,
format!("failed to download rust-analyzer: {error}"),
);

return Ok(());
}
}

let pwd = VoltEnvironment::uri()?;
let server_path = Url::parse(&pwd)?.join(&file_path.as_os_str().to_string_lossy())?;

PLUGIN_RPC.start_lsp(
server_path,
Vec::new(),
vec![DocumentFilter {
language: Some(String::from("rust")),
scheme: None,
pattern: None,
}],
config.map(|config| config.rust_analyzer).unwrap_or(None),
);

Ok(())
}

fn download_rust_analyzer(
nightly: bool,
target: &PathBuf,
architecture: &str,
target_triple: &str,
) -> Result<()> {
let gz_path = PathBuf::from("rust-analyzer.gz");

let url = if nightly {
format!("https://github.com/rust-lang/rust-analyzer/releases/download/nightly/rust-analyzer-{architecture}-{target_triple}.gz")
} else {
format!("https://github.com/rust-lang/rust-analyzer/releases/latest/download/rust-analyzer-{architecture}-{target_triple}.gz")
};

let mut response = Http::get(&url)?;
let body = response.body_read_all()?;
fs::write(&gz_path, body)?;

let mut gz = GzDecoder::new(File::open(&gz_path)?);
let mut file = File::create(target)?;
io::copy(&mut gz, &mut file)?;

fs::remove_file(&gz_path)?;

Ok(())
}
2 changes: 1 addition & 1 deletion volt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ icon = "rust-logo.svg"
language = ["rust"]
workspace-contains = ["*/Cargo.toml"]

[config."rustAnalyzer.nightly"]
[config."rustAnalyzerBuilds.nightly"]
default = false
description = "Whether to fetch daily nightly builds of rust-analyzer for usage in the editor."

0 comments on commit ee6dca7

Please sign in to comment.