A simple CPU rendered GUI IDE experience.
references
bendn 4 weeks ago
parent d9f9455 · commit fa4e47e
-rw-r--r--src/commands.rs19
-rw-r--r--src/edi.rs118
-rw-r--r--src/gotolist.rs14
-rw-r--r--src/lsp/client.rs21
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(())
diff --git a/src/edi.rs b/src/edi.rs
index 35a4ef8..b2c437e 100644
--- a/src/edi.rs
+++ b/src/edi.rs
@@ -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 {