mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Editor docs (#4097)
Release Notes: - N/A --------- Co-authored-by: Kirill <kirill@zed.dev>
This commit is contained in:
parent
647b08b101
commit
6cbc49e5f0
@ -19,12 +19,13 @@ use chrono::{DateTime, Local};
|
|||||||
use client::telemetry::AssistantKind;
|
use client::telemetry::AssistantKind;
|
||||||
use collections::{hash_map, HashMap, HashSet, VecDeque};
|
use collections::{hash_map, HashMap, HashSet, VecDeque};
|
||||||
use editor::{
|
use editor::{
|
||||||
|
actions::{MoveDown, MoveUp},
|
||||||
display_map::{
|
display_map::{
|
||||||
BlockContext, BlockDisposition, BlockId, BlockProperties, BlockStyle, ToDisplayPoint,
|
BlockContext, BlockDisposition, BlockId, BlockProperties, BlockStyle, ToDisplayPoint,
|
||||||
},
|
},
|
||||||
scroll::autoscroll::{Autoscroll, AutoscrollStrategy},
|
scroll::{Autoscroll, AutoscrollStrategy},
|
||||||
Anchor, Editor, EditorElement, EditorEvent, EditorStyle, MoveDown, MoveUp, MultiBufferSnapshot,
|
Anchor, Editor, EditorElement, EditorEvent, EditorStyle, MultiBufferSnapshot, ToOffset,
|
||||||
ToOffset, ToPoint,
|
ToPoint,
|
||||||
};
|
};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
@ -479,7 +480,7 @@ impl AssistantPanel {
|
|||||||
|
|
||||||
fn cancel_last_inline_assist(
|
fn cancel_last_inline_assist(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
_: &editor::Cancel,
|
_: &editor::actions::Cancel,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
) {
|
) {
|
||||||
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
|
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
|
||||||
@ -891,7 +892,7 @@ impl AssistantPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_editor_cancel(&mut self, _: &editor::Cancel, cx: &mut ViewContext<Self>) {
|
fn handle_editor_cancel(&mut self, _: &editor::actions::Cancel, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(search_bar) = self.toolbar.read(cx).item_of_type::<BufferSearchBar>() {
|
if let Some(search_bar) = self.toolbar.read(cx).item_of_type::<BufferSearchBar>() {
|
||||||
if !search_bar.read(cx).is_dismissed() {
|
if !search_bar.read(cx).is_dismissed() {
|
||||||
search_bar.update(cx, |search_bar, cx| {
|
search_bar.update(cx, |search_bar, cx| {
|
||||||
@ -2158,7 +2159,7 @@ impl ConversationEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cancel_last_assist(&mut self, _: &editor::Cancel, cx: &mut ViewContext<Self>) {
|
fn cancel_last_assist(&mut self, _: &editor::actions::Cancel, cx: &mut ViewContext<Self>) {
|
||||||
if !self
|
if !self
|
||||||
.conversation
|
.conversation
|
||||||
.update(cx, |conversation, _| conversation.cancel_last_assist())
|
.update(cx, |conversation, _| conversation.cancel_last_assist())
|
||||||
@ -2417,7 +2418,7 @@ impl ConversationEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy(&mut self, _: &editor::Copy, cx: &mut ViewContext<Self>) {
|
fn copy(&mut self, _: &editor::actions::Copy, cx: &mut ViewContext<Self>) {
|
||||||
let editor = self.editor.read(cx);
|
let editor = self.editor.read(cx);
|
||||||
let conversation = self.conversation.read(cx);
|
let conversation = self.conversation.read(cx);
|
||||||
if editor.selections.count() == 1 {
|
if editor.selections.count() == 1 {
|
||||||
@ -2828,7 +2829,7 @@ impl InlineAssistant {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cancel(&mut self, _: &editor::Cancel, cx: &mut ViewContext<Self>) {
|
fn cancel(&mut self, _: &editor::actions::Cancel, cx: &mut ViewContext<Self>) {
|
||||||
cx.emit(InlineAssistantEvent::Canceled);
|
cx.emit(InlineAssistantEvent::Canceled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,11 @@ use std::{
|
|||||||
|
|
||||||
use call::ActiveCall;
|
use call::ActiveCall;
|
||||||
use editor::{
|
use editor::{
|
||||||
|
actions::{
|
||||||
|
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Redo, Rename, ToggleCodeActions, Undo,
|
||||||
|
},
|
||||||
test::editor_test_context::{AssertionContextManager, EditorTestContext},
|
test::editor_test_context::{AssertionContextManager, EditorTestContext},
|
||||||
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Redo, Rename, ToggleCodeActions,
|
Editor,
|
||||||
Undo,
|
|
||||||
};
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{TestAppContext, VisualContext, VisualTestContext};
|
use gpui::{TestAppContext, VisualContext, VisualTestContext};
|
||||||
@ -217,7 +219,8 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
|
|||||||
editor_cx_b.set_selections_state(indoc! {"
|
editor_cx_b.set_selections_state(indoc! {"
|
||||||
Some textˇ
|
Some textˇ
|
||||||
"});
|
"});
|
||||||
editor_cx_a.update_editor(|editor, cx| editor.newline_above(&editor::NewlineAbove, cx));
|
editor_cx_a
|
||||||
|
.update_editor(|editor, cx| editor.newline_above(&editor::actions::NewlineAbove, cx));
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
editor_cx_a.assert_editor_state(indoc! {"
|
editor_cx_a.assert_editor_state(indoc! {"
|
||||||
ˇ
|
ˇ
|
||||||
@ -237,7 +240,8 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
|
|||||||
|
|
||||||
Some textˇ
|
Some textˇ
|
||||||
"});
|
"});
|
||||||
editor_cx_a.update_editor(|editor, cx| editor.newline_below(&editor::NewlineBelow, cx));
|
editor_cx_a
|
||||||
|
.update_editor(|editor, cx| editor.newline_below(&editor::actions::NewlineBelow, cx));
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
editor_cx_a.assert_editor_state(indoc! {"
|
editor_cx_a.assert_editor_state(indoc! {"
|
||||||
|
|
||||||
|
@ -1229,7 +1229,9 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
|
|||||||
});
|
});
|
||||||
|
|
||||||
// When client B moves, it automatically stops following client A.
|
// When client B moves, it automatically stops following client A.
|
||||||
editor_b2.update(cx_b, |editor, cx| editor.move_right(&editor::MoveRight, cx));
|
editor_b2.update(cx_b, |editor, cx| {
|
||||||
|
editor.move_right(&editor::actions::MoveRight, cx)
|
||||||
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
|
||||||
None
|
None
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::sign_in::CopilotCodeVerification;
|
use crate::sign_in::CopilotCodeVerification;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use copilot::{Copilot, SignOut, Status};
|
use copilot::{Copilot, SignOut, Status};
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
use editor::{scroll::Autoscroll, Editor};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, Action, AnchorCorner, AppContext, AsyncWindowContext, Entity, IntoElement, ParentElement,
|
div, Action, AnchorCorner, AppContext, AsyncWindowContext, Entity, IntoElement, ParentElement,
|
||||||
|
@ -8,7 +8,7 @@ use editor::{
|
|||||||
diagnostic_block_renderer,
|
diagnostic_block_renderer,
|
||||||
display_map::{BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock},
|
display_map::{BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock},
|
||||||
highlight_diagnostic_message,
|
highlight_diagnostic_message,
|
||||||
scroll::autoscroll::Autoscroll,
|
scroll::Autoscroll,
|
||||||
Editor, EditorEvent, ExcerptId, ExcerptRange, MultiBuffer, ToOffset,
|
Editor, EditorEvent, ExcerptId, ExcerptRange, MultiBuffer, ToOffset,
|
||||||
};
|
};
|
||||||
use futures::future::try_join_all;
|
use futures::future::try_join_all;
|
||||||
|
@ -80,7 +80,7 @@ impl Render for DiagnosticIndicator {
|
|||||||
Button::new("diagnostic_message", message)
|
Button::new("diagnostic_message", message)
|
||||||
.label_size(LabelSize::Small)
|
.label_size(LabelSize::Small)
|
||||||
.tooltip(|cx| {
|
.tooltip(|cx| {
|
||||||
Tooltip::for_action("Next Diagnostic", &editor::GoToDiagnostic, cx)
|
Tooltip::for_action("Next Diagnostic", &editor::actions::GoToDiagnostic, cx)
|
||||||
})
|
})
|
||||||
.on_click(cx.listener(|this, _, cx| {
|
.on_click(cx.listener(|this, _, cx| {
|
||||||
this.go_to_next_diagnostic(cx);
|
this.go_to_next_diagnostic(cx);
|
||||||
|
218
crates/editor/src/actions.rs
Normal file
218
crates/editor/src/actions.rs
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
//! This module contains all actions supported by [`Editor`].
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct SelectNext {
|
||||||
|
#[serde(default)]
|
||||||
|
pub replace_newest: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct SelectPrevious {
|
||||||
|
#[serde(default)]
|
||||||
|
pub replace_newest: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct SelectAllMatches {
|
||||||
|
#[serde(default)]
|
||||||
|
pub replace_newest: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct SelectToBeginningOfLine {
|
||||||
|
#[serde(default)]
|
||||||
|
pub(super) stop_at_soft_wraps: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct MovePageUp {
|
||||||
|
#[serde(default)]
|
||||||
|
pub(super) center_cursor: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct MovePageDown {
|
||||||
|
#[serde(default)]
|
||||||
|
pub(super) center_cursor: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct SelectToEndOfLine {
|
||||||
|
#[serde(default)]
|
||||||
|
pub(super) stop_at_soft_wraps: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct ToggleCodeActions {
|
||||||
|
#[serde(default)]
|
||||||
|
pub deployed_from_indicator: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct ConfirmCompletion {
|
||||||
|
#[serde(default)]
|
||||||
|
pub item_ix: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct ConfirmCodeAction {
|
||||||
|
#[serde(default)]
|
||||||
|
pub item_ix: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct ToggleComments {
|
||||||
|
#[serde(default)]
|
||||||
|
pub advance_downwards: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct FoldAt {
|
||||||
|
pub buffer_row: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Deserialize, Default)]
|
||||||
|
pub struct UnfoldAt {
|
||||||
|
pub buffer_row: u32,
|
||||||
|
}
|
||||||
|
impl_actions!(
|
||||||
|
editor,
|
||||||
|
[
|
||||||
|
SelectNext,
|
||||||
|
SelectPrevious,
|
||||||
|
SelectAllMatches,
|
||||||
|
SelectToBeginningOfLine,
|
||||||
|
MovePageUp,
|
||||||
|
MovePageDown,
|
||||||
|
SelectToEndOfLine,
|
||||||
|
ToggleCodeActions,
|
||||||
|
ConfirmCompletion,
|
||||||
|
ConfirmCodeAction,
|
||||||
|
ToggleComments,
|
||||||
|
FoldAt,
|
||||||
|
UnfoldAt
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
gpui::actions!(
|
||||||
|
editor,
|
||||||
|
[
|
||||||
|
AddSelectionAbove,
|
||||||
|
AddSelectionBelow,
|
||||||
|
Backspace,
|
||||||
|
Cancel,
|
||||||
|
ConfirmRename,
|
||||||
|
ContextMenuFirst,
|
||||||
|
ContextMenuLast,
|
||||||
|
ContextMenuNext,
|
||||||
|
ContextMenuPrev,
|
||||||
|
ConvertToKebabCase,
|
||||||
|
ConvertToLowerCamelCase,
|
||||||
|
ConvertToLowerCase,
|
||||||
|
ConvertToSnakeCase,
|
||||||
|
ConvertToTitleCase,
|
||||||
|
ConvertToUpperCamelCase,
|
||||||
|
ConvertToUpperCase,
|
||||||
|
Copy,
|
||||||
|
CopyHighlightJson,
|
||||||
|
CopyPath,
|
||||||
|
CopyRelativePath,
|
||||||
|
Cut,
|
||||||
|
CutToEndOfLine,
|
||||||
|
Delete,
|
||||||
|
DeleteLine,
|
||||||
|
DeleteToBeginningOfLine,
|
||||||
|
DeleteToEndOfLine,
|
||||||
|
DeleteToNextSubwordEnd,
|
||||||
|
DeleteToNextWordEnd,
|
||||||
|
DeleteToPreviousSubwordStart,
|
||||||
|
DeleteToPreviousWordStart,
|
||||||
|
DuplicateLine,
|
||||||
|
ExpandMacroRecursively,
|
||||||
|
FindAllReferences,
|
||||||
|
Fold,
|
||||||
|
FoldSelectedRanges,
|
||||||
|
Format,
|
||||||
|
GoToDefinition,
|
||||||
|
GoToDefinitionSplit,
|
||||||
|
GoToDiagnostic,
|
||||||
|
GoToHunk,
|
||||||
|
GoToPrevDiagnostic,
|
||||||
|
GoToPrevHunk,
|
||||||
|
GoToTypeDefinition,
|
||||||
|
GoToTypeDefinitionSplit,
|
||||||
|
HalfPageDown,
|
||||||
|
HalfPageUp,
|
||||||
|
Hover,
|
||||||
|
Indent,
|
||||||
|
JoinLines,
|
||||||
|
LineDown,
|
||||||
|
LineUp,
|
||||||
|
MoveDown,
|
||||||
|
MoveLeft,
|
||||||
|
MoveLineDown,
|
||||||
|
MoveLineUp,
|
||||||
|
MoveRight,
|
||||||
|
MoveToBeginning,
|
||||||
|
MoveToBeginningOfLine,
|
||||||
|
MoveToEnclosingBracket,
|
||||||
|
MoveToEnd,
|
||||||
|
MoveToEndOfLine,
|
||||||
|
MoveToEndOfParagraph,
|
||||||
|
MoveToNextSubwordEnd,
|
||||||
|
MoveToNextWordEnd,
|
||||||
|
MoveToPreviousSubwordStart,
|
||||||
|
MoveToPreviousWordStart,
|
||||||
|
MoveToStartOfParagraph,
|
||||||
|
MoveUp,
|
||||||
|
Newline,
|
||||||
|
NewlineAbove,
|
||||||
|
NewlineBelow,
|
||||||
|
NextScreen,
|
||||||
|
OpenExcerpts,
|
||||||
|
Outdent,
|
||||||
|
PageDown,
|
||||||
|
PageUp,
|
||||||
|
Paste,
|
||||||
|
Redo,
|
||||||
|
RedoSelection,
|
||||||
|
Rename,
|
||||||
|
RestartLanguageServer,
|
||||||
|
RevealInFinder,
|
||||||
|
ReverseLines,
|
||||||
|
ScrollCursorBottom,
|
||||||
|
ScrollCursorCenter,
|
||||||
|
ScrollCursorTop,
|
||||||
|
SelectAll,
|
||||||
|
SelectDown,
|
||||||
|
SelectLargerSyntaxNode,
|
||||||
|
SelectLeft,
|
||||||
|
SelectLine,
|
||||||
|
SelectRight,
|
||||||
|
SelectSmallerSyntaxNode,
|
||||||
|
SelectToBeginning,
|
||||||
|
SelectToEnd,
|
||||||
|
SelectToEndOfParagraph,
|
||||||
|
SelectToNextSubwordEnd,
|
||||||
|
SelectToNextWordEnd,
|
||||||
|
SelectToPreviousSubwordStart,
|
||||||
|
SelectToPreviousWordStart,
|
||||||
|
SelectToStartOfParagraph,
|
||||||
|
SelectUp,
|
||||||
|
ShowCharacterPalette,
|
||||||
|
ShowCompletions,
|
||||||
|
ShuffleLines,
|
||||||
|
SortLinesCaseInsensitive,
|
||||||
|
SortLinesCaseSensitive,
|
||||||
|
SplitSelectionIntoLines,
|
||||||
|
Tab,
|
||||||
|
TabPrev,
|
||||||
|
ToggleInlayHints,
|
||||||
|
ToggleSoftWrap,
|
||||||
|
Transpose,
|
||||||
|
Undo,
|
||||||
|
UndoSelection,
|
||||||
|
UnfoldLines,
|
||||||
|
]
|
||||||
|
);
|
@ -30,7 +30,8 @@ pub use block_map::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub use self::fold_map::{Fold, FoldPoint};
|
pub use self::fold_map::{Fold, FoldPoint};
|
||||||
pub use self::inlay_map::{Inlay, InlayOffset, InlayPoint};
|
pub use self::inlay_map::{InlayOffset, InlayPoint};
|
||||||
|
pub(crate) use inlay_map::Inlay;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum FoldStatus {
|
pub enum FoldStatus {
|
||||||
@ -220,7 +221,7 @@ impl DisplayMap {
|
|||||||
.insert(Some(type_id), Arc::new((style, ranges)));
|
.insert(Some(type_id), Arc::new((style, ranges)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn highlight_inlays(
|
pub(crate) fn highlight_inlays(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
highlights: Vec<InlayHighlight>,
|
highlights: Vec<InlayHighlight>,
|
||||||
@ -258,11 +259,11 @@ impl DisplayMap {
|
|||||||
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_inlays(&self) -> impl Iterator<Item = &Inlay> {
|
pub(crate) fn current_inlays(&self) -> impl Iterator<Item = &Inlay> {
|
||||||
self.inlay_map.current_inlays()
|
self.inlay_map.current_inlays()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn splice_inlays(
|
pub(crate) fn splice_inlays(
|
||||||
&mut self,
|
&mut self,
|
||||||
to_remove: Vec<InlayId>,
|
to_remove: Vec<InlayId>,
|
||||||
to_insert: Vec<Inlay>,
|
to_insert: Vec<Inlay>,
|
||||||
@ -306,7 +307,7 @@ impl DisplayMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Highlights<'a> {
|
pub(crate) struct Highlights<'a> {
|
||||||
pub text_highlights: Option<&'a TextHighlights>,
|
pub text_highlights: Option<&'a TextHighlights>,
|
||||||
pub inlay_highlights: Option<&'a InlayHighlights>,
|
pub inlay_highlights: Option<&'a InlayHighlights>,
|
||||||
pub inlay_highlight_style: Option<HighlightStyle>,
|
pub inlay_highlight_style: Option<HighlightStyle>,
|
||||||
@ -880,8 +881,9 @@ impl DisplaySnapshot {
|
|||||||
self.text_highlights.get(&Some(type_id)).cloned()
|
self.text_highlights.get(&Some(type_id)).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub fn inlay_highlights<Tag: ?Sized + 'static>(
|
pub(crate) fn inlay_highlights<Tag: ?Sized + 'static>(
|
||||||
&self,
|
&self,
|
||||||
) -> Option<&HashMap<InlayId, (HighlightStyle, InlayHighlight)>> {
|
) -> Option<&HashMap<InlayId, (HighlightStyle, InlayHighlight)>> {
|
||||||
let type_id = TypeId::of::<Tag>();
|
let type_id = TypeId::of::<Tag>();
|
||||||
|
@ -582,7 +582,7 @@ impl BlockSnapshot {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks<'a>(
|
pub(crate) fn chunks<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
rows: Range<u32>,
|
rows: Range<u32>,
|
||||||
language_aware: bool,
|
language_aware: bool,
|
||||||
|
@ -655,7 +655,7 @@ impl FoldSnapshot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks<'a>(
|
pub(crate) fn chunks<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range<FoldOffset>,
|
range: Range<FoldOffset>,
|
||||||
language_aware: bool,
|
language_aware: bool,
|
||||||
|
@ -35,8 +35,8 @@ enum Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Inlay {
|
pub(crate) struct Inlay {
|
||||||
pub id: InlayId,
|
pub(crate) id: InlayId,
|
||||||
pub position: Anchor,
|
pub position: Anchor,
|
||||||
pub text: text::Rope,
|
pub text: text::Rope,
|
||||||
}
|
}
|
||||||
@ -1016,7 +1016,7 @@ impl InlaySnapshot {
|
|||||||
(line_end - line_start) as u32
|
(line_end - line_start) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks<'a>(
|
pub(crate) fn chunks<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range<InlayOffset>,
|
range: Range<InlayOffset>,
|
||||||
language_aware: bool,
|
language_aware: bool,
|
||||||
|
@ -568,7 +568,7 @@ impl WrapSnapshot {
|
|||||||
Patch::new(wrap_edits)
|
Patch::new(wrap_edits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks<'a>(
|
pub(crate) fn chunks<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
rows: Range<u32>,
|
rows: Range<u32>,
|
||||||
language_aware: bool,
|
language_aware: bool,
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
#![allow(rustdoc::private_intra_doc_links)]
|
||||||
|
//! This is the place where everything editor-related is stored (data-wise) and displayed (ui-wise).
|
||||||
|
//! The main point of interest in this crate is [`Editor`] type, which is used in every other Zed part as a user input element.
|
||||||
|
//! It comes in different flavors: single line, multiline and a fixed height one.
|
||||||
|
//!
|
||||||
|
//! Editor contains of multiple large submodules:
|
||||||
|
//! * [`element`] — the place where all rendering happens
|
||||||
|
//! * [`display_map`] - chunks up text in the editor into the logical blocks, establishes coordinates and mapping between each of them.
|
||||||
|
//! Contains all metadata related to text transformations (folds, fake inlay text insertions, soft wraps, tab markup, etc.).
|
||||||
|
//! * [`inlay_hint_cache`] - is a storage of inlay hints out of LSP requests, responsible for querying LSP and updating `display_map`'s state accordingly.
|
||||||
|
//!
|
||||||
|
//! All other submodules and structs are mostly concerned with holding editor data about the way it displays current buffer region(s).
|
||||||
|
//!
|
||||||
|
//! If you're looking to improve Vim mode, you should check out Vim crate that wraps Editor and overrides it's behaviour.
|
||||||
|
pub mod actions;
|
||||||
mod blink_manager;
|
mod blink_manager;
|
||||||
pub mod display_map;
|
pub mod display_map;
|
||||||
mod editor_settings;
|
mod editor_settings;
|
||||||
@ -14,13 +29,14 @@ pub mod movement;
|
|||||||
mod persistence;
|
mod persistence;
|
||||||
mod rust_analyzer_ext;
|
mod rust_analyzer_ext;
|
||||||
pub mod scroll;
|
pub mod scroll;
|
||||||
pub mod selections_collection;
|
mod selections_collection;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod editor_tests;
|
mod editor_tests;
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub mod test;
|
pub mod test;
|
||||||
use ::git::diff::DiffHunk;
|
use ::git::diff::DiffHunk;
|
||||||
|
pub(crate) use actions::*;
|
||||||
use aho_corasick::AhoCorasick;
|
use aho_corasick::AhoCorasick;
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use blink_manager::BlinkManager;
|
use blink_manager::BlinkManager;
|
||||||
@ -32,14 +48,13 @@ use copilot::Copilot;
|
|||||||
pub use display_map::DisplayPoint;
|
pub use display_map::DisplayPoint;
|
||||||
use display_map::*;
|
use display_map::*;
|
||||||
pub use editor_settings::EditorSettings;
|
pub use editor_settings::EditorSettings;
|
||||||
pub use element::{
|
use element::LineWithInvisibles;
|
||||||
Cursor, EditorElement, HighlightedRange, HighlightedRangeLine, LineWithInvisibles,
|
pub use element::{Cursor, EditorElement, HighlightedRange, HighlightedRangeLine};
|
||||||
};
|
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use git::diff_hunk_to_display;
|
use git::diff_hunk_to_display;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action,
|
div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action,
|
||||||
AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context,
|
AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context,
|
||||||
DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight,
|
DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight,
|
||||||
HighlightStyle, Hsla, InputHandler, InteractiveText, KeyContext, Model, MouseButton,
|
HighlightStyle, Hsla, InputHandler, InteractiveText, KeyContext, Model, MouseButton,
|
||||||
@ -51,7 +66,7 @@ use hover_popover::{hide_hover, HoverState};
|
|||||||
use inlay_hint_cache::{InlayHintCache, InlaySplice, InvalidationStrategy};
|
use inlay_hint_cache::{InlayHintCache, InlaySplice, InvalidationStrategy};
|
||||||
pub use items::MAX_TAB_TITLE_LEN;
|
pub use items::MAX_TAB_TITLE_LEN;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
pub use language::{char_kind, CharKind};
|
use language::{char_kind, CharKind};
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{self, all_language_settings, InlayHintSettings},
|
language_settings::{self, all_language_settings, InlayHintSettings},
|
||||||
markdown, point_from_lsp, AutoindentMode, BracketPair, Buffer, Capability, CodeAction,
|
markdown, point_from_lsp, AutoindentMode, BracketPair, Buffer, Capability, CodeAction,
|
||||||
@ -74,9 +89,7 @@ use parking_lot::RwLock;
|
|||||||
use project::{FormatTrigger, Location, Project, ProjectPath, ProjectTransaction};
|
use project::{FormatTrigger, Location, Project, ProjectPath, ProjectTransaction};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use rpc::proto::{self, *};
|
use rpc::proto::{self, *};
|
||||||
use scroll::{
|
use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide};
|
||||||
autoscroll::Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide,
|
|
||||||
};
|
|
||||||
use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
|
use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::{Settings, SettingsStore};
|
use settings::{Settings, SettingsStore};
|
||||||
@ -113,10 +126,12 @@ const MAX_LINE_LEN: usize = 1024;
|
|||||||
const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
|
const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
|
||||||
const MAX_SELECTION_HISTORY_LEN: usize = 1024;
|
const MAX_SELECTION_HISTORY_LEN: usize = 1024;
|
||||||
const COPILOT_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75);
|
const COPILOT_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75);
|
||||||
|
#[doc(hidden)]
|
||||||
pub const CODE_ACTIONS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(250);
|
pub const CODE_ACTIONS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(250);
|
||||||
|
#[doc(hidden)]
|
||||||
pub const DOCUMENT_HIGHLIGHTS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75);
|
pub const DOCUMENT_HIGHLIGHTS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75);
|
||||||
|
|
||||||
pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
||||||
|
|
||||||
pub fn render_parsed_markdown(
|
pub fn render_parsed_markdown(
|
||||||
element_id: impl Into<ElementId>,
|
element_id: impl Into<ElementId>,
|
||||||
@ -181,103 +196,8 @@ pub fn render_parsed_markdown(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct SelectNext {
|
|
||||||
#[serde(default)]
|
|
||||||
pub replace_newest: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct SelectPrevious {
|
|
||||||
#[serde(default)]
|
|
||||||
pub replace_newest: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct SelectAllMatches {
|
|
||||||
#[serde(default)]
|
|
||||||
pub replace_newest: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct SelectToBeginningOfLine {
|
|
||||||
#[serde(default)]
|
|
||||||
stop_at_soft_wraps: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct MovePageUp {
|
|
||||||
#[serde(default)]
|
|
||||||
center_cursor: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct MovePageDown {
|
|
||||||
#[serde(default)]
|
|
||||||
center_cursor: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct SelectToEndOfLine {
|
|
||||||
#[serde(default)]
|
|
||||||
stop_at_soft_wraps: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct ToggleCodeActions {
|
|
||||||
#[serde(default)]
|
|
||||||
pub deployed_from_indicator: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct ConfirmCompletion {
|
|
||||||
#[serde(default)]
|
|
||||||
pub item_ix: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct ConfirmCodeAction {
|
|
||||||
#[serde(default)]
|
|
||||||
pub item_ix: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct ToggleComments {
|
|
||||||
#[serde(default)]
|
|
||||||
pub advance_downwards: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct FoldAt {
|
|
||||||
pub buffer_row: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Deserialize, Default)]
|
|
||||||
pub struct UnfoldAt {
|
|
||||||
pub buffer_row: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_actions!(
|
|
||||||
editor,
|
|
||||||
[
|
|
||||||
SelectNext,
|
|
||||||
SelectPrevious,
|
|
||||||
SelectAllMatches,
|
|
||||||
SelectToBeginningOfLine,
|
|
||||||
MovePageUp,
|
|
||||||
MovePageDown,
|
|
||||||
SelectToEndOfLine,
|
|
||||||
ToggleCodeActions,
|
|
||||||
ConfirmCompletion,
|
|
||||||
ConfirmCodeAction,
|
|
||||||
ToggleComments,
|
|
||||||
FoldAt,
|
|
||||||
UnfoldAt
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum InlayId {
|
pub(crate) enum InlayId {
|
||||||
Suggestion(usize),
|
Suggestion(usize),
|
||||||
Hint(usize),
|
Hint(usize),
|
||||||
}
|
}
|
||||||
@ -291,128 +211,6 @@ impl InlayId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actions!(
|
|
||||||
editor,
|
|
||||||
[
|
|
||||||
AddSelectionAbove,
|
|
||||||
AddSelectionBelow,
|
|
||||||
Backspace,
|
|
||||||
Cancel,
|
|
||||||
ConfirmRename,
|
|
||||||
ContextMenuFirst,
|
|
||||||
ContextMenuLast,
|
|
||||||
ContextMenuNext,
|
|
||||||
ContextMenuPrev,
|
|
||||||
ConvertToKebabCase,
|
|
||||||
ConvertToLowerCamelCase,
|
|
||||||
ConvertToLowerCase,
|
|
||||||
ConvertToSnakeCase,
|
|
||||||
ConvertToTitleCase,
|
|
||||||
ConvertToUpperCamelCase,
|
|
||||||
ConvertToUpperCase,
|
|
||||||
Copy,
|
|
||||||
CopyHighlightJson,
|
|
||||||
CopyPath,
|
|
||||||
CopyRelativePath,
|
|
||||||
Cut,
|
|
||||||
CutToEndOfLine,
|
|
||||||
Delete,
|
|
||||||
DeleteLine,
|
|
||||||
DeleteToBeginningOfLine,
|
|
||||||
DeleteToEndOfLine,
|
|
||||||
DeleteToNextSubwordEnd,
|
|
||||||
DeleteToNextWordEnd,
|
|
||||||
DeleteToPreviousSubwordStart,
|
|
||||||
DeleteToPreviousWordStart,
|
|
||||||
DuplicateLine,
|
|
||||||
ExpandMacroRecursively,
|
|
||||||
FindAllReferences,
|
|
||||||
Fold,
|
|
||||||
FoldSelectedRanges,
|
|
||||||
Format,
|
|
||||||
GoToDefinition,
|
|
||||||
GoToDefinitionSplit,
|
|
||||||
GoToDiagnostic,
|
|
||||||
GoToHunk,
|
|
||||||
GoToPrevDiagnostic,
|
|
||||||
GoToPrevHunk,
|
|
||||||
GoToTypeDefinition,
|
|
||||||
GoToTypeDefinitionSplit,
|
|
||||||
HalfPageDown,
|
|
||||||
HalfPageUp,
|
|
||||||
Hover,
|
|
||||||
Indent,
|
|
||||||
JoinLines,
|
|
||||||
LineDown,
|
|
||||||
LineUp,
|
|
||||||
MoveDown,
|
|
||||||
MoveLeft,
|
|
||||||
MoveLineDown,
|
|
||||||
MoveLineUp,
|
|
||||||
MoveRight,
|
|
||||||
MoveToBeginning,
|
|
||||||
MoveToBeginningOfLine,
|
|
||||||
MoveToEnclosingBracket,
|
|
||||||
MoveToEnd,
|
|
||||||
MoveToEndOfLine,
|
|
||||||
MoveToEndOfParagraph,
|
|
||||||
MoveToNextSubwordEnd,
|
|
||||||
MoveToNextWordEnd,
|
|
||||||
MoveToPreviousSubwordStart,
|
|
||||||
MoveToPreviousWordStart,
|
|
||||||
MoveToStartOfParagraph,
|
|
||||||
MoveUp,
|
|
||||||
Newline,
|
|
||||||
NewlineAbove,
|
|
||||||
NewlineBelow,
|
|
||||||
NextScreen,
|
|
||||||
OpenExcerpts,
|
|
||||||
Outdent,
|
|
||||||
PageDown,
|
|
||||||
PageUp,
|
|
||||||
Paste,
|
|
||||||
Redo,
|
|
||||||
RedoSelection,
|
|
||||||
Rename,
|
|
||||||
RestartLanguageServer,
|
|
||||||
RevealInFinder,
|
|
||||||
ReverseLines,
|
|
||||||
ScrollCursorBottom,
|
|
||||||
ScrollCursorCenter,
|
|
||||||
ScrollCursorTop,
|
|
||||||
SelectAll,
|
|
||||||
SelectDown,
|
|
||||||
SelectLargerSyntaxNode,
|
|
||||||
SelectLeft,
|
|
||||||
SelectLine,
|
|
||||||
SelectRight,
|
|
||||||
SelectSmallerSyntaxNode,
|
|
||||||
SelectToBeginning,
|
|
||||||
SelectToEnd,
|
|
||||||
SelectToEndOfParagraph,
|
|
||||||
SelectToNextSubwordEnd,
|
|
||||||
SelectToNextWordEnd,
|
|
||||||
SelectToPreviousSubwordStart,
|
|
||||||
SelectToPreviousWordStart,
|
|
||||||
SelectToStartOfParagraph,
|
|
||||||
SelectUp,
|
|
||||||
ShowCharacterPalette,
|
|
||||||
ShowCompletions,
|
|
||||||
ShuffleLines,
|
|
||||||
SortLinesCaseInsensitive,
|
|
||||||
SortLinesCaseSensitive,
|
|
||||||
SplitSelectionIntoLines,
|
|
||||||
Tab,
|
|
||||||
TabPrev,
|
|
||||||
ToggleInlayHints,
|
|
||||||
ToggleSoftWrap,
|
|
||||||
Transpose,
|
|
||||||
Undo,
|
|
||||||
UndoSelection,
|
|
||||||
UnfoldLines,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
enum DocumentHighlightRead {}
|
enum DocumentHighlightRead {}
|
||||||
enum DocumentHighlightWrite {}
|
enum DocumentHighlightWrite {}
|
||||||
enum InputComposition {}
|
enum InputComposition {}
|
||||||
@ -489,7 +287,7 @@ pub enum SelectPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum SelectMode {
|
pub(crate) enum SelectMode {
|
||||||
Character,
|
Character,
|
||||||
Word(Range<Anchor>),
|
Word(Range<Anchor>),
|
||||||
Line(Range<Anchor>),
|
Line(Range<Anchor>),
|
||||||
@ -760,6 +558,7 @@ struct SnippetState {
|
|||||||
active_index: usize,
|
active_index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
pub struct RenameState {
|
pub struct RenameState {
|
||||||
pub range: Range<Anchor>,
|
pub range: Range<Anchor>,
|
||||||
pub old_name: Arc<str>,
|
pub old_name: Arc<str>,
|
||||||
@ -1499,7 +1298,7 @@ impl CodeActionsMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CopilotState {
|
pub(crate) struct CopilotState {
|
||||||
excerpt_id: Option<ExcerptId>,
|
excerpt_id: Option<ExcerptId>,
|
||||||
pending_refresh: Task<Option<()>>,
|
pending_refresh: Task<Option<()>>,
|
||||||
pending_cycling_refresh: Task<Option<()>>,
|
pending_cycling_refresh: Task<Option<()>>,
|
||||||
@ -1619,15 +1418,13 @@ pub struct ClipboardSelection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NavigationData {
|
pub(crate) struct NavigationData {
|
||||||
cursor_anchor: Anchor,
|
cursor_anchor: Anchor,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
scroll_anchor: ScrollAnchor,
|
scroll_anchor: ScrollAnchor,
|
||||||
scroll_top_row: u32,
|
scroll_top_row: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EditorCreated(pub View<Editor>);
|
|
||||||
|
|
||||||
enum GotoDefinitionKind {
|
enum GotoDefinitionKind {
|
||||||
Symbol,
|
Symbol,
|
||||||
Type,
|
Type,
|
||||||
@ -8125,7 +7922,7 @@ impl Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
|
pub fn fold(&mut self, _: &actions::Fold, cx: &mut ViewContext<Self>) {
|
||||||
let mut fold_ranges = Vec::new();
|
let mut fold_ranges = Vec::new();
|
||||||
|
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
@ -8484,7 +8281,7 @@ impl Editor {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn highlight_inlay_background<T: 'static>(
|
pub(crate) fn highlight_inlay_background<T: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ranges: Vec<InlayHighlight>,
|
ranges: Vec<InlayHighlight>,
|
||||||
color_fetcher: fn(&ThemeColors) -> Hsla,
|
color_fetcher: fn(&ThemeColors) -> Hsla,
|
||||||
@ -8691,7 +8488,7 @@ impl Editor {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn highlight_inlays<T: 'static>(
|
pub(crate) fn highlight_inlays<T: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
highlights: Vec<InlayHighlight>,
|
highlights: Vec<InlayHighlight>,
|
||||||
style: HighlightStyle,
|
style: HighlightStyle,
|
||||||
@ -9899,7 +9696,7 @@ pub fn highlight_diagnostic_message(diagnostic: &Diagnostic) -> (SharedString, V
|
|||||||
(text_without_backticks.into(), code_ranges)
|
(text_without_backticks.into(), code_ranges)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostic_style(severity: DiagnosticSeverity, valid: bool, colors: &StatusColors) -> Hsla {
|
fn diagnostic_style(severity: DiagnosticSeverity, valid: bool, colors: &StatusColors) -> Hsla {
|
||||||
match (severity, valid) {
|
match (severity, valid) {
|
||||||
(DiagnosticSeverity::ERROR, true) => colors.error,
|
(DiagnosticSeverity::ERROR, true) => colors.error,
|
||||||
(DiagnosticSeverity::ERROR, false) => colors.error,
|
(DiagnosticSeverity::ERROR, false) => colors.error,
|
||||||
@ -9958,7 +9755,7 @@ pub fn styled_runs_for_code_label<'a>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_words<'a>(text: &'a str) -> impl std::iter::Iterator<Item = &'a str> + 'a {
|
pub(crate) fn split_words<'a>(text: &'a str) -> impl std::iter::Iterator<Item = &'a str> + 'a {
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
let mut codepoints = text.char_indices().peekable();
|
let mut codepoints = text.char_indices().peekable();
|
||||||
|
|
||||||
|
@ -2599,7 +2599,7 @@ impl EditorElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LineWithInvisibles {
|
pub(crate) struct LineWithInvisibles {
|
||||||
pub line: ShapedLine,
|
pub line: ShapedLine,
|
||||||
invisibles: Vec<Invisible>,
|
invisibles: Vec<Invisible>,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
/// Stores and updates all data received from LSP <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHint">textDocument/inlayHint</a> requests.
|
||||||
|
/// Has nothing to do with other inlays, e.g. copilot suggestions — those are stored elsewhere.
|
||||||
|
/// On every update, cache may query for more inlay hints and update inlays on the screen.
|
||||||
|
///
|
||||||
|
/// Inlays stored on screen are in [`crate::display_map::inlay_map`] and this cache is the only way to update any inlay hint data in the visible hints in the inlay map.
|
||||||
|
/// For determining the update to the `inlay_map`, the cache requires a list of visible inlay hints — all other hints are not relevant and their separate updates are not influencing the cache work.
|
||||||
|
///
|
||||||
|
/// Due to the way the data is stored for both visible inlays and the cache, every inlay (and inlay hint) collection is editor-specific, so a single buffer may have multiple sets of inlays of open on different panes.
|
||||||
use std::{
|
use std::{
|
||||||
cmp,
|
cmp,
|
||||||
ops::{ControlFlow, Range},
|
ops::{ControlFlow, Range},
|
||||||
@ -39,7 +47,7 @@ struct TasksForRanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CachedExcerptHints {
|
struct CachedExcerptHints {
|
||||||
version: usize,
|
version: usize,
|
||||||
buffer_version: Global,
|
buffer_version: Global,
|
||||||
buffer_id: u64,
|
buffer_id: u64,
|
||||||
@ -47,15 +55,30 @@ pub struct CachedExcerptHints {
|
|||||||
hints_by_id: HashMap<InlayId, InlayHint>,
|
hints_by_id: HashMap<InlayId, InlayHint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A logic to apply when querying for new inlay hints and deciding what to do with the old entries in the cache in case of conflicts.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum InvalidationStrategy {
|
pub(super) enum InvalidationStrategy {
|
||||||
|
/// Hints reset is <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_inlayHint_refresh">requested</a> by the LSP server.
|
||||||
|
/// Demands to re-query all inlay hints needed and invalidate all cached entries, but does not require instant update with invalidation.
|
||||||
|
///
|
||||||
|
/// Despite nothing forbids language server from sending this request on every edit, it is expected to be sent only when certain internal server state update, invisible for the editor otherwise.
|
||||||
RefreshRequested,
|
RefreshRequested,
|
||||||
|
/// Multibuffer excerpt(s) and/or singleton buffer(s) were edited at least on one place.
|
||||||
|
/// Neither editor nor LSP is able to tell which open file hints' are not affected, so all of them have to be invalidated, re-queried and do that fast enough to avoid being slow, but also debounce to avoid loading hints on every fast keystroke sequence.
|
||||||
BufferEdited,
|
BufferEdited,
|
||||||
|
/// A new file got opened/new excerpt was added to a multibuffer/a [multi]buffer was scrolled to a new position.
|
||||||
|
/// No invalidation should be done at all, all new hints are added to the cache.
|
||||||
|
///
|
||||||
|
/// A special case is the settings change: in addition to LSP capabilities, Zed allows omitting certain hint kinds (defined by the corresponding LSP part: type/parameter/other).
|
||||||
|
/// This does not lead to cache invalidation, but would require cache usage for determining which hints are not displayed and issuing an update to inlays on the screen.
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
/// A splice to send into the `inlay_map` for updating the visible inlays on the screen.
|
||||||
pub struct InlaySplice {
|
/// "Visible" inlays may not be displayed in the buffer right away, but those are ready to be displayed on further buffer scroll, pane item activations, etc. right away without additional LSP queries or settings changes.
|
||||||
|
/// The data in the cache is never used directly for displaying inlays on the screen, to avoid races with updates from LSP queries and sync overhead.
|
||||||
|
/// Splice is picked to help avoid extra hint flickering and "jumps" on the screen.
|
||||||
|
pub(super) struct InlaySplice {
|
||||||
pub to_remove: Vec<InlayId>,
|
pub to_remove: Vec<InlayId>,
|
||||||
pub to_insert: Vec<Inlay>,
|
pub to_insert: Vec<Inlay>,
|
||||||
}
|
}
|
||||||
@ -237,7 +260,7 @@ impl TasksForRanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InlayHintCache {
|
impl InlayHintCache {
|
||||||
pub fn new(inlay_hint_settings: InlayHintSettings) -> Self {
|
pub(super) fn new(inlay_hint_settings: InlayHintSettings) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allowed_hint_kinds: inlay_hint_settings.enabled_inlay_hint_kinds(),
|
allowed_hint_kinds: inlay_hint_settings.enabled_inlay_hint_kinds(),
|
||||||
enabled: inlay_hint_settings.enabled,
|
enabled: inlay_hint_settings.enabled,
|
||||||
@ -248,7 +271,10 @@ impl InlayHintCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_settings(
|
/// Checks inlay hint settings for enabled hint kinds and general enabled state.
|
||||||
|
/// Generates corresponding inlay_map splice updates on settings changes.
|
||||||
|
/// Does not update inlay hint cache state on disabling or inlay hint kinds change: only reenabling forces new LSP queries.
|
||||||
|
pub(super) fn update_settings(
|
||||||
&mut self,
|
&mut self,
|
||||||
multi_buffer: &Model<MultiBuffer>,
|
multi_buffer: &Model<MultiBuffer>,
|
||||||
new_hint_settings: InlayHintSettings,
|
new_hint_settings: InlayHintSettings,
|
||||||
@ -299,7 +325,11 @@ impl InlayHintCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_hint_refresh(
|
/// If needed, queries LSP for new inlay hints, using the invalidation strategy given.
|
||||||
|
/// To reduce inlay hint jumping, attempts to query a visible range of the editor(s) first,
|
||||||
|
/// followed by the delayed queries of the same range above and below the visible one.
|
||||||
|
/// This way, concequent refresh invocations are less likely to trigger LSP queries for the invisible ranges.
|
||||||
|
pub(super) fn spawn_hint_refresh(
|
||||||
&mut self,
|
&mut self,
|
||||||
reason: &'static str,
|
reason: &'static str,
|
||||||
excerpts_to_query: HashMap<ExcerptId, (Model<Buffer>, Global, Range<usize>)>,
|
excerpts_to_query: HashMap<ExcerptId, (Model<Buffer>, Global, Range<usize>)>,
|
||||||
@ -460,7 +490,11 @@ impl InlayHintCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_excerpts(&mut self, excerpts_removed: Vec<ExcerptId>) -> Option<InlaySplice> {
|
/// Completely forget of certain excerpts that were removed from the multibuffer.
|
||||||
|
pub(super) fn remove_excerpts(
|
||||||
|
&mut self,
|
||||||
|
excerpts_removed: Vec<ExcerptId>,
|
||||||
|
) -> Option<InlaySplice> {
|
||||||
let mut to_remove = Vec::new();
|
let mut to_remove = Vec::new();
|
||||||
for excerpt_to_remove in excerpts_removed {
|
for excerpt_to_remove in excerpts_removed {
|
||||||
self.update_tasks.remove(&excerpt_to_remove);
|
self.update_tasks.remove(&excerpt_to_remove);
|
||||||
@ -480,7 +514,7 @@ impl InlayHintCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub(super) fn clear(&mut self) {
|
||||||
if !self.update_tasks.is_empty() || !self.hints.is_empty() {
|
if !self.update_tasks.is_empty() || !self.hints.is_empty() {
|
||||||
self.version += 1;
|
self.version += 1;
|
||||||
}
|
}
|
||||||
@ -488,7 +522,7 @@ impl InlayHintCache {
|
|||||||
self.hints.clear();
|
self.hints.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hint_by_id(&self, excerpt_id: ExcerptId, hint_id: InlayId) -> Option<InlayHint> {
|
pub(super) fn hint_by_id(&self, excerpt_id: ExcerptId, hint_id: InlayId) -> Option<InlayHint> {
|
||||||
self.hints
|
self.hints
|
||||||
.get(&excerpt_id)?
|
.get(&excerpt_id)?
|
||||||
.read()
|
.read()
|
||||||
@ -516,7 +550,8 @@ impl InlayHintCache {
|
|||||||
self.version
|
self.version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_hint_resolve(
|
/// Queries a certain hint from the cache for extra data via the LSP <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHint_resolve">resolve</a> request.
|
||||||
|
pub(super) fn spawn_hint_resolve(
|
||||||
&self,
|
&self,
|
||||||
buffer_id: u64,
|
buffer_id: u64,
|
||||||
excerpt_id: ExcerptId,
|
excerpt_id: ExcerptId,
|
||||||
@ -1199,7 +1234,7 @@ pub mod tests {
|
|||||||
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
scroll::{autoscroll::Autoscroll, scroll_amount::ScrollAmount},
|
scroll::{scroll_amount::ScrollAmount, Autoscroll},
|
||||||
ExcerptRange,
|
ExcerptRange,
|
||||||
};
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
@ -69,7 +69,7 @@ pub enum GoToDefinitionLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct InlayHighlight {
|
pub(crate) struct InlayHighlight {
|
||||||
pub inlay: InlayId,
|
pub inlay: InlayId,
|
||||||
pub inlay_position: Anchor,
|
pub inlay_position: Anchor,
|
||||||
pub range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
//! Movement module contains helper functions for calculating intended position
|
||||||
|
//! in editor given a given motion (e.g. it handles converting a "move left" command into coordinates in editor). It is exposed mostly for use by vim crate.
|
||||||
|
|
||||||
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
|
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
|
||||||
use crate::{char_kind, CharKind, EditorStyle, ToOffset, ToPoint};
|
use crate::{char_kind, CharKind, EditorStyle, ToOffset, ToPoint};
|
||||||
use gpui::{px, Pixels, TextSystem};
|
use gpui::{px, Pixels, TextSystem};
|
||||||
@ -5,6 +8,9 @@ use language::Point;
|
|||||||
|
|
||||||
use std::{ops::Range, sync::Arc};
|
use std::{ops::Range, sync::Arc};
|
||||||
|
|
||||||
|
/// Defines search strategy for items in `movement` module.
|
||||||
|
/// `FindRange::SingeLine` only looks for a match on a single line at a time, whereas
|
||||||
|
/// `FindRange::MultiLine` keeps going until the end of a string.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum FindRange {
|
pub enum FindRange {
|
||||||
SingleLine,
|
SingleLine,
|
||||||
@ -14,11 +20,13 @@ pub enum FindRange {
|
|||||||
/// TextLayoutDetails encompasses everything we need to move vertically
|
/// TextLayoutDetails encompasses everything we need to move vertically
|
||||||
/// taking into account variable width characters.
|
/// taking into account variable width characters.
|
||||||
pub struct TextLayoutDetails {
|
pub struct TextLayoutDetails {
|
||||||
pub text_system: Arc<TextSystem>,
|
pub(crate) text_system: Arc<TextSystem>,
|
||||||
pub editor_style: EditorStyle,
|
pub(crate) editor_style: EditorStyle,
|
||||||
pub rem_size: Pixels,
|
pub(crate) rem_size: Pixels,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a column to the left of the current point, wrapping
|
||||||
|
/// to the previous line if that point is at the start of line.
|
||||||
pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
||||||
if point.column() > 0 {
|
if point.column() > 0 {
|
||||||
*point.column_mut() -= 1;
|
*point.column_mut() -= 1;
|
||||||
@ -29,6 +37,8 @@ pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
|||||||
map.clip_point(point, Bias::Left)
|
map.clip_point(point, Bias::Left)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a column to the left of the current point, doing nothing if
|
||||||
|
/// that point is already at the start of line.
|
||||||
pub fn saturating_left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
pub fn saturating_left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
||||||
if point.column() > 0 {
|
if point.column() > 0 {
|
||||||
*point.column_mut() -= 1;
|
*point.column_mut() -= 1;
|
||||||
@ -36,6 +46,8 @@ pub fn saturating_left(map: &DisplaySnapshot, mut point: DisplayPoint) -> Displa
|
|||||||
map.clip_point(point, Bias::Left)
|
map.clip_point(point, Bias::Left)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a column to the right of the current point, wrapping
|
||||||
|
/// to the next line if that point is at the end of line.
|
||||||
pub fn right(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
pub fn right(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
||||||
let max_column = map.line_len(point.row());
|
let max_column = map.line_len(point.row());
|
||||||
if point.column() < max_column {
|
if point.column() < max_column {
|
||||||
@ -47,11 +59,14 @@ pub fn right(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
|||||||
map.clip_point(point, Bias::Right)
|
map.clip_point(point, Bias::Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a column to the right of the current point, not performing any wrapping
|
||||||
|
/// if that point is already at the end of line.
|
||||||
pub fn saturating_right(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
pub fn saturating_right(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
|
||||||
*point.column_mut() += 1;
|
*point.column_mut() += 1;
|
||||||
map.clip_point(point, Bias::Right)
|
map.clip_point(point, Bias::Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a display point for the preceding displayed line (which might be a soft-wrapped line).
|
||||||
pub fn up(
|
pub fn up(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
start: DisplayPoint,
|
start: DisplayPoint,
|
||||||
@ -69,6 +84,7 @@ pub fn up(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a display point for the next displayed line (which might be a soft-wrapped line).
|
||||||
pub fn down(
|
pub fn down(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
start: DisplayPoint,
|
start: DisplayPoint,
|
||||||
@ -86,7 +102,7 @@ pub fn down(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn up_by_rows(
|
pub(crate) fn up_by_rows(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
start: DisplayPoint,
|
start: DisplayPoint,
|
||||||
row_count: u32,
|
row_count: u32,
|
||||||
@ -125,7 +141,7 @@ pub fn up_by_rows(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn down_by_rows(
|
pub(crate) fn down_by_rows(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
start: DisplayPoint,
|
start: DisplayPoint,
|
||||||
row_count: u32,
|
row_count: u32,
|
||||||
@ -161,6 +177,10 @@ pub fn down_by_rows(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the start of line.
|
||||||
|
/// If `stop_at_soft_boundaries` is true, the returned position is that of the
|
||||||
|
/// displayed line (e.g. it could actually be in the middle of a text line if that line is soft-wrapped).
|
||||||
|
/// Otherwise it's always going to be the start of a logical line.
|
||||||
pub fn line_beginning(
|
pub fn line_beginning(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
display_point: DisplayPoint,
|
display_point: DisplayPoint,
|
||||||
@ -177,6 +197,10 @@ pub fn line_beginning(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the last indented position on a given line.
|
||||||
|
/// If `stop_at_soft_boundaries` is true, the returned [`DisplayPoint`] is that of a
|
||||||
|
/// displayed line (e.g. if there's soft wrap it's gonna be returned),
|
||||||
|
/// otherwise it's always going to be a start of a logical line.
|
||||||
pub fn indented_line_beginning(
|
pub fn indented_line_beginning(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
display_point: DisplayPoint,
|
display_point: DisplayPoint,
|
||||||
@ -201,6 +225,11 @@ pub fn indented_line_beginning(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the end of line.
|
||||||
|
|
||||||
|
/// If `stop_at_soft_boundaries` is true, the returned position is that of the
|
||||||
|
/// displayed line (e.g. it could actually be in the middle of a text line if that line is soft-wrapped).
|
||||||
|
/// Otherwise it's always going to be the end of a logical line.
|
||||||
pub fn line_end(
|
pub fn line_end(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
display_point: DisplayPoint,
|
display_point: DisplayPoint,
|
||||||
@ -217,6 +246,8 @@ pub fn line_end(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the previous word boundary, where a word character is defined as either
|
||||||
|
/// uppercase letter, lowercase letter, '_' character or language-specific word character (like '-' in CSS).
|
||||||
pub fn previous_word_start(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
pub fn previous_word_start(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||||
let raw_point = point.to_point(map);
|
let raw_point = point.to_point(map);
|
||||||
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
||||||
@ -227,6 +258,9 @@ pub fn previous_word_start(map: &DisplaySnapshot, point: DisplayPoint) -> Displa
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the previous subword boundary, where a subword is defined as a run of
|
||||||
|
/// word characters of the same "subkind" - where subcharacter kinds are '_' character,
|
||||||
|
/// lowerspace characters and uppercase characters.
|
||||||
pub fn previous_subword_start(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
pub fn previous_subword_start(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||||
let raw_point = point.to_point(map);
|
let raw_point = point.to_point(map);
|
||||||
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
||||||
@ -240,6 +274,8 @@ pub fn previous_subword_start(map: &DisplaySnapshot, point: DisplayPoint) -> Dis
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the next word boundary, where a word character is defined as either
|
||||||
|
/// uppercase letter, lowercase letter, '_' character or language-specific word character (like '-' in CSS).
|
||||||
pub fn next_word_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
pub fn next_word_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||||
let raw_point = point.to_point(map);
|
let raw_point = point.to_point(map);
|
||||||
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
||||||
@ -250,6 +286,9 @@ pub fn next_word_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the next subword boundary, where a subword is defined as a run of
|
||||||
|
/// word characters of the same "subkind" - where subcharacter kinds are '_' character,
|
||||||
|
/// lowerspace characters and uppercase characters.
|
||||||
pub fn next_subword_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
pub fn next_subword_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||||
let raw_point = point.to_point(map);
|
let raw_point = point.to_point(map);
|
||||||
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
||||||
@ -263,6 +302,8 @@ pub fn next_subword_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPo
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the start of the current paragraph, where a paragraph
|
||||||
|
/// is defined as a run of non-blank lines.
|
||||||
pub fn start_of_paragraph(
|
pub fn start_of_paragraph(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
display_point: DisplayPoint,
|
display_point: DisplayPoint,
|
||||||
@ -290,6 +331,8 @@ pub fn start_of_paragraph(
|
|||||||
DisplayPoint::zero()
|
DisplayPoint::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a position of the end of the current paragraph, where a paragraph
|
||||||
|
/// is defined as a run of non-blank lines.
|
||||||
pub fn end_of_paragraph(
|
pub fn end_of_paragraph(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
display_point: DisplayPoint,
|
display_point: DisplayPoint,
|
||||||
@ -376,6 +419,9 @@ pub fn find_boundary(
|
|||||||
map.clip_point(offset.to_display_point(map), Bias::Right)
|
map.clip_point(offset.to_display_point(map), Bias::Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the characters following a given offset in the [`DisplaySnapshot`].
|
||||||
|
/// The returned value also contains a range of the start/end of a returned character in
|
||||||
|
/// the [`DisplaySnapshot`]. The offsets are relative to the start of a buffer.
|
||||||
pub fn chars_after(
|
pub fn chars_after(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
mut offset: usize,
|
mut offset: usize,
|
||||||
@ -387,6 +433,9 @@ pub fn chars_after(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reverse iterator over the characters following a given offset in the [`DisplaySnapshot`].
|
||||||
|
/// The returned value also contains a range of the start/end of a returned character in
|
||||||
|
/// the [`DisplaySnapshot`]. The offsets are relative to the start of a buffer.
|
||||||
pub fn chars_before(
|
pub fn chars_before(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
mut offset: usize,
|
mut offset: usize,
|
||||||
@ -400,7 +449,7 @@ pub fn chars_before(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_inside_word(map: &DisplaySnapshot, point: DisplayPoint) -> bool {
|
pub(crate) fn is_inside_word(map: &DisplaySnapshot, point: DisplayPoint) -> bool {
|
||||||
let raw_point = point.to_point(map);
|
let raw_point = point.to_point(map);
|
||||||
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
let scope = map.buffer_snapshot.language_scope_at(raw_point);
|
||||||
let ix = map.clip_point(point, Bias::Left).to_offset(map, Bias::Left);
|
let ix = map.clip_point(point, Bias::Left).to_offset(map, Bias::Left);
|
||||||
@ -413,7 +462,10 @@ pub fn is_inside_word(map: &DisplaySnapshot, point: DisplayPoint) -> bool {
|
|||||||
prev_char_kind.zip(next_char_kind) == Some((CharKind::Word, CharKind::Word))
|
prev_char_kind.zip(next_char_kind) == Some((CharKind::Word, CharKind::Word))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn surrounding_word(map: &DisplaySnapshot, position: DisplayPoint) -> Range<DisplayPoint> {
|
pub(crate) fn surrounding_word(
|
||||||
|
map: &DisplaySnapshot,
|
||||||
|
position: DisplayPoint,
|
||||||
|
) -> Range<DisplayPoint> {
|
||||||
let position = map
|
let position = map
|
||||||
.clip_point(position, Bias::Left)
|
.clip_point(position, Bias::Left)
|
||||||
.to_offset(map, Bias::Left);
|
.to_offset(map, Bias::Left);
|
||||||
@ -429,6 +481,12 @@ pub fn surrounding_word(map: &DisplaySnapshot, position: DisplayPoint) -> Range<
|
|||||||
start..end
|
start..end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a list of lines (represented as a [`DisplayPoint`] range) contained
|
||||||
|
/// within a passed range.
|
||||||
|
///
|
||||||
|
/// The line ranges are **always* going to be in bounds of a requested range, which means that
|
||||||
|
/// the first and the last lines might not necessarily represent the
|
||||||
|
/// full range of a logical line (as their `.start`/`.end` values are clipped to those of a passed in range).
|
||||||
pub fn split_display_range_by_lines(
|
pub fn split_display_range_by_lines(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
range: Range<DisplayPoint>,
|
range: Range<DisplayPoint>,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pub mod actions;
|
mod actions;
|
||||||
pub mod autoscroll;
|
pub(crate) mod autoscroll;
|
||||||
pub mod scroll_amount;
|
pub(crate) mod scroll_amount;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||||
@ -9,8 +9,10 @@ use crate::{
|
|||||||
Anchor, DisplayPoint, Editor, EditorEvent, EditorMode, InlayHintRefreshReason,
|
Anchor, DisplayPoint, Editor, EditorEvent, EditorMode, InlayHintRefreshReason,
|
||||||
MultiBufferSnapshot, ToPoint,
|
MultiBufferSnapshot, ToPoint,
|
||||||
};
|
};
|
||||||
|
pub use autoscroll::{Autoscroll, AutoscrollStrategy};
|
||||||
use gpui::{point, px, AppContext, Entity, Pixels, Task, ViewContext};
|
use gpui::{point, px, AppContext, Entity, Pixels, Task, ViewContext};
|
||||||
use language::{Bias, Point};
|
use language::{Bias, Point};
|
||||||
|
pub use scroll_amount::ScrollAmount;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
@ -18,11 +20,6 @@ use std::{
|
|||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{ItemId, WorkspaceId};
|
use workspace::{ItemId, WorkspaceId};
|
||||||
|
|
||||||
use self::{
|
|
||||||
autoscroll::{Autoscroll, AutoscrollStrategy},
|
|
||||||
scroll_amount::ScrollAmount,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const SCROLL_EVENT_SEPARATION: Duration = Duration::from_millis(28);
|
pub const SCROLL_EVENT_SEPARATION: Duration = Duration::from_millis(28);
|
||||||
pub const VERTICAL_SCROLL_MARGIN: f32 = 3.;
|
pub const VERTICAL_SCROLL_MARGIN: f32 = 3.;
|
||||||
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
|
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
|
||||||
|
@ -175,7 +175,7 @@ impl Editor {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoscroll_horizontally(
|
pub(crate) fn autoscroll_horizontally(
|
||||||
&mut self,
|
&mut self,
|
||||||
start_row: u32,
|
start_row: u32,
|
||||||
viewport_width: Pixels,
|
viewport_width: Pixels,
|
||||||
|
@ -99,7 +99,7 @@ impl SelectionsCollection {
|
|||||||
.map(|pending| pending.map(|p| p.summary::<D>(&self.buffer(cx))))
|
.map(|pending| pending.map(|p| p.summary::<D>(&self.buffer(cx))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pending_mode(&self) -> Option<SelectMode> {
|
pub(crate) fn pending_mode(&self) -> Option<SelectMode> {
|
||||||
self.pending.as_ref().map(|pending| pending.mode.clone())
|
self.pending.as_ref().map(|pending| pending.mode.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +398,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pending_anchor_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
|
pub(crate) fn set_pending_anchor_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
|
||||||
self.collection.pending = Some(PendingSelection {
|
self.collection.pending = Some(PendingSelection {
|
||||||
selection: Selection {
|
selection: Selection {
|
||||||
id: post_inc(&mut self.collection.next_selection_id),
|
id: post_inc(&mut self.collection.next_selection_id),
|
||||||
@ -412,7 +412,11 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||||||
self.selections_changed = true;
|
self.selections_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pending_display_range(&mut self, range: Range<DisplayPoint>, mode: SelectMode) {
|
pub(crate) fn set_pending_display_range(
|
||||||
|
&mut self,
|
||||||
|
range: Range<DisplayPoint>,
|
||||||
|
mode: SelectMode,
|
||||||
|
) {
|
||||||
let (start, end, reversed) = {
|
let (start, end, reversed) = {
|
||||||
let display_map = self.display_map();
|
let display_map = self.display_map();
|
||||||
let buffer = self.buffer();
|
let buffer = self.buffer();
|
||||||
@ -448,7 +452,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||||||
self.selections_changed = true;
|
self.selections_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
|
pub(crate) fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
|
||||||
self.collection.pending = Some(PendingSelection { selection, mode });
|
self.collection.pending = Some(PendingSelection { selection, mode });
|
||||||
self.selections_changed = true;
|
self.selections_changed = true;
|
||||||
}
|
}
|
||||||
@ -855,7 +859,7 @@ impl<'a> DerefMut for MutableSelectionsCollection<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Panics if passed selections are not in order
|
// Panics if passed selections are not in order
|
||||||
pub fn resolve_multiple<'a, D, I>(
|
pub(crate) fn resolve_multiple<'a, D, I>(
|
||||||
selections: I,
|
selections: I,
|
||||||
snapshot: &MultiBufferSnapshot,
|
snapshot: &MultiBufferSnapshot,
|
||||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
) -> impl 'a + Iterator<Item = Selection<D>>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Bias, Editor};
|
use editor::{scroll::Autoscroll, Bias, Editor};
|
||||||
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, rems, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Model,
|
actions, rems, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Model,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor};
|
use editor::{display_map::ToDisplayPoint, scroll::Autoscroll, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, prelude::*, AnyWindowHandle, AppContext, DismissEvent, EventEmitter, FocusHandle,
|
actions, div, prelude::*, AnyWindowHandle, AppContext, DismissEvent, EventEmitter, FocusHandle,
|
||||||
FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext,
|
FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chrono::{Datelike, Local, NaiveTime, Timelike};
|
use chrono::{Datelike, Local, NaiveTime, Timelike};
|
||||||
use editor::scroll::autoscroll::Autoscroll;
|
use editor::scroll::Autoscroll;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use gpui::{actions, AppContext, ViewContext, WindowContext};
|
use gpui::{actions, AppContext, ViewContext, WindowContext};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use collections::{HashMap, VecDeque};
|
use collections::{HashMap, VecDeque};
|
||||||
use editor::{Editor, EditorEvent, MoveToEnd};
|
use editor::{actions::MoveToEnd, Editor, EditorEvent};
|
||||||
use futures::{channel::mpsc, StreamExt};
|
use futures::{channel::mpsc, StreamExt};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, AnchorCorner, AnyElement, AppContext, Context, EventEmitter, FocusHandle,
|
actions, div, AnchorCorner, AnyElement, AppContext, Context, EventEmitter, FocusHandle,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId};
|
use editor::{scroll::Autoscroll, Anchor, Editor, ExcerptId};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, canvas, div, rems, uniform_list, AnyElement, AppContext, AvailableSpace, Div,
|
actions, canvas, div, rems, uniform_list, AnyElement, AppContext, AvailableSpace, Div,
|
||||||
EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model,
|
EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use editor::{
|
use editor::{
|
||||||
display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Anchor, AnchorRangeExt,
|
display_map::ToDisplayPoint, scroll::Autoscroll, Anchor, AnchorRangeExt, DisplayPoint, Editor,
|
||||||
DisplayPoint, Editor, EditorMode, ToPoint,
|
EditorMode, ToPoint,
|
||||||
};
|
};
|
||||||
use fuzzy::StringMatch;
|
use fuzzy::StringMatch;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -3,7 +3,7 @@ mod project_panel_settings;
|
|||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Cancel, Editor};
|
use editor::{actions::Cancel, scroll::Autoscroll, Editor};
|
||||||
use file_associations::FileAssociations;
|
use file_associations::FileAssociations;
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use editor::{scroll::autoscroll::Autoscroll, styled_runs_for_code_label, Bias, Editor};
|
use editor::{scroll::Autoscroll, styled_runs_for_code_label, Bias, Editor};
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, rems, AppContext, DismissEvent, FontWeight, Model, ParentElement, StyledText, Task,
|
actions, rems, AppContext, DismissEvent, FontWeight, Model, ParentElement, StyledText, Task,
|
||||||
|
@ -45,13 +45,13 @@ impl Render for QuickActionBar {
|
|||||||
"toggle inlay hints",
|
"toggle inlay hints",
|
||||||
IconName::InlayHint,
|
IconName::InlayHint,
|
||||||
editor.read(cx).inlay_hints_enabled(),
|
editor.read(cx).inlay_hints_enabled(),
|
||||||
Box::new(editor::ToggleInlayHints),
|
Box::new(editor::actions::ToggleInlayHints),
|
||||||
"Toggle Inlay Hints",
|
"Toggle Inlay Hints",
|
||||||
{
|
{
|
||||||
let editor = editor.clone();
|
let editor = editor.clone();
|
||||||
move |_, cx| {
|
move |_, cx| {
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.toggle_inlay_hints(&editor::ToggleInlayHints, cx);
|
editor.toggle_inlay_hints(&editor::actions::ToggleInlayHints, cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
ToggleCaseSensitive, ToggleReplace, ToggleWholeWord,
|
ToggleCaseSensitive, ToggleReplace, ToggleWholeWord,
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::{Editor, EditorElement, EditorStyle, Tab};
|
use editor::{actions::Tab, Editor, EditorElement, EditorStyle};
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, impl_actions, Action, AppContext, ClickEvent, EventEmitter, FocusableView,
|
actions, div, impl_actions, Action, AppContext, ClickEvent, EventEmitter, FocusableView,
|
||||||
@ -635,7 +635,7 @@ impl BufferSearchBar {
|
|||||||
registrar.register_handler(|this, action: &SelectAllMatches, cx| {
|
registrar.register_handler(|this, action: &SelectAllMatches, cx| {
|
||||||
this.select_all_matches(action, cx);
|
this.select_all_matches(action, cx);
|
||||||
});
|
});
|
||||||
registrar.register_handler(|this, _: &editor::Cancel, cx| {
|
registrar.register_handler(|this, _: &editor::actions::Cancel, cx| {
|
||||||
this.dismiss(&Dismiss, cx);
|
this.dismiss(&Dismiss, cx);
|
||||||
});
|
});
|
||||||
registrar.register_handler_for_dismissed_search(|this, deploy, cx| {
|
registrar.register_handler_for_dismissed_search(|this, deploy, cx| {
|
||||||
|
@ -7,8 +7,8 @@ use crate::{
|
|||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::{
|
use editor::{
|
||||||
items::active_match_index, scroll::autoscroll::Autoscroll, Anchor, Editor, EditorEvent,
|
actions::SelectAll, items::active_match_index, scroll::Autoscroll, Anchor, Editor, EditorEvent,
|
||||||
MultiBuffer, SelectAll, MAX_TAB_TITLE_LEN,
|
MultiBuffer, MAX_TAB_TITLE_LEN,
|
||||||
};
|
};
|
||||||
use editor::{EditorElement, EditorStyle};
|
use editor::{EditorElement, EditorStyle};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@ -1383,11 +1383,11 @@ impl ProjectSearchBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab(&mut self, _: &editor::Tab, cx: &mut ViewContext<Self>) {
|
fn tab(&mut self, _: &editor::actions::Tab, cx: &mut ViewContext<Self>) {
|
||||||
self.cycle_field(Direction::Next, cx);
|
self.cycle_field(Direction::Next, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_previous(&mut self, _: &editor::TabPrev, cx: &mut ViewContext<Self>) {
|
fn tab_previous(&mut self, _: &editor::actions::TabPrev, cx: &mut ViewContext<Self>) {
|
||||||
self.cycle_field(Direction::Prev, cx);
|
self.cycle_field(Direction::Prev, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,11 @@ pub struct AutoHeightEditorStory {
|
|||||||
|
|
||||||
impl AutoHeightEditorStory {
|
impl AutoHeightEditorStory {
|
||||||
pub fn new(cx: &mut WindowContext) -> View<Self> {
|
pub fn new(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.bind_keys([KeyBinding::new("enter", editor::Newline, Some("Editor"))]);
|
cx.bind_keys([KeyBinding::new(
|
||||||
|
"enter",
|
||||||
|
editor::actions::Newline,
|
||||||
|
Some("Editor"),
|
||||||
|
)]);
|
||||||
cx.new_view(|cx| Self {
|
cx.new_view(|cx| Self {
|
||||||
editor: cx.new_view(|cx| {
|
editor: cx.new_view(|cx| {
|
||||||
let mut editor = Editor::auto_height(3, cx);
|
let mut editor = Editor::auto_height(3, cx);
|
||||||
|
@ -2,7 +2,7 @@ mod persistence;
|
|||||||
pub mod terminal_element;
|
pub mod terminal_element;
|
||||||
pub mod terminal_panel;
|
pub mod terminal_panel;
|
||||||
|
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
use editor::{scroll::Autoscroll, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, impl_actions, overlay, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle,
|
div, impl_actions, overlay, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle,
|
||||||
FocusableView, KeyContext, KeyDownEvent, Keystroke, Model, MouseButton, MouseDownEvent, Pixels,
|
FocusableView, KeyContext, KeyDownEvent, Keystroke, Model, MouseButton, MouseDownEvent, Pixels,
|
||||||
@ -357,7 +357,7 @@ impl TerminalView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_all(&mut self, _: &editor::SelectAll, cx: &mut ViewContext<Self>) {
|
fn select_all(&mut self, _: &editor::actions::SelectAll, cx: &mut ViewContext<Self>) {
|
||||||
self.terminal.update(cx, |term, _| term.select_all());
|
self.terminal.update(cx, |term, _| term.select_all());
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use command_palette::CommandInterceptResult;
|
use command_palette::CommandInterceptResult;
|
||||||
use editor::{SortLinesCaseInsensitive, SortLinesCaseSensitive};
|
use editor::actions::{SortLinesCaseInsensitive, SortLinesCaseSensitive};
|
||||||
use gpui::{impl_actions, Action, AppContext, ViewContext};
|
use gpui::{impl_actions, Action, AppContext, ViewContext};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use workspace::{SaveIntent, Workspace};
|
use workspace::{SaveIntent, Workspace};
|
||||||
@ -204,25 +204,31 @@ pub fn command_interceptor(mut query: &str, _: &AppContext) -> Option<CommandInt
|
|||||||
|
|
||||||
// quickfix / loclist (merged together for now)
|
// quickfix / loclist (merged together for now)
|
||||||
"cl" | "cli" | "clis" | "clist" => ("clist", diagnostics::Deploy.boxed_clone()),
|
"cl" | "cli" | "clis" | "clist" => ("clist", diagnostics::Deploy.boxed_clone()),
|
||||||
"cc" => ("cc", editor::Hover.boxed_clone()),
|
"cc" => ("cc", editor::actions::Hover.boxed_clone()),
|
||||||
"ll" => ("ll", editor::Hover.boxed_clone()),
|
"ll" => ("ll", editor::actions::Hover.boxed_clone()),
|
||||||
"cn" | "cne" | "cnex" | "cnext" => ("cnext", editor::GoToDiagnostic.boxed_clone()),
|
"cn" | "cne" | "cnex" | "cnext" => ("cnext", editor::actions::GoToDiagnostic.boxed_clone()),
|
||||||
"lne" | "lnex" | "lnext" => ("cnext", editor::GoToDiagnostic.boxed_clone()),
|
"lne" | "lnex" | "lnext" => ("cnext", editor::actions::GoToDiagnostic.boxed_clone()),
|
||||||
|
|
||||||
"cpr" | "cpre" | "cprev" | "cprevi" | "cprevio" | "cpreviou" | "cprevious" => {
|
"cpr" | "cpre" | "cprev" | "cprevi" | "cprevio" | "cpreviou" | "cprevious" => (
|
||||||
("cprevious", editor::GoToPrevDiagnostic.boxed_clone())
|
"cprevious",
|
||||||
|
editor::actions::GoToPrevDiagnostic.boxed_clone(),
|
||||||
|
),
|
||||||
|
"cN" | "cNe" | "cNex" | "cNext" => {
|
||||||
|
("cNext", editor::actions::GoToPrevDiagnostic.boxed_clone())
|
||||||
}
|
}
|
||||||
"cN" | "cNe" | "cNex" | "cNext" => ("cNext", editor::GoToPrevDiagnostic.boxed_clone()),
|
"lp" | "lpr" | "lpre" | "lprev" | "lprevi" | "lprevio" | "lpreviou" | "lprevious" => (
|
||||||
"lp" | "lpr" | "lpre" | "lprev" | "lprevi" | "lprevio" | "lpreviou" | "lprevious" => {
|
"lprevious",
|
||||||
("lprevious", editor::GoToPrevDiagnostic.boxed_clone())
|
editor::actions::GoToPrevDiagnostic.boxed_clone(),
|
||||||
|
),
|
||||||
|
"lN" | "lNe" | "lNex" | "lNext" => {
|
||||||
|
("lNext", editor::actions::GoToPrevDiagnostic.boxed_clone())
|
||||||
}
|
}
|
||||||
"lN" | "lNe" | "lNex" | "lNext" => ("lNext", editor::GoToPrevDiagnostic.boxed_clone()),
|
|
||||||
|
|
||||||
// modify the buffer (should accept [range])
|
// modify the buffer (should accept [range])
|
||||||
"j" | "jo" | "joi" | "join" => ("join", JoinLines.boxed_clone()),
|
"j" | "jo" | "joi" | "join" => ("join", JoinLines.boxed_clone()),
|
||||||
"d" | "de" | "del" | "dele" | "delet" | "delete" | "dl" | "dell" | "delel" | "deletl"
|
"d" | "de" | "del" | "dele" | "delet" | "delete" | "dl" | "dell" | "delel" | "deletl"
|
||||||
| "deletel" | "dp" | "dep" | "delp" | "delep" | "deletp" | "deletep" => {
|
| "deletel" | "dp" | "dep" | "delp" | "delep" | "deletp" | "deletep" => {
|
||||||
("delete", editor::DeleteLine.boxed_clone())
|
("delete", editor::actions::DeleteLine.boxed_clone())
|
||||||
}
|
}
|
||||||
"sor" | "sor " | "sort" | "sort " => ("sort", SortLinesCaseSensitive.boxed_clone()),
|
"sor" | "sor " | "sort" | "sort " => ("sort", SortLinesCaseSensitive.boxed_clone()),
|
||||||
"sor i" | "sort i" => ("sort i", SortLinesCaseInsensitive.boxed_clone()),
|
"sor i" | "sort i" => ("sort i", SortLinesCaseInsensitive.boxed_clone()),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{normal::repeat, state::Mode, Vim};
|
use crate::{normal::repeat, state::Mode, Vim};
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Bias};
|
use editor::{scroll::Autoscroll, Bias};
|
||||||
use gpui::{actions, Action, ViewContext};
|
use gpui::{actions, Action, ViewContext};
|
||||||
use language::SelectionGoal;
|
use language::SelectionGoal;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use editor::{
|
use editor::{
|
||||||
char_kind,
|
|
||||||
display_map::{DisplaySnapshot, FoldPoint, ToDisplayPoint},
|
display_map::{DisplaySnapshot, FoldPoint, ToDisplayPoint},
|
||||||
movement::{self, find_boundary, find_preceding_boundary, FindRange, TextLayoutDetails},
|
movement::{self, find_boundary, find_preceding_boundary, FindRange, TextLayoutDetails},
|
||||||
Bias, CharKind, DisplayPoint, ToOffset,
|
Bias, DisplayPoint, ToOffset,
|
||||||
};
|
};
|
||||||
use gpui::{actions, impl_actions, px, ViewContext, WindowContext};
|
use gpui::{actions, impl_actions, px, ViewContext, WindowContext};
|
||||||
use language::{Point, Selection, SelectionGoal};
|
use language::{char_kind, CharKind, Point, Selection, SelectionGoal};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
Vim,
|
Vim,
|
||||||
};
|
};
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
use editor::scroll::autoscroll::Autoscroll;
|
use editor::scroll::Autoscroll;
|
||||||
use editor::{Bias, DisplayPoint};
|
use editor::{Bias, DisplayPoint};
|
||||||
use gpui::{actions, ViewContext, WindowContext};
|
use gpui::{actions, ViewContext, WindowContext};
|
||||||
use language::SelectionGoal;
|
use language::SelectionGoal;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use editor::scroll::autoscroll::Autoscroll;
|
use editor::scroll::Autoscroll;
|
||||||
use gpui::ViewContext;
|
use gpui::ViewContext;
|
||||||
use language::{Bias, Point};
|
use language::{Bias, Point};
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
use crate::{motion::Motion, object::Object, state::Mode, utils::copy_selections_content, Vim};
|
use crate::{motion::Motion, object::Object, state::Mode, utils::copy_selections_content, Vim};
|
||||||
use editor::{
|
use editor::{
|
||||||
char_kind,
|
|
||||||
display_map::DisplaySnapshot,
|
display_map::DisplaySnapshot,
|
||||||
movement::{self, FindRange, TextLayoutDetails},
|
movement::{self, FindRange, TextLayoutDetails},
|
||||||
scroll::autoscroll::Autoscroll,
|
scroll::Autoscroll,
|
||||||
CharKind, DisplayPoint,
|
DisplayPoint,
|
||||||
};
|
};
|
||||||
use gpui::WindowContext;
|
use gpui::WindowContext;
|
||||||
use language::Selection;
|
use language::{char_kind, CharKind, Selection};
|
||||||
|
|
||||||
pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
|
pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
|
||||||
// Some motions ignore failure when switching to normal mode
|
// Some motions ignore failure when switching to normal mode
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{motion::Motion, object::Object, utils::copy_selections_content, Vim};
|
use crate::{motion::Motion, object::Object, utils::copy_selections_content, Vim};
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Bias};
|
use editor::{display_map::ToDisplayPoint, scroll::Autoscroll, Bias};
|
||||||
use gpui::WindowContext;
|
use gpui::WindowContext;
|
||||||
use language::Point;
|
use language::Point;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use editor::{scroll::autoscroll::Autoscroll, MultiBufferSnapshot, ToOffset, ToPoint};
|
use editor::{scroll::Autoscroll, MultiBufferSnapshot, ToOffset, ToPoint};
|
||||||
use gpui::{impl_actions, ViewContext, WindowContext};
|
use gpui::{impl_actions, ViewContext, WindowContext};
|
||||||
use language::{Bias, Point};
|
use language::{Bias, Point};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use std::{borrow::Cow, cmp};
|
use std::{borrow::Cow, cmp};
|
||||||
|
|
||||||
use editor::{
|
use editor::{
|
||||||
display_map::ToDisplayPoint, movement, scroll::autoscroll::Autoscroll, ClipboardSelection,
|
display_map::ToDisplayPoint, movement, scroll::Autoscroll, ClipboardSelection, DisplayPoint,
|
||||||
DisplayPoint,
|
|
||||||
};
|
};
|
||||||
use gpui::{impl_actions, ViewContext};
|
use gpui::{impl_actions, ViewContext};
|
||||||
use language::{Bias, SelectionGoal};
|
use language::{Bias, SelectionGoal};
|
||||||
|
@ -12,7 +12,7 @@ actions!(vim, [Repeat, EndRepeat]);
|
|||||||
|
|
||||||
fn should_replay(action: &Box<dyn Action>) -> bool {
|
fn should_replay(action: &Box<dyn Action>) -> bool {
|
||||||
// skip so that we don't leave the character palette open
|
// skip so that we don't leave the character palette open
|
||||||
if editor::ShowCharacterPalette.partial_eq(&**action) {
|
if editor::actions::ShowCharacterPalette.partial_eq(&**action) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::Vim;
|
use crate::Vim;
|
||||||
use editor::{
|
use editor::{
|
||||||
display_map::ToDisplayPoint,
|
display_map::ToDisplayPoint,
|
||||||
scroll::{scroll_amount::ScrollAmount, VERTICAL_SCROLL_MARGIN},
|
scroll::{ScrollAmount, VERTICAL_SCROLL_MARGIN},
|
||||||
DisplayPoint, Editor,
|
DisplayPoint, Editor,
|
||||||
};
|
};
|
||||||
use gpui::{actions, ViewContext};
|
use gpui::{actions, ViewContext};
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use editor::{
|
use editor::{
|
||||||
char_kind,
|
|
||||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||||
movement::{self, FindRange},
|
movement::{self, FindRange},
|
||||||
Bias, CharKind, DisplayPoint,
|
Bias, DisplayPoint,
|
||||||
};
|
};
|
||||||
use gpui::{actions, impl_actions, ViewContext, WindowContext};
|
use gpui::{actions, impl_actions, ViewContext, WindowContext};
|
||||||
use language::Selection;
|
use language::{char_kind, CharKind, Selection};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use collections::HashMap;
|
|||||||
use editor::{
|
use editor::{
|
||||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||||
movement,
|
movement,
|
||||||
scroll::autoscroll::Autoscroll,
|
scroll::Autoscroll,
|
||||||
Bias, DisplayPoint, Editor,
|
Bias, DisplayPoint, Editor,
|
||||||
};
|
};
|
||||||
use gpui::{actions, ViewContext, WindowContext};
|
use gpui::{actions, ViewContext, WindowContext};
|
||||||
|
@ -53,39 +53,46 @@ pub fn app_menus() -> Vec<Menu<'static>> {
|
|||||||
Menu {
|
Menu {
|
||||||
name: "Edit",
|
name: "Edit",
|
||||||
items: vec![
|
items: vec![
|
||||||
MenuItem::os_action("Undo", editor::Undo, OsAction::Undo),
|
MenuItem::os_action("Undo", editor::actions::Undo, OsAction::Undo),
|
||||||
MenuItem::os_action("Redo", editor::Redo, OsAction::Redo),
|
MenuItem::os_action("Redo", editor::actions::Redo, OsAction::Redo),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
MenuItem::os_action("Cut", editor::Cut, OsAction::Cut),
|
MenuItem::os_action("Cut", editor::actions::Cut, OsAction::Cut),
|
||||||
MenuItem::os_action("Copy", editor::Copy, OsAction::Copy),
|
MenuItem::os_action("Copy", editor::actions::Copy, OsAction::Copy),
|
||||||
MenuItem::os_action("Paste", editor::Paste, OsAction::Paste),
|
MenuItem::os_action("Paste", editor::actions::Paste, OsAction::Paste),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
MenuItem::action("Find", search::buffer_search::Deploy { focus: true }),
|
MenuItem::action("Find", search::buffer_search::Deploy { focus: true }),
|
||||||
MenuItem::action("Find In Project", workspace::NewSearch),
|
MenuItem::action("Find In Project", workspace::NewSearch),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
MenuItem::action("Toggle Line Comment", editor::ToggleComments::default()),
|
MenuItem::action(
|
||||||
MenuItem::action("Emoji & Symbols", editor::ShowCharacterPalette),
|
"Toggle Line Comment",
|
||||||
|
editor::actions::ToggleComments::default(),
|
||||||
|
),
|
||||||
|
MenuItem::action("Emoji & Symbols", editor::actions::ShowCharacterPalette),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Menu {
|
Menu {
|
||||||
name: "Selection",
|
name: "Selection",
|
||||||
items: vec![
|
items: vec![
|
||||||
MenuItem::os_action("Select All", editor::SelectAll, OsAction::SelectAll),
|
MenuItem::os_action(
|
||||||
MenuItem::action("Expand Selection", editor::SelectLargerSyntaxNode),
|
"Select All",
|
||||||
MenuItem::action("Shrink Selection", editor::SelectSmallerSyntaxNode),
|
editor::actions::SelectAll,
|
||||||
|
OsAction::SelectAll,
|
||||||
|
),
|
||||||
|
MenuItem::action("Expand Selection", editor::actions::SelectLargerSyntaxNode),
|
||||||
|
MenuItem::action("Shrink Selection", editor::actions::SelectSmallerSyntaxNode),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
MenuItem::action("Add Cursor Above", editor::AddSelectionAbove),
|
MenuItem::action("Add Cursor Above", editor::actions::AddSelectionAbove),
|
||||||
MenuItem::action("Add Cursor Below", editor::AddSelectionBelow),
|
MenuItem::action("Add Cursor Below", editor::actions::AddSelectionBelow),
|
||||||
MenuItem::action(
|
MenuItem::action(
|
||||||
"Select Next Occurrence",
|
"Select Next Occurrence",
|
||||||
editor::SelectNext {
|
editor::actions::SelectNext {
|
||||||
replace_newest: false,
|
replace_newest: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
MenuItem::action("Move Line Up", editor::MoveLineUp),
|
MenuItem::action("Move Line Up", editor::actions::MoveLineUp),
|
||||||
MenuItem::action("Move Line Down", editor::MoveLineDown),
|
MenuItem::action("Move Line Down", editor::actions::MoveLineDown),
|
||||||
MenuItem::action("Duplicate Selection", editor::DuplicateLine),
|
MenuItem::action("Duplicate Selection", editor::actions::DuplicateLine),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Menu {
|
Menu {
|
||||||
@ -124,13 +131,13 @@ pub fn app_menus() -> Vec<Menu<'static>> {
|
|||||||
MenuItem::action("Go to File", file_finder::Toggle),
|
MenuItem::action("Go to File", file_finder::Toggle),
|
||||||
// MenuItem::action("Go to Symbol in Project", project_symbols::Toggle),
|
// MenuItem::action("Go to Symbol in Project", project_symbols::Toggle),
|
||||||
MenuItem::action("Go to Symbol in Editor", outline::Toggle),
|
MenuItem::action("Go to Symbol in Editor", outline::Toggle),
|
||||||
MenuItem::action("Go to Definition", editor::GoToDefinition),
|
MenuItem::action("Go to Definition", editor::actions::GoToDefinition),
|
||||||
MenuItem::action("Go to Type Definition", editor::GoToTypeDefinition),
|
MenuItem::action("Go to Type Definition", editor::actions::GoToTypeDefinition),
|
||||||
MenuItem::action("Find All References", editor::FindAllReferences),
|
MenuItem::action("Find All References", editor::actions::FindAllReferences),
|
||||||
MenuItem::action("Go to Line/Column", go_to_line::Toggle),
|
MenuItem::action("Go to Line/Column", go_to_line::Toggle),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
MenuItem::action("Next Problem", editor::GoToDiagnostic),
|
MenuItem::action("Next Problem", editor::actions::GoToDiagnostic),
|
||||||
MenuItem::action("Previous Problem", editor::GoToPrevDiagnostic),
|
MenuItem::action("Previous Problem", editor::actions::GoToPrevDiagnostic),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Menu {
|
Menu {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use cli::{ipc, IpcHandshake};
|
use cli::{ipc, IpcHandshake};
|
||||||
use cli::{ipc::IpcSender, CliRequest, CliResponse};
|
use cli::{ipc::IpcSender, CliRequest, CliResponse};
|
||||||
use editor::scroll::autoscroll::Autoscroll;
|
use editor::scroll::Autoscroll;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
||||||
use futures::channel::{mpsc, oneshot};
|
use futures::channel::{mpsc, oneshot};
|
||||||
|
@ -730,7 +730,7 @@ fn open_bundled_file(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor, EditorEvent};
|
use editor::{scroll::Autoscroll, DisplayPoint, Editor, EditorEvent};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, Action, AnyWindowHandle, AppContext, AssetSource, Entity, TestAppContext,
|
actions, Action, AnyWindowHandle, AppContext, AssetSource, Entity, TestAppContext,
|
||||||
VisualTestContext, WindowHandle,
|
VisualTestContext, WindowHandle,
|
||||||
|
Loading…
Reference in New Issue
Block a user