From 767a82527a22e5f7a8c0a541dd063aa12b9d5a2b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 10 Nov 2024 10:03:11 +0200 Subject: [PATCH] Open all kinds of files from multi buffers' headers (#20469) Closes https://github.com/zed-industries/zed/issues/11661 Release Notes: - Fixed multi buffer headers not able to jump to untitled files --- crates/editor/src/editor.rs | 56 +------------ crates/editor/src/element.rs | 147 ++++++++++++++--------------------- 2 files changed, 61 insertions(+), 142 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3851744062e7725be5126b3d58ce4ee8294a6fca..e72117025257d81dd1ac1d092e57daa86e7e3859 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -128,7 +128,7 @@ use project::{ lsp_store::{FormatTarget, FormatTrigger}, project_settings::{GitGutterSetting, ProjectSettings}, CodeAction, Completion, CompletionIntent, DocumentHighlight, InlayHint, Item, Location, - LocationLink, Project, ProjectPath, ProjectTransaction, TaskSourceKind, + LocationLink, Project, ProjectTransaction, TaskSourceKind, }; use rand::prelude::*; use rpc::{proto::*, ErrorExt}; @@ -12651,60 +12651,6 @@ impl Editor { }); } - fn jump( - &mut self, - path: ProjectPath, - position: Point, - anchor: language::Anchor, - offset_from_top: u32, - cx: &mut ViewContext, - ) { - let workspace = self.workspace(); - cx.spawn(|_, mut cx| async move { - let workspace = workspace.ok_or_else(|| anyhow!("cannot jump without workspace"))?; - let editor = workspace.update(&mut cx, |workspace, cx| { - // Reset the preview item id before opening the new item - workspace.active_pane().update(cx, |pane, cx| { - pane.set_preview_item_id(None, cx); - }); - workspace.open_path_preview(path, None, true, true, cx) - })?; - let editor = editor - .await? - .downcast::() - .ok_or_else(|| anyhow!("opened item was not an editor"))? - .downgrade(); - editor.update(&mut cx, |editor, cx| { - let buffer = editor - .buffer() - .read(cx) - .as_singleton() - .ok_or_else(|| anyhow!("cannot jump in a multi-buffer"))?; - let buffer = buffer.read(cx); - let cursor = if buffer.can_resolve(&anchor) { - language::ToPoint::to_point(&anchor, buffer) - } else { - buffer.clip_point(position, Bias::Left) - }; - - let nav_history = editor.nav_history.take(); - editor.change_selections( - Some(Autoscroll::top_relative(offset_from_top as usize)), - cx, - |s| { - s.select_ranges([cursor..cursor]); - }, - ); - editor.nav_history = nav_history; - - anyhow::Ok(()) - })??; - - anyhow::Ok(()) - }) - .detach_and_log_err(cx); - } - fn marked_text_ranges(&self, cx: &AppContext) -> Option>> { let snapshot = self.buffer.read(cx).read(cx); let (_, ranges) = self.text_highlights::(cx)?; diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 07e30104fd50e41a6777b266fa261b86c855a664..594be60eaa21ff21ffee9482664727fedc979ab8 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -27,7 +27,6 @@ use crate::{ use client::ParticipantIndex; use collections::{BTreeMap, HashMap, HashSet}; use git::{blame::BlameEntry, diff::DiffHunkStatus, Oid}; -use gpui::Subscription; use gpui::{ anchored, deferred, div, fill, outline, point, px, quad, relative, size, svg, transparent_black, Action, AnchorCorner, AnyElement, AvailableSpace, Bounds, ClipboardItem, @@ -38,6 +37,7 @@ use gpui::{ StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, TextStyleRefinement, View, ViewContext, WeakView, WindowContext, }; +use gpui::{ClickEvent, Subscription}; use itertools::Itertools; use language::{ language_settings::{ @@ -2058,7 +2058,6 @@ impl EditorElement { block: &Block, available_width: AvailableSpace, block_id: BlockId, - block_row_start: DisplayRow, snapshot: &EditorSnapshot, text_x: Pixels, rows: &Range, @@ -2130,15 +2129,12 @@ impl EditorElement { next_excerpt, show_excerpt_controls, starts_new_buffer, - height, .. } => { #[derive(Clone)] struct JumpData { position: Point, - anchor: text::Anchor, - path: ProjectPath, - line_offset_from_top: u32, + path: Option, } let icon_offset = gutter_dimensions.width @@ -2169,40 +2165,21 @@ impl EditorElement { if let Some(next_excerpt) = next_excerpt { let buffer = &next_excerpt.buffer; let range = &next_excerpt.range; - let jump_data = project::File::from_dyn(buffer.file()).map(|file| { - let jump_path = ProjectPath { - worktree_id: file.worktree_id(cx), - path: file.path.clone(), - }; + let jump_data = { + let jump_path = + project::File::from_dyn(buffer.file()).map(|file| ProjectPath { + worktree_id: file.worktree_id(cx), + path: file.path.clone(), + }); let jump_anchor = range .primary .as_ref() .map_or(range.context.start, |primary| primary.start); - - let excerpt_start = range.context.start; - let jump_position = language::ToPoint::to_point(&jump_anchor, buffer); - let offset_from_excerpt_start = if jump_anchor == excerpt_start { - 0 - } else { - let excerpt_start_row = - language::ToPoint::to_point(&jump_anchor, buffer).row; - jump_position.row - excerpt_start_row - }; - - let line_offset_from_top = - block_row_start.0 + *height + offset_from_excerpt_start - - snapshot - .scroll_anchor - .scroll_position(&snapshot.display_snapshot) - .y as u32; - JumpData { - position: jump_position, - anchor: jump_anchor, + position: language::ToPoint::to_point(&jump_anchor, buffer), path: jump_path, - line_offset_from_top, } - }); + }; if *starts_new_buffer { let include_root = self @@ -2257,31 +2234,22 @@ impl EditorElement { }), ), ) - .when_some(jump_data, |el, jump_data| { - el.child(Icon::new(IconName::ArrowUpRight)) - .cursor_pointer() - .tooltip(|cx| { - Tooltip::for_action( - "Jump to File", - &OpenExcerpts, - cx, - ) - }) - .on_mouse_down(MouseButton::Left, |_, cx| { - cx.stop_propagation() - }) - .on_click(cx.listener_for(&self.editor, { - move |editor, _, cx| { - editor.jump( - jump_data.path.clone(), - jump_data.position, - jump_data.anchor, - jump_data.line_offset_from_top, - cx, - ); - } - })) - }), + .child(Icon::new(IconName::ArrowUpRight)) + .cursor_pointer() + .tooltip(|cx| { + Tooltip::for_action("Jump to File", &OpenExcerpts, cx) + }) + .on_mouse_down(MouseButton::Left, |_, cx| { + cx.stop_propagation() + }) + .on_click(cx.listener_for(&self.editor, { + move |editor, e: &ClickEvent, cx| { + editor.open_excerpts_common( + e.down.modifiers.secondary(), + cx, + ); + } + })), ), ); if *show_excerpt_controls { @@ -2300,6 +2268,7 @@ impl EditorElement { ); } } else { + let editor = self.editor.clone(); result = result.child( h_flex() .id("excerpt header block") @@ -2320,32 +2289,39 @@ impl EditorElement { }), ) .cursor_pointer() - .when_some(jump_data.clone(), |this, jump_data| { - this.on_click(cx.listener_for(&self.editor, { - let path = jump_data.path.clone(); - move |editor, _, cx| { - cx.stop_propagation(); - - editor.jump( - path.clone(), - jump_data.position, - jump_data.anchor, - jump_data.line_offset_from_top, - cx, - ); - } - })) - .tooltip(move |cx| { - Tooltip::for_action( - format!( - "Jump to {}:L{}", - jump_data.path.path.display(), - jump_data.position.row + 1 - ), - &OpenExcerpts, - cx, - ) - }) + .on_click(cx.listener_for(&self.editor, { + move |editor, e: &ClickEvent, cx| { + cx.stop_propagation(); + editor + .open_excerpts_common(e.down.modifiers.secondary(), cx); + } + })) + .tooltip(move |cx| { + let jump_message = format!( + "Jump to {}:L{}", + match &jump_data.path { + Some(project_path) => + project_path.path.display().to_string(), + None => { + let editor = editor.read(cx); + editor + .file_at(jump_data.position, cx) + .map(|file| { + file.full_path(cx).display().to_string() + }) + .or_else(|| { + Some( + editor + .tab_description(0, cx)? + .to_string(), + ) + }) + .unwrap_or_else(|| "Unknown buffer".to_string()) + } + }, + jump_data.position.row + 1 + ); + Tooltip::for_action(jump_message, &OpenExcerpts, cx) }) .child( h_flex() @@ -2480,7 +2456,6 @@ impl EditorElement { block, AvailableSpace::MinContent, block_id, - row, snapshot, text_x, &rows, @@ -2526,7 +2501,6 @@ impl EditorElement { block, width.into(), block_id, - row, snapshot, text_x, &rows, @@ -2573,7 +2547,6 @@ impl EditorElement { &block, width, focused_block.id, - rows.end, snapshot, text_x, &rows,