A simple CPU rendered GUI IDE experience.
| -rw-r--r-- | src/commands.rs | 19 | ||||
| -rw-r--r-- | src/edi.rs | 118 | ||||
| -rw-r--r-- | src/gotolist.rs | 14 | ||||
| -rw-r--r-- | src/lsp/client.rs | 21 |
4 files changed, 96 insertions, 76 deletions
diff --git a/src/commands.rs b/src/commands.rs index d32f3c9..fc37f45 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -14,7 +14,7 @@ use rust_analyzer::lsp::ext::*; use crate::FG; use crate::edi::{Editor, lsp_m}; use crate::gotolist::{At, GoToList}; -use crate::lsp::{PathURI, Rq}; +use crate::lsp::{PathURI, Rq, tdpp}; use crate::menu::charc; use crate::menu::generic::{CorA, GenericMenu, MenuData}; use crate::sym::GoTo; @@ -109,6 +109,8 @@ commands!( @ RAOpenCargoToml: "open-cargo-toml", /// Runs the test at the cursor @ RARunTest: "run-test", + /// Go to the references to this symbol + @ References: "references", // /// View child modules // @ ViewChildModules: "child-modules", /// GoTo line, @@ -309,7 +311,7 @@ impl Editor { self.bar.last_action = "no such parent".into(); return Ok(()); }; - self.open_loclink(x, w); + self.go(x, w)?; } Cmd::RAJoinLines => { let teds = @@ -384,7 +386,7 @@ impl Editor { else { bail!("wtf?"); }; - self.open_loc(x, w); + self.go(x, w)?; } Cmd::RARunnables => { let p = self.text.to_l_position(*self.text.cursor.first()); @@ -392,6 +394,17 @@ impl Editor { let x = l.runtime.spawn(l.runnables(&o, p)?); self.state = crate::edi::st::State::Runnables(Rq::new(x)); } + Cmd::References => + self.state = crate::edi::st::State::GoToL(GoToList { + data: ( + vec![], + Some(crate::gotolist::O::References(Rq::new( + l.runtime + .spawn(l.go_to_references(tdpp!(self))?), + ))), + ), + ..default() + }), _ => unimplemented!(), } Ok(()) @@ -514,6 +514,13 @@ impl Editor { }); } State::GoToL(z) => match &mut z.data.1 { + Some(crate::gotolist::O::References(y)) => { + y.poll(|x, _| { + x.ok().flatten().map(|x| { + z.data.0 = x.iter().map(GoTo::from).collect() + }) + }); + } Some(crate::gotolist::O::Impl(y)) => { y.poll(|x, _| { x.ok().map(|x| { @@ -877,8 +884,10 @@ impl Editor { self.hist.lc = text.cursor.clone(); } Some(Do::GoToDefinition) => { - if let Some(x) = self.requests.def.result.clone() { - self.open_loclink(&x, w.clone()); + if let Some(x) = self.requests.def.result.clone() + && let Err(e) = self.go(&x, w.clone()) + { + log::error!("gtd: {e}"); } } Some(Do::InsertCursorAtMouse) => { @@ -1162,44 +1171,12 @@ impl Editor { } } } - Some(Do::SymbolsSelect(x)) => 'out: { + Some(Do::SymbolsSelect(x)) => + if let Some(Ok(x)) = x.sel() + && let Err(e) = self.go(x.at, window.clone()) { - if let Some(Ok(x)) = x.sel() - && let Err(e) = try bikeshed rootcause::Result<()> { - match x.at.at { - At::R(r) => { - let f = x.at.path.canonicalize()?; - self.state = State::Default; - self.requests.complete = - CompletionState::None; - if Some(&f) != self.origin.as_ref() { - self.open(&f, window.clone())?; - } - let p = self.text.l_position(r.start).ok_or( - report!("provided range out of bound") - .context_custom::<WDebug, _>(r), - )?; - if p != 0 { - self.text - .cursor - .just(p, &self.text.rope); - } - self.text.scroll_to_cursor_centering(); - } - At::P(x) => { - self.text - .cursor - .just(x, &self.text.rope); - self.text.scroll_to_cursor_centering(); - break 'out; - } - }; - } - { - log::error!("alas! {e}"); - } - } - } + log::error!("alas! {e}"); + }, Some(Do::RenameSymbol(to)) => { if let Some((lsp, f)) = lsp!(self + p) { let x = lsp @@ -1276,10 +1253,9 @@ impl Editor { }, ) .unwrap(); - let mut r2 = Rq::default(); - r2.request(lsp.runtime.spawn(async { r.0.await })); - self.state = State::CodeAction(r2); + self.state = + State::CodeAction(Rq::new(lsp.runtime.spawn(r.0))); } } Some(Do::CASelectLeft) => { @@ -1809,15 +1785,12 @@ impl Editor { ))); } } - Some(Do::GTLSelect(x)) => { - if let Some(Ok(GoTo { path: p, at: At::R(r) })) = x.sel() - && Some(&*p) == self.origin.as_deref() + Some(Do::GTLSelect(x)) => + if let Some(Ok(g)) = x.sel() + && let Err(e) = self.go(g, window.clone()) { - let x = self.text.l_range(r).unwrap(); - self.text.vo = self.text.char_to_line(x.start); - self.text.cursor.just(x.start, &self.text.rope); - } - } + eprintln!("go-to-list select fail: {e}"); + }, Some(Do::GT) => { let State::GoToL(x) = &mut self.state else { unreachable!() @@ -2006,32 +1979,33 @@ impl Editor { } Ok(()) } - /// this is so dumb - pub fn open_loc( - &mut self, - Location { uri, range }: &Location, - w: Arc<dyn Window>, - ) { - self.open(&uri.to_file_path().unwrap(), w.clone()).unwrap(); - self.text.cursor.just( - self.text.l_position(range.start).unwrap(), - &self.text.rope, - ); - self.text.scroll_to_cursor(); - } - pub fn open_loclink( + pub fn go( &mut self, - LocationLink { target_uri, target_range, .. }: &LocationLink, + g: impl Into<GoTo<'_>>, w: Arc<dyn Window>, - ) { - self.open(&target_uri.to_file_path().unwrap(), w.clone()).unwrap(); + ) -> rootcause::Result<()> { + let g = g.into(); + let f = g.path.canonicalize()?; + self.open(&f, w.clone())?; - self.text.cursor.just( - self.text.l_position(target_range.start).unwrap(), - &self.text.rope, - ); - self.text.scroll_to_cursor(); + match g.at { + At::R(r) => { + let p = self.text.l_position(r.start).ok_or( + report!("provided range out of bound") + .context_custom::<WDebug, _>(r), + )?; + if p != 0 { + self.text.cursor.just(p, &self.text.rope); + } + self.text.scroll_to_cursor_centering(); + } + At::P(x) => { + self.text.cursor.just(x, &self.text.rope); + self.text.scroll_to_cursor_centering(); + } + }; + Ok(()) } } use NamedKey::*; diff --git a/src/gotolist.rs b/src/gotolist.rs index 8461021..3fee279 100644 --- a/src/gotolist.rs +++ b/src/gotolist.rs @@ -4,7 +4,7 @@ use std::path::Path; use dsb::Cell; use dsb::cell::Style; use lsp_types::request::GotoImplementation; -use lsp_types::{Location, Range}; +use lsp_types::{Location, LocationLink, Range}; use crate::FG; use crate::lsp::RqS; @@ -16,6 +16,7 @@ pub enum GTL {} #[derive(Debug)] pub enum O { Impl(RqS<(), GotoImplementation>), + References(RqS<(), lsp_types::request::References>), Bmk, } impl<'a> Key<'a> for GoTo<'a> { @@ -106,6 +107,17 @@ impl From<&Location> for GoTo<'static> { } } +impl From<&LocationLink> for GoTo<'static> { + fn from( + LocationLink { target_uri, target_range, .. }: &LocationLink, + ) -> Self { + Self { + path: Cow::Owned(target_uri.to_file_path().unwrap()), + at: At::R(*target_range), + } + } +} + #[derive(Debug, Eq, PartialEq, Clone, Copy)] pub enum At { R(Range), diff --git a/src/lsp/client.rs b/src/lsp/client.rs index 65225db..3c5dc93 100644 --- a/src/lsp/client.rs +++ b/src/lsp/client.rs @@ -554,6 +554,27 @@ impl Client { }) .map(fst) } + + pub fn go_to_references( + &self, + tdpp: TextDocumentPositionParams, + ) -> Result< + impl Future< + Output = Result< + Option<Vec<Location>>, + RequestError<References>, + >, + >, + SendError<Message>, + > { + self.request::<References>(&ReferenceParams { + text_document_position: tdpp, + work_done_progress_params: default(), + partial_result_params: default(), + context: ReferenceContext { include_declaration: false }, + }) + .map(fst) + } } pub trait PathURI { |