Open excerpts on alt-enter
Also: Remove special handling for alt-shift-D binding in diagnostics view that opens excerpts. Rely on alt-enter in all multi-buffers instead. Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
dea40c5d1a
commit
721258911c
3 changed files with 88 additions and 62 deletions
|
@ -1,13 +1,11 @@
|
||||||
pub mod items;
|
pub mod items;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::{BTreeSet, HashMap, HashSet};
|
use collections::{BTreeSet, HashSet};
|
||||||
use editor::{
|
use editor::{
|
||||||
diagnostic_block_renderer,
|
diagnostic_block_renderer,
|
||||||
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
|
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
|
||||||
highlight_diagnostic_message,
|
highlight_diagnostic_message, Editor, ExcerptId, MultiBuffer, ToOffset,
|
||||||
items::BufferItemHandle,
|
|
||||||
Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset,
|
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action, elements::*, fonts::TextStyle, keymap::Binding, AnyViewHandle, AppContext, Entity,
|
action, elements::*, fonts::TextStyle, keymap::Binding, AnyViewHandle, AppContext, Entity,
|
||||||
|
@ -31,21 +29,12 @@ use util::TryFutureExt;
|
||||||
use workspace::{ItemHandle, ItemNavHistory, ItemViewHandle as _, Workspace};
|
use workspace::{ItemHandle, ItemNavHistory, ItemViewHandle as _, Workspace};
|
||||||
|
|
||||||
action!(Deploy);
|
action!(Deploy);
|
||||||
action!(OpenExcerpts);
|
|
||||||
|
|
||||||
const CONTEXT_LINE_COUNT: u32 = 1;
|
const CONTEXT_LINE_COUNT: u32 = 1;
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext) {
|
pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_bindings([
|
cx.add_bindings([Binding::new("alt-shift-D", Deploy, Some("Workspace"))]);
|
||||||
Binding::new("alt-shift-D", Deploy, Some("Workspace")),
|
|
||||||
Binding::new(
|
|
||||||
"alt-shift-D",
|
|
||||||
OpenExcerpts,
|
|
||||||
Some("ProjectDiagnosticsEditor"),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
cx.add_action(ProjectDiagnosticsEditor::deploy);
|
cx.add_action(ProjectDiagnosticsEditor::deploy);
|
||||||
cx.add_action(ProjectDiagnosticsEditor::open_excerpts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event = editor::Event;
|
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>) {
|
fn update_excerpts(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let paths = mem::take(&mut self.paths_to_update);
|
let paths = mem::take(&mut self.paths_to_update);
|
||||||
let project = self.model.read(cx).project.clone();
|
let project = self.model.read(cx).project.clone();
|
||||||
|
|
|
@ -132,6 +132,7 @@ action!(ShowCompletions);
|
||||||
action!(ToggleCodeActions, bool);
|
action!(ToggleCodeActions, bool);
|
||||||
action!(ConfirmCompletion, Option<usize>);
|
action!(ConfirmCompletion, Option<usize>);
|
||||||
action!(ConfirmCodeAction, Option<usize>);
|
action!(ConfirmCodeAction, Option<usize>);
|
||||||
|
action!(OpenExcerpts);
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpener>>) {
|
pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpener>>) {
|
||||||
path_openers.push(Box::new(items::BufferOpener));
|
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("alt-cmd-f", FoldSelectedRanges, Some("Editor")),
|
||||||
Binding::new("ctrl-space", ShowCompletions, Some("Editor")),
|
Binding::new("ctrl-space", ShowCompletions, Some("Editor")),
|
||||||
Binding::new("cmd-.", ToggleCodeActions(false), Some("Editor")),
|
Binding::new("cmd-.", ToggleCodeActions(false), Some("Editor")),
|
||||||
|
Binding::new("alt-enter", OpenExcerpts, Some("Editor")),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
cx.add_action(Editor::open_new);
|
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::fold_selected_ranges);
|
||||||
cx.add_action(Editor::show_completions);
|
cx.add_action(Editor::show_completions);
|
||||||
cx.add_action(Editor::toggle_code_actions);
|
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_completion);
|
||||||
cx.add_async_action(Editor::confirm_code_action);
|
cx.add_async_action(Editor::confirm_code_action);
|
||||||
cx.add_async_action(Editor::rename);
|
cx.add_async_action(Editor::rename);
|
||||||
|
@ -4179,14 +4182,14 @@ impl Editor {
|
||||||
target_editor_handle.update(cx, |target_editor, cx| {
|
target_editor_handle.update(cx, |target_editor, cx| {
|
||||||
// When selecting a definition in a different buffer, disable the nav history
|
// When selecting a definition in a different buffer, disable the nav history
|
||||||
// to avoid creating a history entry at the previous cursor location.
|
// to avoid creating a history entry at the previous cursor location.
|
||||||
let disabled_history = if editor_handle == target_editor_handle {
|
let prev_nav_history_len = target_editor
|
||||||
None
|
.nav_history()
|
||||||
} else {
|
.map_or(0, |history| history.len());
|
||||||
target_editor.nav_history.take()
|
|
||||||
};
|
|
||||||
target_editor.select_ranges([range], Some(Autoscroll::Center), cx);
|
target_editor.select_ranges([range], Some(Autoscroll::Center), cx);
|
||||||
if disabled_history.is_some() {
|
if editor_handle != target_editor_handle {
|
||||||
target_editor.nav_history = disabled_history;
|
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 {
|
pub fn searchable(&self) -> bool {
|
||||||
self.searchable
|
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 {
|
impl EditorSnapshot {
|
||||||
|
|
|
@ -649,6 +649,14 @@ impl<T: Toolbar> ToolbarHandle for ViewHandle<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemNavHistory {
|
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 {
|
pub fn new<T: ItemView>(history: Rc<RefCell<NavHistory>>, item_view: &ViewHandle<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
history,
|
history,
|
||||||
|
@ -666,6 +674,14 @@ impl ItemNavHistory {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavHistory {
|
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> {
|
pub fn pop_backward(&mut self) -> Option<NavigationEntry> {
|
||||||
self.backward_stack.pop_back()
|
self.backward_stack.pop_back()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue