A simple CPU rendered GUI IDE experience.
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/edi.rs | 11 | ||||
| -rw-r--r-- | src/lsp.rs | 10 | ||||
| -rw-r--r-- | src/lsp/client.rs | 11 | ||||
| -rw-r--r-- | src/lsp/init_opts.rs | 108 | ||||
| -rw-r--r-- | src/lsp/vsc_settings.rs | 18 |
6 files changed, 105 insertions, 54 deletions
@@ -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 @@ -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)) }); @@ -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()) + })?) +} |