A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/commands.rs')
| -rw-r--r-- | src/commands.rs | 155 |
1 files changed, 153 insertions, 2 deletions
diff --git a/src/commands.rs b/src/commands.rs index c21acb1..c85911b 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,13 +1,21 @@ use std::iter::repeat; use std::path::Path; +use std::process::Stdio; +use std::sync::Arc; use Default::default; +use Into::into; +use anyhow::{anyhow, bail}; use dsb::Cell; use dsb::cell::Style; +use lsp_types::*; +use rust_analyzer::lsp::ext::*; use crate::FG; +use crate::edi::{Editor, lsp_m}; +use crate::lsp::PathURI; use crate::menu::{back, charc, filter, next, score}; -use crate::text::{TextArea, col, color_}; +use crate::text::{RopeExt, SortTedits, TextArea, col, color_}; macro_rules! commands { ($(#[doc = $d: literal] $t:tt $identifier: ident: $c:literal),+ $(,)?) => { @@ -44,7 +52,18 @@ commands!( @ RARestart: "ra-restart", /// go to parent module @ RAParent: "parent", - + /// join lines under cursors. + @ RAJoinLines: "join-lines", + /// gets list of runnables + @ RARunnables: "runnables", + /// Open docs for type at cursor + @ RADocs: "open-docs", + /// Rebuilds rust-analyzer proc macros + @ RARebuildProcMacros: "rebuild-proc-macros", + /// Cancels current running rust-analyzer check process + @ RACancelFlycheck: "cancel-flycheck", + /// Opens Cargo.toml file for this workspace + @ RAOpenCargoToml: "open-cargo-toml" ); #[derive(Debug, Default)] @@ -157,3 +176,135 @@ fn r( }); to.extend(b); } + +impl Editor { + pub fn handle_command( + &mut self, + z: Cmd, + w: Arc<winit::window::Window>, + ) -> anyhow::Result<()> { + if !z.needs_lsp() { + return Ok(()); + } + let Some((l, o)) = lsp_m!(self + p) else { + bail!("no lsp"); + }; + + match z { + Cmd::RAMoveIU | Cmd::RAMoveID => { + let r = self + .text + .to_l_position(*self.text.cursor.first()) + .unwrap(); + let mut x = l.request_immediate::<rust_analyzer::lsp::ext::MoveItem>(&MoveItemParams { + direction: if let Cmd::RAMoveIU = z { MoveItemDirection::Up } else { MoveItemDirection::Down }, + text_document: o.tid(), + range: Range { start : r, end : r}, + })?; + + x.sort_tedits(); + for t in x { + self.text.apply_snippet_tedit(&t)?; + } + } + Cmd::RARestart => { + _ = l.request::<ReloadWorkspace>(&())?.0; + } + Cmd::RAParent => { + let Some(GotoDefinitionResponse::Link([ref x])) = + l.request_immediate::<ParentModule>( + &TextDocumentPositionParams { + text_document: o.tid(), + position: self + .text + .to_l_position(*self.text.cursor.first()) + .unwrap(), + }, + )? + else { + self.bar.last_action = "no such parent".into(); + return Ok(()); + }; + self.open_loclink(x, w); + } + Cmd::RAJoinLines => { + let teds = + l.request_immediate::<JoinLines>(&JoinLinesParams { + ranges: self + .text + .cursor + .iter() + .filter_map(|x| { + self.text.to_l_range( + x.sel.map(into).unwrap_or(*x..*x), + ) + }) + .collect(), + text_document: o.tid(), + })?; + self.text + .apply_tedits(&mut { teds }) + .map_err(|_| anyhow!("couldnt apply edits"))?; + } + Cmd::RADocs => { + let u = l.request_immediate::<ExternalDocs>( + &TextDocumentPositionParams { + position: self + .text + .to_l_position(*self.text.cursor.first()) + .unwrap(), + text_document: o.tid(), + }, + )?; + use rust_analyzer::lsp::ext::ExternalDocsResponse::*; + std::process::Command::new("firefox-nightly") + .arg( + match &u { + WithLocal(ExternalDocsPair { + web: Some(x), + .. + }) if let Some("doc.rust-lang.org") = + x.domain() + && let Some(x) = + x.path().strip_prefix("/nightly/") + && option_env!("USER") == Some("os") => + format!("http://127.0.0.1:3242/{x}"), // i have a lighttpd server running + WithLocal(ExternalDocsPair { + local: Some(url), + .. + }) if let Ok(p) = url.to_file_path() + && p.exists() => + url.to_string(), + WithLocal(ExternalDocsPair { + web: Some(url), + .. + }) + | Simple(Some(url)) => url.to_string(), + _ => return Ok(()), + } + .to_string(), + ) + .stdout(Stdio::null()) + .spawn() + .unwrap(); + } + Cmd::RARebuildProcMacros => { + _ = l.request::<RebuildProcMacros>(&())?; + } + Cmd::RACancelFlycheck => l.notify::<CancelFlycheck>(&())?, + Cmd::RAOpenCargoToml => { + let Some(GotoDefinitionResponse::Scalar(x)) = + &l.request_immediate::<OpenCargoToml>( + &OpenCargoTomlParams { text_document: o.tid() }, + )? + else { + bail!("wtf?"); + }; + self.open_loc(x, w); + } + _ => unimplemented!(), + } + + Ok(()) + } +} |