Merge branch 'main' into copilot-disabled-globs
This commit is contained in:
commit
9d41f83b1b
81 changed files with 1649 additions and 1545 deletions
|
@ -23,6 +23,7 @@ test-support = [
|
|||
]
|
||||
|
||||
[dependencies]
|
||||
client = { path = "../client" }
|
||||
clock = { path = "../clock" }
|
||||
copilot = { path = "../copilot" }
|
||||
db = { path = "../db" }
|
||||
|
|
|
@ -22,6 +22,7 @@ pub mod test;
|
|||
use aho_corasick::AhoCorasick;
|
||||
use anyhow::{anyhow, Result};
|
||||
use blink_manager::BlinkManager;
|
||||
use client::ClickhouseEvent;
|
||||
use clock::ReplicaId;
|
||||
use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
|
||||
use copilot::Copilot;
|
||||
|
@ -51,8 +52,8 @@ use itertools::Itertools;
|
|||
pub use language::{char_kind, CharKind};
|
||||
use language::{
|
||||
AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, CursorShape,
|
||||
Diagnostic, DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, OffsetUtf16,
|
||||
Point, Selection, SelectionGoal, TransactionId,
|
||||
Diagnostic, DiagnosticSeverity, File, IndentKind, IndentSize, Language, OffsetRangeExt,
|
||||
OffsetUtf16, Point, Selection, SelectionGoal, TransactionId,
|
||||
};
|
||||
use link_go_to_definition::{
|
||||
hide_link_definition, show_link_definition, LinkDefinitionKind, LinkGoToDefinitionState,
|
||||
|
@ -808,10 +809,13 @@ impl CompletionsMenu {
|
|||
},
|
||||
)
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(ConfirmCompletion {
|
||||
item_ix: Some(item_ix),
|
||||
});
|
||||
.on_down(MouseButton::Left, move |_, this, cx| {
|
||||
this.confirm_completion(
|
||||
&ConfirmCompletion {
|
||||
item_ix: Some(item_ix),
|
||||
},
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.into_any(),
|
||||
);
|
||||
|
@ -969,9 +973,23 @@ impl CodeActionsMenu {
|
|||
.with_style(item_style)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
||||
cx.dispatch_action(ConfirmCodeAction {
|
||||
item_ix: Some(item_ix),
|
||||
.on_down(MouseButton::Left, move |_, this, cx| {
|
||||
let workspace = this
|
||||
.workspace
|
||||
.as_ref()
|
||||
.and_then(|(workspace, _)| workspace.upgrade(cx));
|
||||
cx.window_context().defer(move |cx| {
|
||||
if let Some(workspace) = workspace {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
if let Some(task) = Editor::confirm_code_action(
|
||||
workspace,
|
||||
&Default::default(),
|
||||
cx,
|
||||
) {
|
||||
task.detach_and_log_err(cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.into_any(),
|
||||
|
@ -1295,7 +1313,7 @@ impl Editor {
|
|||
cx.set_global(ScrollbarAutoHide(should_auto_hide_scrollbars));
|
||||
}
|
||||
|
||||
this.report_event("open editor", cx);
|
||||
this.report_editor_event("open", cx);
|
||||
this
|
||||
}
|
||||
|
||||
|
@ -1330,6 +1348,10 @@ impl Editor {
|
|||
&self.buffer
|
||||
}
|
||||
|
||||
fn workspace(&self, cx: &AppContext) -> Option<ViewHandle<Workspace>> {
|
||||
self.workspace.as_ref()?.0.upgrade(cx)
|
||||
}
|
||||
|
||||
pub fn title<'a>(&self, cx: &'a AppContext) -> Cow<'a, str> {
|
||||
self.buffer().read(cx).title(cx)
|
||||
}
|
||||
|
@ -1356,6 +1378,10 @@ impl Editor {
|
|||
self.buffer.read(cx).language_at(point, cx)
|
||||
}
|
||||
|
||||
pub fn file_at<'a, T: ToOffset>(&self, point: T, cx: &'a AppContext) -> Option<Arc<dyn File>> {
|
||||
self.buffer.read(cx).read(cx).file_at(point).cloned()
|
||||
}
|
||||
|
||||
pub fn active_excerpt(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
|
@ -3148,10 +3174,13 @@ impl Editor {
|
|||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.with_padding(Padding::uniform(3.))
|
||||
.on_down(MouseButton::Left, |_, _, cx| {
|
||||
cx.dispatch_action(ToggleCodeActions {
|
||||
deployed_from_indicator: true,
|
||||
});
|
||||
.on_down(MouseButton::Left, |_, this, cx| {
|
||||
this.toggle_code_actions(
|
||||
&ToggleCodeActions {
|
||||
deployed_from_indicator: true,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.into_any(),
|
||||
)
|
||||
|
@ -3209,11 +3238,13 @@ impl Editor {
|
|||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.with_padding(Padding::uniform(3.))
|
||||
.on_click(MouseButton::Left, {
|
||||
move |_, _, cx| {
|
||||
cx.dispatch_any_action(match fold_status {
|
||||
FoldStatus::Folded => Box::new(UnfoldAt { buffer_row }),
|
||||
FoldStatus::Foldable => Box::new(FoldAt { buffer_row }),
|
||||
});
|
||||
move |_, editor, cx| match fold_status {
|
||||
FoldStatus::Folded => {
|
||||
editor.unfold_at(&UnfoldAt { buffer_row }, cx);
|
||||
}
|
||||
FoldStatus::Foldable => {
|
||||
editor.fold_at(&FoldAt { buffer_row }, cx);
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_any()
|
||||
|
@ -5572,93 +5603,77 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn go_to_definition(
|
||||
workspace: &mut Workspace,
|
||||
_: &GoToDefinition,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
Self::go_to_definition_of_kind(GotoDefinitionKind::Symbol, workspace, cx);
|
||||
pub fn go_to_definition(&mut self, _: &GoToDefinition, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_definition_of_kind(GotoDefinitionKind::Symbol, cx);
|
||||
}
|
||||
|
||||
pub fn go_to_type_definition(
|
||||
workspace: &mut Workspace,
|
||||
_: &GoToTypeDefinition,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
Self::go_to_definition_of_kind(GotoDefinitionKind::Type, workspace, cx);
|
||||
pub fn go_to_type_definition(&mut self, _: &GoToTypeDefinition, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_definition_of_kind(GotoDefinitionKind::Type, cx);
|
||||
}
|
||||
|
||||
fn go_to_definition_of_kind(
|
||||
kind: GotoDefinitionKind,
|
||||
workspace: &mut Workspace,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
let active_item = workspace.active_item(cx);
|
||||
let editor_handle = if let Some(editor) = active_item
|
||||
.as_ref()
|
||||
.and_then(|item| item.act_as::<Self>(cx))
|
||||
{
|
||||
editor
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let editor = editor_handle.read(cx);
|
||||
let buffer = editor.buffer.read(cx);
|
||||
let head = editor.selections.newest::<usize>(cx).head();
|
||||
fn go_to_definition_of_kind(&mut self, kind: GotoDefinitionKind, cx: &mut ViewContext<Self>) {
|
||||
let Some(workspace) = self.workspace(cx) else { return };
|
||||
let buffer = self.buffer.read(cx);
|
||||
let head = self.selections.newest::<usize>(cx).head();
|
||||
let (buffer, head) = if let Some(text_anchor) = buffer.text_anchor_for_position(head, cx) {
|
||||
text_anchor
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let project = workspace.project().clone();
|
||||
let project = workspace.read(cx).project().clone();
|
||||
let definitions = project.update(cx, |project, cx| match kind {
|
||||
GotoDefinitionKind::Symbol => project.definition(&buffer, head, cx),
|
||||
GotoDefinitionKind::Type => project.type_definition(&buffer, head, cx),
|
||||
});
|
||||
|
||||
cx.spawn_labeled("Fetching Definition...", |workspace, mut cx| async move {
|
||||
cx.spawn_labeled("Fetching Definition...", |editor, mut cx| async move {
|
||||
let definitions = definitions.await?;
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
Editor::navigate_to_definitions(workspace, editor_handle, definitions, cx);
|
||||
editor.update(&mut cx, |editor, cx| {
|
||||
editor.navigate_to_definitions(definitions, cx);
|
||||
})?;
|
||||
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
pub fn navigate_to_definitions(
|
||||
workspace: &mut Workspace,
|
||||
editor_handle: ViewHandle<Editor>,
|
||||
definitions: Vec<LocationLink>,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
&mut self,
|
||||
mut definitions: Vec<LocationLink>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
let pane = workspace.active_pane().clone();
|
||||
let Some(workspace) = self.workspace(cx) else { return };
|
||||
let pane = workspace.read(cx).active_pane().clone();
|
||||
// If there is one definition, just open it directly
|
||||
if let [definition] = definitions.as_slice() {
|
||||
if definitions.len() == 1 {
|
||||
let definition = definitions.pop().unwrap();
|
||||
let range = definition
|
||||
.target
|
||||
.range
|
||||
.to_offset(definition.target.buffer.read(cx));
|
||||
|
||||
let target_editor_handle =
|
||||
workspace.open_project_item(definition.target.buffer.clone(), cx);
|
||||
target_editor_handle.update(cx, |target_editor, cx| {
|
||||
// When selecting a definition in a different buffer, disable the nav history
|
||||
// to avoid creating a history entry at the previous cursor location.
|
||||
if editor_handle != target_editor_handle {
|
||||
pane.update(cx, |pane, _| pane.disable_history());
|
||||
}
|
||||
target_editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
if Some(&definition.target.buffer) == self.buffer.read(cx).as_singleton().as_ref() {
|
||||
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select_ranges([range]);
|
||||
});
|
||||
|
||||
pane.update(cx, |pane, _| pane.enable_history());
|
||||
});
|
||||
} else {
|
||||
cx.window_context().defer(move |cx| {
|
||||
let target_editor: ViewHandle<Self> = workspace.update(cx, |workspace, cx| {
|
||||
workspace.open_project_item(definition.target.buffer.clone(), cx)
|
||||
});
|
||||
target_editor.update(cx, |target_editor, cx| {
|
||||
// When selecting a definition in a different buffer, disable the nav history
|
||||
// to avoid creating a history entry at the previous cursor location.
|
||||
pane.update(cx, |pane, _| pane.disable_history());
|
||||
target_editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select_ranges([range]);
|
||||
});
|
||||
pane.update(cx, |pane, _| pane.enable_history());
|
||||
});
|
||||
});
|
||||
}
|
||||
} else if !definitions.is_empty() {
|
||||
let replica_id = editor_handle.read(cx).replica_id(cx);
|
||||
let replica_id = self.replica_id(cx);
|
||||
let title = definitions
|
||||
.iter()
|
||||
.find(|definition| definition.origin.is_some())
|
||||
|
@ -5678,7 +5693,9 @@ impl Editor {
|
|||
.into_iter()
|
||||
.map(|definition| definition.target)
|
||||
.collect();
|
||||
Self::open_locations_in_multibuffer(workspace, locations, replica_id, title, cx)
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
Self::open_locations_in_multibuffer(workspace, locations, replica_id, title, cx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6834,7 +6851,7 @@ impl Editor {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn report_event(&self, name: &str, cx: &AppContext) {
|
||||
fn report_editor_event(&self, name: &'static str, cx: &AppContext) {
|
||||
if let Some((project, file)) = self.project.as_ref().zip(
|
||||
self.buffer
|
||||
.read(cx)
|
||||
|
@ -6846,11 +6863,31 @@ impl Editor {
|
|||
let extension = Path::new(file.file_name(cx))
|
||||
.extension()
|
||||
.and_then(|e| e.to_str());
|
||||
project.read(cx).client().report_event(
|
||||
name,
|
||||
json!({ "File Extension": extension, "Vim Mode": settings.vim_mode }),
|
||||
let telemetry = project.read(cx).client().telemetry().clone();
|
||||
telemetry.report_mixpanel_event(
|
||||
match name {
|
||||
"open" => "open editor",
|
||||
"save" => "save editor",
|
||||
_ => name,
|
||||
},
|
||||
json!({ "File Extension": extension, "Vim Mode": settings.vim_mode, "In Clickhouse": true }),
|
||||
settings.telemetry(),
|
||||
);
|
||||
let event = ClickhouseEvent::Editor {
|
||||
file_extension: extension.map(ToString::to_string),
|
||||
vim_mode: settings.vim_mode,
|
||||
operation: name,
|
||||
copilot_enabled: settings.features.copilot,
|
||||
copilot_enabled_for_language: settings.show_copilot_suggestions(
|
||||
self.language_at(0, cx)
|
||||
.map(|language| language.name())
|
||||
.as_deref(),
|
||||
self.file_at(0, cx)
|
||||
.map(|file| file.path().clone())
|
||||
.as_deref(),
|
||||
),
|
||||
};
|
||||
telemetry.report_clickhouse_event(event, settings.telemetry())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7494,8 +7531,16 @@ impl Deref for EditorStyle {
|
|||
|
||||
pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock {
|
||||
let mut highlighted_lines = Vec::new();
|
||||
for line in diagnostic.message.lines() {
|
||||
highlighted_lines.push(highlight_diagnostic_message(line));
|
||||
for (index, line) in diagnostic.message.lines().enumerate() {
|
||||
let line = match &diagnostic.source {
|
||||
Some(source) if index == 0 => {
|
||||
let source_highlight = Vec::from_iter(0..source.len());
|
||||
highlight_diagnostic_message(source_highlight, &format!("{source}: {line}"))
|
||||
}
|
||||
|
||||
_ => highlight_diagnostic_message(Vec::new(), line),
|
||||
};
|
||||
highlighted_lines.push(line);
|
||||
}
|
||||
|
||||
Arc::new(move |cx: &mut BlockContext| {
|
||||
|
@ -7519,11 +7564,14 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
|
|||
})
|
||||
}
|
||||
|
||||
pub fn highlight_diagnostic_message(message: &str) -> (String, Vec<usize>) {
|
||||
pub fn highlight_diagnostic_message(
|
||||
inital_highlights: Vec<usize>,
|
||||
message: &str,
|
||||
) -> (String, Vec<usize>) {
|
||||
let mut message_without_backticks = String::new();
|
||||
let mut prev_offset = 0;
|
||||
let mut inside_block = false;
|
||||
let mut highlights = Vec::new();
|
||||
let mut highlights = inital_highlights;
|
||||
for (match_ix, (offset, _)) in message
|
||||
.match_indices('`')
|
||||
.chain([(message.len(), "")])
|
||||
|
|
|
@ -211,10 +211,13 @@ impl EditorElement {
|
|||
enum GutterHandlers {}
|
||||
scene.push_mouse_region(
|
||||
MouseRegion::new::<GutterHandlers>(cx.view_id(), cx.view_id() + 1, gutter_bounds)
|
||||
.on_hover(|hover, _: &mut Editor, cx| {
|
||||
cx.dispatch_action(GutterHover {
|
||||
hovered: hover.started,
|
||||
})
|
||||
.on_hover(|hover, editor: &mut Editor, cx| {
|
||||
editor.gutter_hover(
|
||||
&GutterHover {
|
||||
hovered: hover.started,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
@ -309,25 +312,17 @@ impl EditorElement {
|
|||
editor.select(SelectPhase::End, cx);
|
||||
}
|
||||
|
||||
if let Some(workspace) = editor
|
||||
.workspace
|
||||
.as_ref()
|
||||
.and_then(|(workspace, _)| workspace.upgrade(cx))
|
||||
{
|
||||
if !pending_nonempty_selections && cmd && text_bounds.contains_point(position) {
|
||||
let (point, target_point) = position_map.point_for_position(text_bounds, position);
|
||||
if !pending_nonempty_selections && cmd && text_bounds.contains_point(position) {
|
||||
let (point, target_point) = position_map.point_for_position(text_bounds, position);
|
||||
|
||||
if point == target_point {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
if shift {
|
||||
go_to_fetched_type_definition(workspace, point, cx);
|
||||
} else {
|
||||
go_to_fetched_definition(workspace, point, cx);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
if point == target_point {
|
||||
if shift {
|
||||
go_to_fetched_type_definition(editor, point, cx);
|
||||
} else {
|
||||
go_to_fetched_definition(editor, point, cx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -762,8 +757,8 @@ impl EditorElement {
|
|||
|
||||
scene.push_mouse_region(
|
||||
MouseRegion::new::<FoldMarkers>(cx.view_id(), *id as usize, bound)
|
||||
.on_click(MouseButton::Left, move |_, _: &mut Editor, cx| {
|
||||
cx.dispatch_action(UnfoldAt { buffer_row })
|
||||
.on_click(MouseButton::Left, move |_, editor: &mut Editor, cx| {
|
||||
editor.unfold_at(&UnfoldAt { buffer_row }, cx)
|
||||
})
|
||||
.with_notify_on_hover(true)
|
||||
.with_notify_on_click(true),
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
use crate::{
|
||||
display_map::ToDisplayPoint, Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSnapshot,
|
||||
EditorStyle, RangeToAnchorExt,
|
||||
};
|
||||
use futures::FutureExt;
|
||||
use gpui::{
|
||||
actions,
|
||||
|
@ -12,11 +16,6 @@ use settings::Settings;
|
|||
use std::{ops::Range, sync::Arc, time::Duration};
|
||||
use util::TryFutureExt;
|
||||
|
||||
use crate::{
|
||||
display_map::ToDisplayPoint, Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSnapshot,
|
||||
EditorStyle, GoToDiagnostic, RangeToAnchorExt,
|
||||
};
|
||||
|
||||
pub const HOVER_DELAY_MILLIS: u64 = 350;
|
||||
pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200;
|
||||
|
||||
|
@ -668,8 +667,8 @@ impl DiagnosticPopover {
|
|||
..Default::default()
|
||||
})
|
||||
.on_move(|_, _, _| {}) // Consume move events so they don't reach regions underneath.
|
||||
.on_click(MouseButton::Left, |_, _, cx| {
|
||||
cx.dispatch_action(GoToDiagnostic)
|
||||
.on_click(MouseButton::Left, |_, this, cx| {
|
||||
this.go_to_diagnostic(&Default::default(), cx)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.with_tooltip::<PrimaryDiagnostic>(
|
||||
|
|
|
@ -636,7 +636,7 @@ impl Item for Editor {
|
|||
project: ModelHandle<Project>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
self.report_event("save editor", cx);
|
||||
self.report_editor_event("save", cx);
|
||||
let format = self.perform_format(project.clone(), FormatTrigger::Save, cx);
|
||||
let buffers = self.buffer().clone().read(cx).all_buffers();
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use crate::{Anchor, DisplayPoint, Editor, EditorSnapshot, SelectPhase};
|
||||
use gpui::{Task, ViewContext};
|
||||
use language::{Bias, ToOffset};
|
||||
use project::LocationLink;
|
||||
use settings::Settings;
|
||||
use util::TryFutureExt;
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::{
|
||||
Anchor, DisplayPoint, Editor, EditorSnapshot, GoToDefinition, GoToTypeDefinition, SelectPhase,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct LinkGoToDefinitionState {
|
||||
|
@ -250,70 +246,51 @@ pub fn hide_link_definition(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
|
|||
}
|
||||
|
||||
pub fn go_to_fetched_definition(
|
||||
workspace: &mut Workspace,
|
||||
editor: &mut Editor,
|
||||
point: DisplayPoint,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
go_to_fetched_definition_of_kind(LinkDefinitionKind::Symbol, workspace, point, cx);
|
||||
go_to_fetched_definition_of_kind(LinkDefinitionKind::Symbol, editor, point, cx);
|
||||
}
|
||||
|
||||
pub fn go_to_fetched_type_definition(
|
||||
workspace: &mut Workspace,
|
||||
editor: &mut Editor,
|
||||
point: DisplayPoint,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
go_to_fetched_definition_of_kind(LinkDefinitionKind::Type, workspace, point, cx);
|
||||
go_to_fetched_definition_of_kind(LinkDefinitionKind::Type, editor, point, cx);
|
||||
}
|
||||
|
||||
fn go_to_fetched_definition_of_kind(
|
||||
kind: LinkDefinitionKind,
|
||||
workspace: &mut Workspace,
|
||||
editor: &mut Editor,
|
||||
point: DisplayPoint,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
let active_item = workspace.active_item(cx);
|
||||
let editor_handle = if let Some(editor) = active_item
|
||||
.as_ref()
|
||||
.and_then(|item| item.act_as::<Editor>(cx))
|
||||
{
|
||||
editor
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let (cached_definitions, cached_definitions_kind) = editor_handle.update(cx, |editor, cx| {
|
||||
let definitions = editor.link_go_to_definition_state.definitions.clone();
|
||||
hide_link_definition(editor, cx);
|
||||
(definitions, editor.link_go_to_definition_state.kind)
|
||||
});
|
||||
let cached_definitions = editor.link_go_to_definition_state.definitions.clone();
|
||||
hide_link_definition(editor, cx);
|
||||
let cached_definitions_kind = editor.link_go_to_definition_state.kind;
|
||||
|
||||
let is_correct_kind = cached_definitions_kind == Some(kind);
|
||||
if !cached_definitions.is_empty() && is_correct_kind {
|
||||
editor_handle.update(cx, |editor, cx| {
|
||||
if !editor.focused {
|
||||
cx.focus_self();
|
||||
}
|
||||
});
|
||||
if !editor.focused {
|
||||
cx.focus_self();
|
||||
}
|
||||
|
||||
Editor::navigate_to_definitions(workspace, editor_handle, cached_definitions, cx);
|
||||
editor.navigate_to_definitions(cached_definitions, cx);
|
||||
} else {
|
||||
editor_handle.update(cx, |editor, cx| {
|
||||
editor.select(
|
||||
SelectPhase::Begin {
|
||||
position: point,
|
||||
add: false,
|
||||
click_count: 1,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
editor.select(
|
||||
SelectPhase::Begin {
|
||||
position: point,
|
||||
add: false,
|
||||
click_count: 1,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
match kind {
|
||||
LinkDefinitionKind::Symbol => Editor::go_to_definition(workspace, &GoToDefinition, cx),
|
||||
|
||||
LinkDefinitionKind::Type => {
|
||||
Editor::go_to_type_definition(workspace, &GoToTypeDefinition, cx)
|
||||
}
|
||||
LinkDefinitionKind::Symbol => editor.go_to_definition(&Default::default(), cx),
|
||||
LinkDefinitionKind::Type => editor.go_to_type_definition(&Default::default(), cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,8 +403,8 @@ mod tests {
|
|||
])))
|
||||
});
|
||||
|
||||
cx.update_workspace(|workspace, cx| {
|
||||
go_to_fetched_type_definition(workspace, hover_point, cx);
|
||||
cx.update_editor(|editor, cx| {
|
||||
go_to_fetched_type_definition(editor, hover_point, cx);
|
||||
});
|
||||
requests.next().await;
|
||||
cx.foreground().run_until_parked();
|
||||
|
@ -635,8 +612,8 @@ mod tests {
|
|||
"});
|
||||
|
||||
// Cmd click with existing definition doesn't re-request and dismisses highlight
|
||||
cx.update_workspace(|workspace, cx| {
|
||||
go_to_fetched_definition(workspace, hover_point, cx);
|
||||
cx.update_editor(|editor, cx| {
|
||||
go_to_fetched_definition(editor, hover_point, cx);
|
||||
});
|
||||
// Assert selection moved to to definition
|
||||
cx.lsp
|
||||
|
@ -676,8 +653,8 @@ mod tests {
|
|||
},
|
||||
])))
|
||||
});
|
||||
cx.update_workspace(|workspace, cx| {
|
||||
go_to_fetched_definition(workspace, hover_point, cx);
|
||||
cx.update_editor(|editor, cx| {
|
||||
go_to_fetched_definition(editor, hover_point, cx);
|
||||
});
|
||||
requests.next().await;
|
||||
cx.foreground().run_until_parked();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue