A simple CPU rendered GUI IDE experience.
-rw-r--r--Cargo.toml1
-rw-r--r--src/edi.rs11
-rw-r--r--src/lsp.rs10
-rw-r--r--src/lsp/client.rs11
-rw-r--r--src/lsp/init_opts.rs108
-rw-r--r--src/lsp/vsc_settings.rs18
6 files changed, 105 insertions, 54 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 90cb9c6..1ae2fd8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -73,6 +73,7 @@ rootcause = "0.12.1"
ttools = { git = "https://git.bendn.org/ttools" }
# ttools = { path = "../ttools/" }
bind = { package = "ftools", git = "https://git.bendn.org/bind" }
+json_value_merge = "2.0.1"
[profile.dev.package]
rust-analyzer.opt-level = 3
fimg.opt-level = 3
diff --git a/src/edi.rs b/src/edi.rs
index 07a65c7..bef34a4 100644
--- a/src/edi.rs
+++ b/src/edi.rs
@@ -32,7 +32,7 @@ use crate::error::WDebug;
use crate::gotolist::{At, GoTo};
use crate::hov::{self, Hovr};
use crate::lsp::{
- Anonymize, Client, Map_, PathURI, RequestError, Rq, tdpp,
+ Anonymize, Client, Map_, PathURI, RequestError, Rq, tdpp, vsc_settings,
};
use crate::menu::generic::MenuData;
use crate::meta::META;
@@ -190,6 +190,14 @@ impl Editor {
.and_then(|x| rooter(&x, "Cargo.toml"))
.and_then(|x| x.canonicalize().ok());
+ let vsc = o
+ .as_ref()
+ .and_then(|x| x.parent())
+ .and_then(|x| rooter(&x, ".vscode"))
+ .map(|x| (x.clone(), x.join(".vscode").join("settings.json")))
+ .filter(|x| x.1.exists())
+ .and_then(|(ws, x)| (vsc_settings::load(&x, &ws)).ok());
+
let mut loaded_state = false;
if let Some(ws) = me.workspace.as_deref()
&& let h = hash(&ws)
@@ -265,6 +273,7 @@ impl Editor {
.to_string_lossy()
.into_owned(),
},
+ vsc,
);
(&*Box::leak(Box::new(c)), (t2), Some(changed))
});
diff --git a/src/lsp.rs b/src/lsp.rs
index 332fd23..d6edf48 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -6,6 +6,7 @@ use std::thread::spawn;
use std::time::Instant;
use crossbeam::channel::{Receiver, Sender, unbounded};
+use json_value_merge::Merge;
use lsp_server::Message;
use lsp_types::notification::*;
use lsp_types::request::*;
@@ -18,10 +19,12 @@ pub use client::*;
mod init_opts;
mod rq;
pub use rq::*;
+pub mod vsc_settings;
pub fn run(
(tx, rx): (Sender<Message>, Receiver<Message>),
workspace: WorkspaceFolder,
+ vscode_conf: Option<serde_json::Value>,
) -> (Client, std::thread::JoinHandle<()>, oneshot::Sender<Arc<dyn Window>>)
{
let now = Instant::now();
@@ -46,7 +49,12 @@ pub fn run(
req_rx: _req_rx,
not_rx,
};
- _ = c.request::<Initialize>(&init_opts::get(workspace)).unwrap();
+ let mut opts = init_opts::get(workspace);
+ if let Some(v) = vscode_conf {
+ opts.initialization_options.as_mut().unwrap().merge(&v);
+ };
+ dbg!(opts.initialization_options.as_ref());
+ _ = c.request::<Initialize>(&opts).unwrap();
let x = serde_json::from_value::<InitializeResult>(
rx.recv().unwrap().response().unwrap().result.unwrap(),
)
diff --git a/src/lsp/client.rs b/src/lsp/client.rs
index 3c5dc93..2650b5f 100644
--- a/src/lsp/client.rs
+++ b/src/lsp/client.rs
@@ -6,6 +6,7 @@ use std::sync::atomic::Ordering::Relaxed;
use Default::default;
use crossbeam::channel::{Receiver, SendError, Sender};
use futures::FutureExt;
+use json_value_merge::Merge;
use log::debug;
use lsp_server::{
Message, Notification as N, Request as LRq, Response as Re,
@@ -18,6 +19,7 @@ use tokio::sync::oneshot;
use ttools::*;
use crate::lsp::BehaviourAfter::{self, *};
+use crate::lsp::init_opts::ra_config;
use crate::lsp::{RequestError, Rq};
use crate::text::cursor::ceach;
use crate::text::{RopeExt, SortTedits, TextArea};
@@ -575,6 +577,15 @@ impl Client {
})
.map(fst)
}
+
+ pub fn _update_config(&self, with: serde_json::Value) {
+ let mut x = ra_config();
+ x.merge(&with);
+ self.notify::<DidChangeConfiguration>(
+ &DidChangeConfigurationParams { settings: x },
+ )
+ .unwrap();
+ }
}
pub trait PathURI {
diff --git a/src/lsp/init_opts.rs b/src/lsp/init_opts.rs
index 19bd140..301d295 100644
--- a/src/lsp/init_opts.rs
+++ b/src/lsp/init_opts.rs
@@ -302,61 +302,65 @@ pub fn get(workspace: WorkspaceFolder) -> InitializeParams {
name: "gracilaria".into(),
version: Some(env!("CARGO_PKG_VERSION").into()),
}),
- initialization_options: Some(json! {{
- "cargo": {
- "buildScripts": { "enable": true }
- },
- "procMacro": {
- "enable": true,
- "attributes": { "enable": true }
- },
- "hover": {
- "documentation": {
- "keywords": { "enable": false },
- },
- },
- "inlayHints": {
- "closureReturnTypeHints": { "enable": "with_block" },
- "closingBraceHints": { "minLines": 5 },
- "closureStyle": "rust_analyzer",
- "genericParameterHints": { "type": { "enable": true } },
- "rangeExclusiveHints": { "enable": true },
- "closureCaptureHints": { "enable": true },
- },
- "typing": { "triggerChars": ".=<>{(+" },
- "assist": { "preferSelf": true },
- "checkOnSave": true,
- "diagnostics": { "enable": true },
- "semanticHighlighting": {
- "punctuation": {
- "separate": {
- "macroBang": true
- },
- "specialization": { "enable": true },
- "enable": true
- }
- },
- "workspace": {
- "symbol": {
- "search": { "limit": 1024 }
- }
- },
- "showUnlinkedFileNotification": false,
- "completion": {
- "fullFunctionSignatures": { "enable": true, },
- "autoIter": { "enable": false, },
- "autoImport": { "enable": true, },
- "termSearch": { "enable": true, },
- "autoself": { "enable": true, },
- "privateEditable": { "enable": true },
- },
- "imports": {
- "granularity": "group",
- },
- }}),
+ initialization_options: Some(ra_config()),
trace: None,
workspace_folders: Some(vec![workspace]),
..default()
}
}
+pub fn ra_config() -> serde_json::Value {
+ json! {{
+ "cargo": {
+ "buildScripts": { "enable": true }
+ },
+ "procMacro": {
+ "enable": true,
+ "attributes": { "enable": true }
+ },
+ "hover": {
+ "documentation": {
+ "keywords": { "enable": false },
+ },
+ },
+ "inlayHints": {
+ "closureReturnTypeHints": { "enable": "with_block" },
+ "closingBraceHints": { "minLines": 5 },
+ "closureStyle": "rust_analyzer",
+ "genericParameterHints": { "type": { "enable": true } },
+ "rangeExclusiveHints": { "enable": true },
+ "closureCaptureHints": { "enable": true },
+ },
+ "typing": { "triggerChars": ".=<>{(+" },
+ "assist": { "preferSelf": true },
+ "checkOnSave": true,
+ "diagnostics": { "enable": true },
+ "semanticHighlighting": {
+ "punctuation": {
+ "separate": {
+ "macroBang": true
+ },
+ "specialization": { "enable": true },
+ "enable": true
+ }
+ },
+ "workspace": {
+ "symbol": {
+ "search": { "limit": 1024 }
+ }
+ },
+ "showUnlinkedFileNotification": false,
+ "completion": {
+ "fullFunctionSignatures": { "enable": true, },
+ "autoIter": { "enable": false, },
+ "autoImport": { "enable": true, },
+ "termSearch": { "enable": true, },
+ "autoself": { "enable": true, },
+ "privateEditable": { "enable": true },
+ },
+ "imports": {
+ "granularity": "group",
+ },
+ }
+ }
+}
diff --git a/src/lsp/vsc_settings.rs b/src/lsp/vsc_settings.rs
new file mode 100644
index 0000000..570ebe3
--- /dev/null
+++ b/src/lsp/vsc_settings.rs
@@ -0,0 +1,18 @@
+use std::path::Path;
+use std::process::Stdio;
+
+use rootcause::prelude::ResultExt;
+use rootcause::report;
+
+pub fn load(p: &Path, ws: &Path) -> rootcause::Result<serde_json::Value> {
+ let std::process::Output {stdout, stderr,.. } = std::process::Command::new("jq").stdout(Stdio::piped())
+ .args(["-M", "-c", "-r", r#"reduce to_entries[] as $x ({}; setpath(($x.key | split(".")); $x.value)) | ."rust-analyzer""#, &p.to_string_lossy()]).spawn()?.wait_with_output()
+ ?;
+ let stdout = String::from_utf8(stdout)?.replace(
+ "${workspaceFolder}",
+ ws.to_str().ok_or(report!("bad path :("))?,
+ );
+ Ok(serde_json::from_str(&stdout).context_with(move || {
+ String::from_utf8(stderr).unwrap_or("dang".into())
+ })?)
+}