@@ -1,13 +1,11 @@
pub mod items;
use anyhow::Result;
-use collections::{BTreeSet, HashMap, HashSet};
+use collections::{BTreeSet, HashSet};
use editor::{
diagnostic_block_renderer,
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
- highlight_diagnostic_message,
- items::BufferItemHandle,
- Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset,
+ highlight_diagnostic_message, Editor, ExcerptId, MultiBuffer, ToOffset,
};
use gpui::{
action, elements::*, fonts::TextStyle, keymap::Binding, AnyViewHandle, AppContext, Entity,
@@ -31,21 +29,12 @@ use util::TryFutureExt;
use workspace::{ItemHandle, ItemNavHistory, ItemViewHandle as _, Workspace};
action!(Deploy);
-action!(OpenExcerpts);
const CONTEXT_LINE_COUNT: u32 = 1;
pub fn init(cx: &mut MutableAppContext) {
- cx.add_bindings([
- Binding::new("alt-shift-D", Deploy, Some("Workspace")),
- Binding::new(
- "alt-shift-D",
- OpenExcerpts,
- Some("ProjectDiagnosticsEditor"),
- ),
- ]);
+ cx.add_bindings([Binding::new("alt-shift-D", Deploy, Some("Workspace"))]);
cx.add_action(ProjectDiagnosticsEditor::deploy);
- cx.add_action(ProjectDiagnosticsEditor::open_excerpts);
}
type Event = editor::Event;
@@ -180,47 +169,6 @@ impl ProjectDiagnosticsEditor {
}
}
- fn open_excerpts(&mut self, _: &OpenExcerpts, cx: &mut ViewContext<Self>) {
- if let Some(workspace) = self.workspace.upgrade(cx) {
- let editor = self.editor.read(cx);
- let excerpts = self.excerpts.read(cx);
- let mut new_selections_by_buffer = HashMap::default();
-
- for selection in editor.local_selections::<usize>(cx) {
- for (buffer, mut range) in
- excerpts.range_to_buffer_ranges(selection.start..selection.end, cx)
- {
- if selection.reversed {
- mem::swap(&mut range.start, &mut range.end);
- }
- new_selections_by_buffer
- .entry(buffer)
- .or_insert(Vec::new())
- .push(range)
- }
- }
-
- // We defer the pane interaction because we ourselves are a workspace item
- // and activating a new item causes the pane to call a method on us reentrantly,
- // which panics if we're on the stack.
- workspace.defer(cx, |workspace, cx| {
- for (buffer, ranges) in new_selections_by_buffer {
- let buffer = BufferItemHandle(buffer);
- if !workspace.activate_pane_for_item(&buffer, cx) {
- workspace.activate_next_pane(cx);
- }
- let editor = workspace
- .open_item(buffer, cx)
- .downcast::<Editor>()
- .unwrap();
- editor.update(cx, |editor, cx| {
- editor.select_ranges(ranges, Some(Autoscroll::Center), cx)
- });
- }
- });
- }
- }
-
fn update_excerpts(&mut self, cx: &mut ViewContext<Self>) {
let paths = mem::take(&mut self.paths_to_update);
let project = self.model.read(cx).project.clone();
@@ -132,6 +132,7 @@ action!(ShowCompletions);
action!(ToggleCodeActions, bool);
action!(ConfirmCompletion, Option<usize>);
action!(ConfirmCodeAction, Option<usize>);
+action!(OpenExcerpts);
pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpener>>) {
path_openers.push(Box::new(items::BufferOpener));
@@ -259,6 +260,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
Binding::new("alt-cmd-f", FoldSelectedRanges, Some("Editor")),
Binding::new("ctrl-space", ShowCompletions, Some("Editor")),
Binding::new("cmd-.", ToggleCodeActions(false), Some("Editor")),
+ Binding::new("alt-enter", OpenExcerpts, Some("Editor")),
]);
cx.add_action(Editor::open_new);
@@ -324,6 +326,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
cx.add_action(Editor::fold_selected_ranges);
cx.add_action(Editor::show_completions);
cx.add_action(Editor::toggle_code_actions);
+ cx.add_action(Editor::open_excerpts);
cx.add_async_action(Editor::confirm_completion);
cx.add_async_action(Editor::confirm_code_action);
cx.add_async_action(Editor::rename);
@@ -4179,14 +4182,14 @@ impl Editor {
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.
- let disabled_history = if editor_handle == target_editor_handle {
- None
- } else {
- target_editor.nav_history.take()
- };
+ let prev_nav_history_len = target_editor
+ .nav_history()
+ .map_or(0, |history| history.len());
target_editor.select_ranges([range], Some(Autoscroll::Center), cx);
- if disabled_history.is_some() {
- target_editor.nav_history = disabled_history;
+ if editor_handle != target_editor_handle {
+ if let Some(history) = target_editor.nav_history() {
+ history.truncate(prev_nav_history_len);
+ }
}
});
}
@@ -5351,6 +5354,65 @@ impl Editor {
pub fn searchable(&self) -> bool {
self.searchable
}
+
+ fn open_excerpts(workspace: &mut Workspace, _: &OpenExcerpts, 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 {
+ cx.propagate_action();
+ return;
+ };
+
+ let editor = editor_handle.read(cx);
+ let buffer = editor.buffer.read(cx);
+ if buffer.is_singleton() {
+ cx.propagate_action();
+ return;
+ }
+
+ let mut new_selections_by_buffer = HashMap::default();
+ for selection in editor.local_selections::<usize>(cx) {
+ for (buffer, mut range) in
+ buffer.range_to_buffer_ranges(selection.start..selection.end, cx)
+ {
+ if selection.reversed {
+ mem::swap(&mut range.start, &mut range.end);
+ }
+ new_selections_by_buffer
+ .entry(buffer)
+ .or_insert(Vec::new())
+ .push(range)
+ }
+ }
+
+ // We defer the pane interaction because we ourselves are a workspace item
+ // and activating a new item causes the pane to call a method on us reentrantly,
+ // which panics if we're on the stack.
+ cx.defer(|workspace, cx| {
+ for (buffer, ranges) in new_selections_by_buffer {
+ let buffer = BufferItemHandle(buffer);
+ if !workspace.activate_pane_for_item(&buffer, cx) {
+ workspace.activate_next_pane(cx);
+ }
+ let editor = workspace
+ .open_item(buffer, cx)
+ .downcast::<Editor>()
+ .unwrap();
+ editor.update(cx, |editor, cx| {
+ let prev_nav_history_len =
+ editor.nav_history().map_or(0, |history| history.len());
+ editor.select_ranges(ranges, Some(Autoscroll::Newest), cx);
+ if let Some(history) = editor.nav_history() {
+ history.truncate(prev_nav_history_len);
+ }
+ });
+ }
+ });
+ }
}
impl EditorSnapshot {
@@ -649,6 +649,14 @@ impl<T: Toolbar> ToolbarHandle for ViewHandle<T> {
}
impl ItemNavHistory {
+ pub fn len(&self) -> usize {
+ self.history.borrow().len()
+ }
+
+ pub fn truncate(&self, len: usize) {
+ self.history.borrow_mut().truncate(len)
+ }
+
pub fn new<T: ItemView>(history: Rc<RefCell<NavHistory>>, item_view: &ViewHandle<T>) -> Self {
Self {
history,
@@ -666,6 +674,14 @@ impl ItemNavHistory {
}
impl NavHistory {
+ pub fn len(&self) -> usize {
+ self.backward_stack.len()
+ }
+
+ pub fn truncate(&mut self, len: usize) {
+ self.backward_stack.truncate(len);
+ }
+
pub fn pop_backward(&mut self) -> Option<NavigationEntry> {
self.backward_stack.pop_back()
}