A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/commands.rs')
-rw-r--r--src/commands.rs155
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(())
+ }
+}