WIP: Start on a GoToDefinition action for the editor

This commit is contained in:
Antonio Scandurra 2022-01-20 12:26:04 +01:00
parent cbbf7391e8
commit 66734e11af
2 changed files with 57 additions and 2 deletions

View file

@ -25,8 +25,8 @@ use gpui::{
use items::BufferItemHandle;
use itertools::Itertools as _;
use language::{
BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point, Selection, SelectionGoal,
TransactionId,
AnchorRangeExt as _, BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point,
Selection, SelectionGoal, TransactionId,
};
pub use multi_buffer::{
Anchor, AnchorRangeExt, ExcerptId, ExcerptProperties, MultiBuffer, ToOffset, ToPoint,
@ -107,6 +107,7 @@ action!(SelectLargerSyntaxNode);
action!(SelectSmallerSyntaxNode);
action!(MoveToEnclosingBracket);
action!(ShowNextDiagnostic);
action!(GoToDefinition);
action!(PageUp);
action!(PageDown);
action!(Fold);
@ -214,6 +215,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
Binding::new("alt-down", SelectSmallerSyntaxNode, Some("Editor")),
Binding::new("ctrl-shift-W", SelectSmallerSyntaxNode, Some("Editor")),
Binding::new("f8", ShowNextDiagnostic, Some("Editor")),
Binding::new("alt-enter", GoToDefinition, Some("Editor")),
Binding::new("ctrl-m", MoveToEnclosingBracket, Some("Editor")),
Binding::new("pageup", PageUp, Some("Editor")),
Binding::new("pagedown", PageDown, Some("Editor")),
@ -277,6 +279,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
cx.add_action(Editor::select_smaller_syntax_node);
cx.add_action(Editor::move_to_enclosing_bracket);
cx.add_action(Editor::show_next_diagnostic);
cx.add_action(Editor::go_to_definition);
cx.add_action(Editor::page_up);
cx.add_action(Editor::page_down);
cx.add_action(Editor::fold);
@ -2984,6 +2987,45 @@ impl Editor {
}
}
pub fn go_to_definition(
workspace: &mut Workspace,
_: &GoToDefinition,
cx: &mut ViewContext<Workspace>,
) {
let editor = workspace
.active_item(cx)
.and_then(|item| item.to_any().downcast::<Self>())
.unwrap()
.read(cx);
let buffer = editor.buffer.read(cx);
let head = editor.newest_selection::<usize>(&buffer.read(cx)).head();
let (buffer, head) = editor.buffer.read(cx).text_anchor_for_position(head, cx);
let definitions = workspace
.project()
.update(cx, |project, cx| project.definition(&buffer, head, cx));
cx.spawn(|workspace, mut cx| async move {
let definitions = definitions.await?;
workspace.update(&mut cx, |workspace, cx| {
for definition in definitions {
let range = definition
.target_range
.to_offset(definition.target_buffer.read(cx));
let target_editor = workspace
.open_item(BufferItemHandle(definition.target_buffer), cx)
.to_any()
.downcast::<Self>()
.unwrap();
target_editor.update(cx, |target_editor, cx| {
target_editor.select_ranges([range], Some(Autoscroll::Fit), cx);
});
}
});
Ok::<(), anyhow::Error>(())
})
.detach_and_log_err(cx);
}
fn refresh_active_diagnostics(&mut self, cx: &mut ViewContext<Editor>) {
if let Some(active_diagnostics) = self.active_diagnostics.as_mut() {
let buffer = self.buffer.read(cx).snapshot(cx);

View file

@ -789,6 +789,19 @@ impl MultiBuffer {
cx.notify();
}
pub fn text_anchor_for_position<'a, T: ToOffset>(
&'a self,
position: T,
cx: &AppContext,
) -> (ModelHandle<Buffer>, language::Anchor) {
let snapshot = self.read(cx);
let anchor = snapshot.anchor_before(position);
(
self.buffers.borrow()[&anchor.buffer_id].buffer.clone(),
anchor.text_anchor,
)
}
fn on_buffer_event(
&mut self,
_: ModelHandle<Buffer>,