Detailed changes
@@ -578,12 +578,7 @@ impl DisplaySnapshot {
line.push_str(chunk.chunk);
let text_style = if let Some(style) = chunk.style {
- editor_style
- .text
- .clone()
- .highlight(style)
- .map(Cow::Owned)
- .unwrap_or_else(|_| Cow::Borrowed(&editor_style.text))
+ Cow::Owned(editor_style.text.clone().highlight(style))
} else {
Cow::Borrowed(&editor_style.text)
};
@@ -2,7 +2,7 @@ use super::{
wrap_map::{self, WrapEdit, WrapPoint, WrapSnapshot},
Highlights,
};
-use crate::{Anchor, Editor, ExcerptId, ExcerptRange, ToPoint as _};
+use crate::{Anchor, Editor, EditorStyle, ExcerptId, ExcerptRange, ToPoint as _};
use collections::{Bound, HashMap, HashSet};
use gpui::{AnyElement, Pixels, ViewContext};
use language::{BufferSnapshot, Chunk, Patch, Point};
@@ -88,6 +88,7 @@ pub struct BlockContext<'a, 'b> {
pub em_width: Pixels,
pub line_height: Pixels,
pub block_id: usize,
+ pub editor_style: &'b EditorStyle,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -39,12 +39,12 @@ use futures::FutureExt;
use fuzzy::{StringMatch, StringMatchCandidate};
use git::diff_hunk_to_display;
use gpui::{
- action, actions, div, point, prelude::*, px, relative, rems, size, uniform_list, AnyElement,
- AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Component, Context,
- EventEmitter, FocusHandle, FontFeatures, FontStyle, FontWeight, HighlightStyle, Hsla,
- InputHandler, KeyContext, Model, MouseButton, ParentComponent, Pixels, Render, Styled,
- Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext,
- WeakView, WindowContext,
+ action, actions, div, point, prelude::*, px, relative, rems, render_view, size, uniform_list,
+ AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem,
+ Component, Context, EventEmitter, FocusHandle, FontFeatures, FontStyle, FontWeight,
+ HighlightStyle, Hsla, InputHandler, KeyContext, Model, MouseButton, ParentComponent, Pixels,
+ Render, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext,
+ VisualContext, WeakView, WindowContext,
};
use highlight_matching_bracket::refresh_matching_bracket_highlights;
use hover_popover::{hide_hover, HoverState};
@@ -100,7 +100,9 @@ use theme::{
use ui::{v_stack, HighlightedLabel, IconButton, StyledExt, TextTooltip};
use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
use workspace::{
- item::ItemEvent, searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace,
+ item::{ItemEvent, ItemHandle},
+ searchable::SearchEvent,
+ ItemNavHistory, SplitDirection, ViewId, Workspace,
};
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
@@ -1878,10 +1880,8 @@ impl Editor {
);
let focus_handle = cx.focus_handle();
- cx.on_focus_in(&focus_handle, Self::handle_focus_in)
- .detach();
- cx.on_focus_out(&focus_handle, Self::handle_focus_out)
- .detach();
+ cx.on_focus(&focus_handle, Self::handle_focus).detach();
+ cx.on_blur(&focus_handle, Self::handle_blur).detach();
let mut this = Self {
handle: cx.view().downgrade(),
@@ -7690,183 +7690,210 @@ impl Editor {
}
}
- // pub fn rename(&mut self, _: &Rename, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
- // use language::ToOffset as _;
+ pub fn rename(&mut self, _: &Rename, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
+ use language::ToOffset as _;
- // let project = self.project.clone()?;
- // let selection = self.selections.newest_anchor().clone();
- // let (cursor_buffer, cursor_buffer_position) = self
- // .buffer
- // .read(cx)
- // .text_anchor_for_position(selection.head(), cx)?;
- // let (tail_buffer, _) = self
- // .buffer
- // .read(cx)
- // .text_anchor_for_position(selection.tail(), cx)?;
- // if tail_buffer != cursor_buffer {
- // return None;
- // }
+ let project = self.project.clone()?;
+ let selection = self.selections.newest_anchor().clone();
+ let (cursor_buffer, cursor_buffer_position) = self
+ .buffer
+ .read(cx)
+ .text_anchor_for_position(selection.head(), cx)?;
+ let (tail_buffer, _) = self
+ .buffer
+ .read(cx)
+ .text_anchor_for_position(selection.tail(), cx)?;
+ if tail_buffer != cursor_buffer {
+ return None;
+ }
- // let snapshot = cursor_buffer.read(cx).snapshot();
- // let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot);
- // let prepare_rename = project.update(cx, |project, cx| {
- // project.prepare_rename(cursor_buffer, cursor_buffer_offset, cx)
- // });
+ let snapshot = cursor_buffer.read(cx).snapshot();
+ let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot);
+ let prepare_rename = project.update(cx, |project, cx| {
+ project.prepare_rename(cursor_buffer, cursor_buffer_offset, cx)
+ });
- // Some(cx.spawn(|this, mut cx| async move {
- // let rename_range = if let Some(range) = prepare_rename.await? {
- // Some(range)
- // } else {
- // this.update(&mut cx, |this, cx| {
- // let buffer = this.buffer.read(cx).snapshot(cx);
- // let mut buffer_highlights = this
- // .document_highlights_for_position(selection.head(), &buffer)
- // .filter(|highlight| {
- // highlight.start.excerpt_id == selection.head().excerpt_id
- // && highlight.end.excerpt_id == selection.head().excerpt_id
- // });
- // buffer_highlights
- // .next()
- // .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor)
- // })?
- // };
- // if let Some(rename_range) = rename_range {
- // let rename_buffer_range = rename_range.to_offset(&snapshot);
- // let cursor_offset_in_rename_range =
- // cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
-
- // this.update(&mut cx, |this, cx| {
- // this.take_rename(false, cx);
- // let buffer = this.buffer.read(cx).read(cx);
- // let cursor_offset = selection.head().to_offset(&buffer);
- // let rename_start = cursor_offset.saturating_sub(cursor_offset_in_rename_range);
- // let rename_end = rename_start + rename_buffer_range.len();
- // let range = buffer.anchor_before(rename_start)..buffer.anchor_after(rename_end);
- // let mut old_highlight_id = None;
- // let old_name: Arc<str> = buffer
- // .chunks(rename_start..rename_end, true)
- // .map(|chunk| {
- // if old_highlight_id.is_none() {
- // old_highlight_id = chunk.syntax_highlight_id;
- // }
- // chunk.text
- // })
- // .collect::<String>()
- // .into();
-
- // drop(buffer);
-
- // // Position the selection in the rename editor so that it matches the current selection.
- // this.show_local_selections = false;
- // let rename_editor = cx.build_view(|cx| {
- // let mut editor = Editor::single_line(cx);
- // if let Some(old_highlight_id) = old_highlight_id {
- // editor.override_text_style =
- // Some(Box::new(move |style| old_highlight_id.style(&style.syntax)));
- // }
- // editor.buffer.update(cx, |buffer, cx| {
- // buffer.edit([(0..0, old_name.clone())], None, cx)
- // });
- // editor.select_all(&SelectAll, cx);
- // editor
- // });
+ Some(cx.spawn(|this, mut cx| async move {
+ let rename_range = if let Some(range) = prepare_rename.await? {
+ Some(range)
+ } else {
+ this.update(&mut cx, |this, cx| {
+ let buffer = this.buffer.read(cx).snapshot(cx);
+ let mut buffer_highlights = this
+ .document_highlights_for_position(selection.head(), &buffer)
+ .filter(|highlight| {
+ highlight.start.excerpt_id == selection.head().excerpt_id
+ && highlight.end.excerpt_id == selection.head().excerpt_id
+ });
+ buffer_highlights
+ .next()
+ .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor)
+ })?
+ };
+ if let Some(rename_range) = rename_range {
+ let rename_buffer_range = rename_range.to_offset(&snapshot);
+ let cursor_offset_in_rename_range =
+ cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
- // let ranges = this
- // .clear_background_highlights::<DocumentHighlightWrite>(cx)
- // .into_iter()
- // .flat_map(|(_, ranges)| ranges.into_iter())
- // .chain(
- // this.clear_background_highlights::<DocumentHighlightRead>(cx)
- // .into_iter()
- // .flat_map(|(_, ranges)| ranges.into_iter()),
- // )
- // .collect();
-
- // this.highlight_text::<Rename>(
- // ranges,
- // HighlightStyle {
- // fade_out: Some(style.rename_fade),
- // ..Default::default()
- // },
- // cx,
- // );
- // cx.focus(&rename_editor);
- // let block_id = this.insert_blocks(
- // [BlockProperties {
- // style: BlockStyle::Flex,
- // position: range.start.clone(),
- // height: 1,
- // render: Arc::new({
- // let editor = rename_editor.clone();
- // move |cx: &mut BlockContext| {
- // ChildView::new(&editor, cx)
- // .contained()
- // .with_padding_left(cx.anchor_x)
- // .into_any()
- // }
- // }),
- // disposition: BlockDisposition::Below,
- // }],
- // Some(Autoscroll::fit()),
- // cx,
- // )[0];
- // this.pending_rename = Some(RenameState {
- // range,
- // old_name,
- // editor: rename_editor,
- // block_id,
- // });
- // })?;
- // }
+ this.update(&mut cx, |this, cx| {
+ this.take_rename(false, cx);
+ let buffer = this.buffer.read(cx).read(cx);
+ let cursor_offset = selection.head().to_offset(&buffer);
+ let rename_start = cursor_offset.saturating_sub(cursor_offset_in_rename_range);
+ let rename_end = rename_start + rename_buffer_range.len();
+ let range = buffer.anchor_before(rename_start)..buffer.anchor_after(rename_end);
+ let mut old_highlight_id = None;
+ let old_name: Arc<str> = buffer
+ .chunks(rename_start..rename_end, true)
+ .map(|chunk| {
+ if old_highlight_id.is_none() {
+ old_highlight_id = chunk.syntax_highlight_id;
+ }
+ chunk.text
+ })
+ .collect::<String>()
+ .into();
- // Ok(())
- // }))
- // }
+ drop(buffer);
- // pub fn confirm_rename(
- // workspace: &mut Workspace,
- // _: &ConfirmRename,
- // cx: &mut ViewContext<Workspace>,
- // ) -> Option<Task<Result<()>>> {
- // let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?;
-
- // let (buffer, range, old_name, new_name) = editor.update(cx, |editor, cx| {
- // let rename = editor.take_rename(false, cx)?;
- // let buffer = editor.buffer.read(cx);
- // let (start_buffer, start) =
- // buffer.text_anchor_for_position(rename.range.start.clone(), cx)?;
- // let (end_buffer, end) =
- // buffer.text_anchor_for_position(rename.range.end.clone(), cx)?;
- // if start_buffer == end_buffer {
- // let new_name = rename.editor.read(cx).text(cx);
- // Some((start_buffer, start..end, rename.old_name, new_name))
- // } else {
- // None
- // }
- // })?;
+ // Position the selection in the rename editor so that it matches the current selection.
+ this.show_local_selections = false;
+ let rename_editor = cx.build_view(|cx| {
+ let mut editor = Editor::single_line(cx);
+ editor.buffer.update(cx, |buffer, cx| {
+ buffer.edit([(0..0, old_name.clone())], None, cx)
+ });
+ editor.select_all(&SelectAll, cx);
+ editor
+ });
- // let rename = workspace.project().clone().update(cx, |project, cx| {
- // project.perform_rename(buffer.clone(), range.start, new_name.clone(), true, cx)
- // });
+ let ranges = this
+ .clear_background_highlights::<DocumentHighlightWrite>(cx)
+ .into_iter()
+ .flat_map(|(_, ranges)| ranges.into_iter())
+ .chain(
+ this.clear_background_highlights::<DocumentHighlightRead>(cx)
+ .into_iter()
+ .flat_map(|(_, ranges)| ranges.into_iter()),
+ )
+ .collect();
- // let editor = editor.downgrade();
- // Some(cx.spawn(|workspace, mut cx| async move {
- // let project_transaction = rename.await?;
- // Self::open_project_transaction(
- // &editor,
- // workspace,
- // project_transaction,
- // format!("Rename: {} → {}", old_name, new_name),
- // cx.clone(),
- // )
- // .await?;
+ this.highlight_text::<Rename>(
+ ranges,
+ HighlightStyle {
+ fade_out: Some(0.6),
+ ..Default::default()
+ },
+ cx,
+ );
+ let rename_focus_handle = rename_editor.focus_handle(cx);
+ cx.focus(&rename_focus_handle);
+ let block_id = this.insert_blocks(
+ [BlockProperties {
+ style: BlockStyle::Flex,
+ position: range.start.clone(),
+ height: 1,
+ render: Arc::new({
+ let rename_editor = rename_editor.clone();
+ move |cx: &mut BlockContext| {
+ let mut text_style = cx.editor_style.text.clone();
+ if let Some(highlight_style) = old_highlight_id
+ .and_then(|h| h.style(&cx.editor_style.syntax))
+ {
+ text_style = text_style.highlight(highlight_style);
+ }
+ div()
+ .pl(cx.anchor_x)
+ .child(render_view(
+ &rename_editor,
+ EditorElement::new(
+ &rename_editor,
+ EditorStyle {
+ background: cx.theme().system().transparent,
+ local_player: cx.editor_style.local_player,
+ text: text_style,
+ scrollbar_width: cx
+ .editor_style
+ .scrollbar_width,
+ syntax: cx.editor_style.syntax.clone(),
+ diagnostic_style: cx
+ .editor_style
+ .diagnostic_style
+ .clone(),
+ },
+ ),
+ ))
+ .render()
+ }
+ }),
+ disposition: BlockDisposition::Below,
+ }],
+ Some(Autoscroll::fit()),
+ cx,
+ )[0];
+ this.pending_rename = Some(RenameState {
+ range,
+ old_name,
+ editor: rename_editor,
+ block_id,
+ });
+ })?;
+ }
- // editor.update(&mut cx, |editor, cx| {
- // editor.refresh_document_highlights(cx);
- // })?;
- // Ok(())
- // }))
- // }
+ Ok(())
+ }))
+ }
+
+ pub fn confirm_rename(
+ &mut self,
+ _: &ConfirmRename,
+ cx: &mut ViewContext<Self>,
+ ) -> Option<Task<Result<()>>> {
+ let rename = self.take_rename(false, cx)?;
+ let workspace = self.workspace()?;
+ let (start_buffer, start) = self
+ .buffer
+ .read(cx)
+ .text_anchor_for_position(rename.range.start.clone(), cx)?;
+ let (end_buffer, end) = self
+ .buffer
+ .read(cx)
+ .text_anchor_for_position(rename.range.end.clone(), cx)?;
+ if start_buffer != end_buffer {
+ return None;
+ }
+
+ let buffer = start_buffer;
+ let range = start..end;
+ let old_name = rename.old_name;
+ let new_name = rename.editor.read(cx).text(cx);
+
+ let rename = workspace
+ .read(cx)
+ .project()
+ .clone()
+ .update(cx, |project, cx| {
+ project.perform_rename(buffer.clone(), range.start, new_name.clone(), true, cx)
+ });
+ let workspace = workspace.downgrade();
+
+ Some(cx.spawn(|editor, mut cx| async move {
+ let project_transaction = rename.await?;
+ Self::open_project_transaction(
+ &editor,
+ workspace,
+ project_transaction,
+ format!("Rename: {} → {}", old_name, new_name),
+ cx.clone(),
+ )
+ .await?;
+
+ editor.update(&mut cx, |editor, cx| {
+ editor.refresh_document_highlights(cx);
+ })?;
+ Ok(())
+ }))
+ }
fn take_rename(
&mut self,
@@ -7874,6 +7901,10 @@ impl Editor {
cx: &mut ViewContext<Self>,
) -> Option<RenameState> {
let rename = self.pending_rename.take()?;
+ if rename.editor.focus_handle(cx).is_focused(cx) {
+ cx.focus(&self.focus_handle);
+ }
+
self.remove_blocks(
[rename.block_id].into_iter().collect(),
Some(Autoscroll::fit()),
@@ -9172,17 +9203,13 @@ impl Editor {
self.focus_handle.is_focused(cx)
}
- fn handle_focus_in(&mut self, cx: &mut ViewContext<Self>) {
- if self.focus_handle.is_focused(cx) {
- // todo!()
- // let focused_event = EditorFocused(cx.handle());
- // cx.emit_global(focused_event);
- cx.emit(Event::Focused);
- }
+ fn handle_focus(&mut self, cx: &mut ViewContext<Self>) {
+ cx.emit(Event::Focused);
+
if let Some(rename) = self.pending_rename.as_ref() {
let rename_editor_focus_handle = rename.editor.read(cx).focus_handle.clone();
cx.focus(&rename_editor_focus_handle);
- } else if self.focus_handle.is_focused(cx) {
+ } else {
self.blink_manager.update(cx, BlinkManager::enable);
self.buffer.update(cx, |buffer, cx| {
buffer.finalize_last_transaction(cx);
@@ -9198,7 +9225,7 @@ impl Editor {
}
}
- fn handle_focus_out(&mut self, cx: &mut ViewContext<Self>) {
+ fn handle_blur(&mut self, cx: &mut ViewContext<Self>) {
// todo!()
// let blurred_event = EditorBlurred(cx.handle());
// cx.emit_global(blurred_event);
@@ -2012,10 +2012,10 @@ impl EditorElement {
anchor_x,
gutter_padding,
line_height,
- // scroll_x,
gutter_width,
em_width,
block_id,
+ editor_style: &self.style,
})
}
TransformBlock::ExcerptHeader {
@@ -2258,11 +2258,7 @@ impl LineWithInvisibles {
if !line_chunk.is_empty() && !line_exceeded_max_len {
let text_style = if let Some(style) = highlighted_chunk.style {
- text_style
- .clone()
- .highlight(style)
- .map(Cow::Owned)
- .unwrap_or_else(|_| Cow::Borrowed(text_style))
+ Cow::Owned(text_style.clone().highlight(style))
} else {
Cow::Borrowed(text_style)
};
@@ -2460,168 +2456,7 @@ impl Element<Editor> for EditorElement {
dispatch_context,
Some(editor.focus_handle.clone()),
|_, cx| {
- register_action(cx, Editor::move_left);
- register_action(cx, Editor::move_right);
- register_action(cx, Editor::move_down);
- register_action(cx, Editor::move_up);
- // on_action(cx, Editor::new_file); todo!()
- // on_action(cx, Editor::new_file_in_direction); todo!()
- register_action(cx, Editor::cancel);
- register_action(cx, Editor::newline);
- register_action(cx, Editor::newline_above);
- register_action(cx, Editor::newline_below);
- register_action(cx, Editor::backspace);
- register_action(cx, Editor::delete);
- register_action(cx, Editor::tab);
- register_action(cx, Editor::tab_prev);
- register_action(cx, Editor::indent);
- register_action(cx, Editor::outdent);
- register_action(cx, Editor::delete_line);
- register_action(cx, Editor::join_lines);
- register_action(cx, Editor::sort_lines_case_sensitive);
- register_action(cx, Editor::sort_lines_case_insensitive);
- register_action(cx, Editor::reverse_lines);
- register_action(cx, Editor::shuffle_lines);
- register_action(cx, Editor::convert_to_upper_case);
- register_action(cx, Editor::convert_to_lower_case);
- register_action(cx, Editor::convert_to_title_case);
- register_action(cx, Editor::convert_to_snake_case);
- register_action(cx, Editor::convert_to_kebab_case);
- register_action(cx, Editor::convert_to_upper_camel_case);
- register_action(cx, Editor::convert_to_lower_camel_case);
- register_action(cx, Editor::delete_to_previous_word_start);
- register_action(cx, Editor::delete_to_previous_subword_start);
- register_action(cx, Editor::delete_to_next_word_end);
- register_action(cx, Editor::delete_to_next_subword_end);
- register_action(cx, Editor::delete_to_beginning_of_line);
- register_action(cx, Editor::delete_to_end_of_line);
- register_action(cx, Editor::cut_to_end_of_line);
- register_action(cx, Editor::duplicate_line);
- register_action(cx, Editor::move_line_up);
- register_action(cx, Editor::move_line_down);
- register_action(cx, Editor::transpose);
- register_action(cx, Editor::cut);
- register_action(cx, Editor::copy);
- register_action(cx, Editor::paste);
- register_action(cx, Editor::undo);
- register_action(cx, Editor::redo);
- register_action(cx, Editor::move_page_up);
- register_action(cx, Editor::move_page_down);
- register_action(cx, Editor::next_screen);
- register_action(cx, Editor::scroll_cursor_top);
- register_action(cx, Editor::scroll_cursor_center);
- register_action(cx, Editor::scroll_cursor_bottom);
- register_action(cx, |editor, _: &LineDown, cx| {
- editor.scroll_screen(&ScrollAmount::Line(1.), cx)
- });
- register_action(cx, |editor, _: &LineUp, cx| {
- editor.scroll_screen(&ScrollAmount::Line(-1.), cx)
- });
- register_action(cx, |editor, _: &HalfPageDown, cx| {
- editor.scroll_screen(&ScrollAmount::Page(0.5), cx)
- });
- register_action(cx, |editor, _: &HalfPageUp, cx| {
- editor.scroll_screen(&ScrollAmount::Page(-0.5), cx)
- });
- register_action(cx, |editor, _: &PageDown, cx| {
- editor.scroll_screen(&ScrollAmount::Page(1.), cx)
- });
- register_action(cx, |editor, _: &PageUp, cx| {
- editor.scroll_screen(&ScrollAmount::Page(-1.), cx)
- });
- register_action(cx, Editor::move_to_previous_word_start);
- register_action(cx, Editor::move_to_previous_subword_start);
- register_action(cx, Editor::move_to_next_word_end);
- register_action(cx, Editor::move_to_next_subword_end);
- register_action(cx, Editor::move_to_beginning_of_line);
- register_action(cx, Editor::move_to_end_of_line);
- register_action(cx, Editor::move_to_start_of_paragraph);
- register_action(cx, Editor::move_to_end_of_paragraph);
- register_action(cx, Editor::move_to_beginning);
- register_action(cx, Editor::move_to_end);
- register_action(cx, Editor::select_up);
- register_action(cx, Editor::select_down);
- register_action(cx, Editor::select_left);
- register_action(cx, Editor::select_right);
- register_action(cx, Editor::select_to_previous_word_start);
- register_action(cx, Editor::select_to_previous_subword_start);
- register_action(cx, Editor::select_to_next_word_end);
- register_action(cx, Editor::select_to_next_subword_end);
- register_action(cx, Editor::select_to_beginning_of_line);
- register_action(cx, Editor::select_to_end_of_line);
- register_action(cx, Editor::select_to_start_of_paragraph);
- register_action(cx, Editor::select_to_end_of_paragraph);
- register_action(cx, Editor::select_to_beginning);
- register_action(cx, Editor::select_to_end);
- register_action(cx, Editor::select_all);
- register_action(cx, |editor, action, cx| {
- editor.select_all_matches(action, cx).log_err();
- });
- register_action(cx, Editor::select_line);
- register_action(cx, Editor::split_selection_into_lines);
- register_action(cx, Editor::add_selection_above);
- register_action(cx, Editor::add_selection_below);
- register_action(cx, |editor, action, cx| {
- editor.select_next(action, cx).log_err();
- });
- register_action(cx, |editor, action, cx| {
- editor.select_previous(action, cx).log_err();
- });
- register_action(cx, Editor::toggle_comments);
- register_action(cx, Editor::select_larger_syntax_node);
- register_action(cx, Editor::select_smaller_syntax_node);
- register_action(cx, Editor::move_to_enclosing_bracket);
- register_action(cx, Editor::undo_selection);
- register_action(cx, Editor::redo_selection);
- register_action(cx, Editor::go_to_diagnostic);
- register_action(cx, Editor::go_to_prev_diagnostic);
- register_action(cx, Editor::go_to_hunk);
- register_action(cx, Editor::go_to_prev_hunk);
- register_action(cx, Editor::go_to_definition);
- register_action(cx, Editor::go_to_definition_split);
- register_action(cx, Editor::go_to_type_definition);
- register_action(cx, Editor::go_to_type_definition_split);
- register_action(cx, Editor::fold);
- register_action(cx, Editor::fold_at);
- register_action(cx, Editor::unfold_lines);
- register_action(cx, Editor::unfold_at);
- register_action(cx, Editor::fold_selected_ranges);
- register_action(cx, Editor::show_completions);
- register_action(cx, Editor::toggle_code_actions);
- // on_action(cx, Editor::open_excerpts); todo!()
- register_action(cx, Editor::toggle_soft_wrap);
- register_action(cx, Editor::toggle_inlay_hints);
- register_action(cx, Editor::reveal_in_finder);
- register_action(cx, Editor::copy_path);
- register_action(cx, Editor::copy_relative_path);
- register_action(cx, Editor::copy_highlight_json);
- register_action(cx, |editor, action, cx| {
- editor
- .format(action, cx)
- .map(|task| task.detach_and_log_err(cx));
- });
- register_action(cx, Editor::restart_language_server);
- register_action(cx, Editor::show_character_palette);
- // on_action(cx, Editor::confirm_completion); todo!()
- register_action(cx, |editor, action, cx| {
- editor
- .confirm_code_action(action, cx)
- .map(|task| task.detach_and_log_err(cx));
- });
- // on_action(cx, Editor::rename); todo!()
- // on_action(cx, Editor::confirm_rename); todo!()
- register_action(cx, |editor, action, cx| {
- editor
- .find_all_references(action, cx)
- .map(|task| task.detach_and_log_err(cx));
- });
- register_action(cx, Editor::next_copilot_suggestion);
- register_action(cx, Editor::previous_copilot_suggestion);
- register_action(cx, Editor::copilot_suggest);
- register_action(cx, Editor::context_menu_first);
- register_action(cx, Editor::context_menu_prev);
- register_action(cx, Editor::context_menu_next);
- register_action(cx, Editor::context_menu_last);
+ register_actions(cx);
// We call with_z_index to establish a new stacking context.
cx.with_z_index(0, |cx| {
@@ -2652,6 +2487,12 @@ impl Element<Editor> for EditorElement {
}
}
+impl Component<Editor> for EditorElement {
+ fn render(self) -> AnyElement<Editor> {
+ AnyElement::new(self)
+ }
+}
+
// impl EditorElement {
// type LayoutState = LayoutState;
// type PaintState = ();
@@ -4128,6 +3969,179 @@ fn scale_horizontal_mouse_autoscroll_delta(delta: Pixels) -> f32 {
// }
// }
+fn register_actions(cx: &mut ViewContext<Editor>) {
+ register_action(cx, Editor::move_left);
+ register_action(cx, Editor::move_right);
+ register_action(cx, Editor::move_down);
+ register_action(cx, Editor::move_up);
+ // on_action(cx, Editor::new_file); todo!()
+ // on_action(cx, Editor::new_file_in_direction); todo!()
+ register_action(cx, Editor::cancel);
+ register_action(cx, Editor::newline);
+ register_action(cx, Editor::newline_above);
+ register_action(cx, Editor::newline_below);
+ register_action(cx, Editor::backspace);
+ register_action(cx, Editor::delete);
+ register_action(cx, Editor::tab);
+ register_action(cx, Editor::tab_prev);
+ register_action(cx, Editor::indent);
+ register_action(cx, Editor::outdent);
+ register_action(cx, Editor::delete_line);
+ register_action(cx, Editor::join_lines);
+ register_action(cx, Editor::sort_lines_case_sensitive);
+ register_action(cx, Editor::sort_lines_case_insensitive);
+ register_action(cx, Editor::reverse_lines);
+ register_action(cx, Editor::shuffle_lines);
+ register_action(cx, Editor::convert_to_upper_case);
+ register_action(cx, Editor::convert_to_lower_case);
+ register_action(cx, Editor::convert_to_title_case);
+ register_action(cx, Editor::convert_to_snake_case);
+ register_action(cx, Editor::convert_to_kebab_case);
+ register_action(cx, Editor::convert_to_upper_camel_case);
+ register_action(cx, Editor::convert_to_lower_camel_case);
+ register_action(cx, Editor::delete_to_previous_word_start);
+ register_action(cx, Editor::delete_to_previous_subword_start);
+ register_action(cx, Editor::delete_to_next_word_end);
+ register_action(cx, Editor::delete_to_next_subword_end);
+ register_action(cx, Editor::delete_to_beginning_of_line);
+ register_action(cx, Editor::delete_to_end_of_line);
+ register_action(cx, Editor::cut_to_end_of_line);
+ register_action(cx, Editor::duplicate_line);
+ register_action(cx, Editor::move_line_up);
+ register_action(cx, Editor::move_line_down);
+ register_action(cx, Editor::transpose);
+ register_action(cx, Editor::cut);
+ register_action(cx, Editor::copy);
+ register_action(cx, Editor::paste);
+ register_action(cx, Editor::undo);
+ register_action(cx, Editor::redo);
+ register_action(cx, Editor::move_page_up);
+ register_action(cx, Editor::move_page_down);
+ register_action(cx, Editor::next_screen);
+ register_action(cx, Editor::scroll_cursor_top);
+ register_action(cx, Editor::scroll_cursor_center);
+ register_action(cx, Editor::scroll_cursor_bottom);
+ register_action(cx, |editor, _: &LineDown, cx| {
+ editor.scroll_screen(&ScrollAmount::Line(1.), cx)
+ });
+ register_action(cx, |editor, _: &LineUp, cx| {
+ editor.scroll_screen(&ScrollAmount::Line(-1.), cx)
+ });
+ register_action(cx, |editor, _: &HalfPageDown, cx| {
+ editor.scroll_screen(&ScrollAmount::Page(0.5), cx)
+ });
+ register_action(cx, |editor, _: &HalfPageUp, cx| {
+ editor.scroll_screen(&ScrollAmount::Page(-0.5), cx)
+ });
+ register_action(cx, |editor, _: &PageDown, cx| {
+ editor.scroll_screen(&ScrollAmount::Page(1.), cx)
+ });
+ register_action(cx, |editor, _: &PageUp, cx| {
+ editor.scroll_screen(&ScrollAmount::Page(-1.), cx)
+ });
+ register_action(cx, Editor::move_to_previous_word_start);
+ register_action(cx, Editor::move_to_previous_subword_start);
+ register_action(cx, Editor::move_to_next_word_end);
+ register_action(cx, Editor::move_to_next_subword_end);
+ register_action(cx, Editor::move_to_beginning_of_line);
+ register_action(cx, Editor::move_to_end_of_line);
+ register_action(cx, Editor::move_to_start_of_paragraph);
+ register_action(cx, Editor::move_to_end_of_paragraph);
+ register_action(cx, Editor::move_to_beginning);
+ register_action(cx, Editor::move_to_end);
+ register_action(cx, Editor::select_up);
+ register_action(cx, Editor::select_down);
+ register_action(cx, Editor::select_left);
+ register_action(cx, Editor::select_right);
+ register_action(cx, Editor::select_to_previous_word_start);
+ register_action(cx, Editor::select_to_previous_subword_start);
+ register_action(cx, Editor::select_to_next_word_end);
+ register_action(cx, Editor::select_to_next_subword_end);
+ register_action(cx, Editor::select_to_beginning_of_line);
+ register_action(cx, Editor::select_to_end_of_line);
+ register_action(cx, Editor::select_to_start_of_paragraph);
+ register_action(cx, Editor::select_to_end_of_paragraph);
+ register_action(cx, Editor::select_to_beginning);
+ register_action(cx, Editor::select_to_end);
+ register_action(cx, Editor::select_all);
+ register_action(cx, |editor, action, cx| {
+ editor.select_all_matches(action, cx).log_err();
+ });
+ register_action(cx, Editor::select_line);
+ register_action(cx, Editor::split_selection_into_lines);
+ register_action(cx, Editor::add_selection_above);
+ register_action(cx, Editor::add_selection_below);
+ register_action(cx, |editor, action, cx| {
+ editor.select_next(action, cx).log_err();
+ });
+ register_action(cx, |editor, action, cx| {
+ editor.select_previous(action, cx).log_err();
+ });
+ register_action(cx, Editor::toggle_comments);
+ register_action(cx, Editor::select_larger_syntax_node);
+ register_action(cx, Editor::select_smaller_syntax_node);
+ register_action(cx, Editor::move_to_enclosing_bracket);
+ register_action(cx, Editor::undo_selection);
+ register_action(cx, Editor::redo_selection);
+ register_action(cx, Editor::go_to_diagnostic);
+ register_action(cx, Editor::go_to_prev_diagnostic);
+ register_action(cx, Editor::go_to_hunk);
+ register_action(cx, Editor::go_to_prev_hunk);
+ register_action(cx, Editor::go_to_definition);
+ register_action(cx, Editor::go_to_definition_split);
+ register_action(cx, Editor::go_to_type_definition);
+ register_action(cx, Editor::go_to_type_definition_split);
+ register_action(cx, Editor::fold);
+ register_action(cx, Editor::fold_at);
+ register_action(cx, Editor::unfold_lines);
+ register_action(cx, Editor::unfold_at);
+ register_action(cx, Editor::fold_selected_ranges);
+ register_action(cx, Editor::show_completions);
+ register_action(cx, Editor::toggle_code_actions);
+ // on_action(cx, Editor::open_excerpts); todo!()
+ register_action(cx, Editor::toggle_soft_wrap);
+ register_action(cx, Editor::toggle_inlay_hints);
+ register_action(cx, Editor::reveal_in_finder);
+ register_action(cx, Editor::copy_path);
+ register_action(cx, Editor::copy_relative_path);
+ register_action(cx, Editor::copy_highlight_json);
+ register_action(cx, |editor, action, cx| {
+ editor
+ .format(action, cx)
+ .map(|task| task.detach_and_log_err(cx));
+ });
+ register_action(cx, Editor::restart_language_server);
+ register_action(cx, Editor::show_character_palette);
+ // on_action(cx, Editor::confirm_completion); todo!()
+ register_action(cx, |editor, action, cx| {
+ editor
+ .confirm_code_action(action, cx)
+ .map(|task| task.detach_and_log_err(cx));
+ });
+ register_action(cx, |editor, action, cx| {
+ editor
+ .rename(action, cx)
+ .map(|task| task.detach_and_log_err(cx));
+ });
+ register_action(cx, |editor, action, cx| {
+ editor
+ .confirm_rename(action, cx)
+ .map(|task| task.detach_and_log_err(cx));
+ });
+ register_action(cx, |editor, action, cx| {
+ editor
+ .find_all_references(action, cx)
+ .map(|task| task.detach_and_log_err(cx));
+ });
+ register_action(cx, Editor::next_copilot_suggestion);
+ register_action(cx, Editor::previous_copilot_suggestion);
+ register_action(cx, Editor::copilot_suggest);
+ register_action(cx, Editor::context_menu_first);
+ register_action(cx, Editor::context_menu_prev);
+ register_action(cx, Editor::context_menu_next);
+ register_action(cx, Editor::context_menu_last);
+}
+
fn register_action<T: Action>(
cx: &mut ViewContext<Editor>,
listener: impl Fn(&mut Editor, &T, &mut ViewContext<Editor>) + 'static,
@@ -1,8 +1,8 @@
use crate::{
black, phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask,
Corners, CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font,
- FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Result,
- Rgba, SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext,
+ FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba,
+ SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext,
};
use refineable::{Cascade, Refineable};
use smallvec::SmallVec;
@@ -157,7 +157,7 @@ impl Default for TextStyle {
}
impl TextStyle {
- pub fn highlight(mut self, style: HighlightStyle) -> Result<Self> {
+ pub fn highlight(mut self, style: HighlightStyle) -> Self {
if let Some(weight) = style.font_weight {
self.font_weight = weight;
}
@@ -177,7 +177,7 @@ impl TextStyle {
self.underline = Some(underline);
}
- Ok(self)
+ self
}
pub fn font(&self) -> Font {
@@ -1,7 +1,7 @@
use crate::{
private::Sealed, AnyBox, AnyElement, AnyModel, AnyWeakModel, AppContext, AvailableSpace,
- Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId, Model, Pixels,
- Size, ViewContext, VisualContext, WeakModel, WindowContext,
+ BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId,
+ Model, Pixels, Size, ViewContext, VisualContext, WeakModel, WindowContext,
};
use anyhow::{Context, Result};
use std::{
@@ -281,6 +281,84 @@ where
}
}
+pub struct RenderView<C, V> {
+ view: View<V>,
+ component: Option<C>,
+}
+
+impl<C, ParentViewState, ViewState> Component<ParentViewState> for RenderView<C, ViewState>
+where
+ C: 'static + Component<ViewState>,
+ ParentViewState: 'static,
+ ViewState: 'static,
+{
+ fn render(self) -> AnyElement<ParentViewState> {
+ AnyElement::new(self)
+ }
+}
+
+impl<C, ParentViewState, ViewState> Element<ParentViewState> for RenderView<C, ViewState>
+where
+ C: 'static + Component<ViewState>,
+ ParentViewState: 'static,
+ ViewState: 'static,
+{
+ type ElementState = AnyElement<ViewState>;
+
+ fn element_id(&self) -> Option<ElementId> {
+ Some(self.view.entity_id().into())
+ }
+
+ fn initialize(
+ &mut self,
+ _: &mut ParentViewState,
+ _: Option<Self::ElementState>,
+ cx: &mut ViewContext<ParentViewState>,
+ ) -> Self::ElementState {
+ cx.with_element_id(Some(self.view.entity_id()), |cx| {
+ self.view.update(cx, |view, cx| {
+ let mut element = self.component.take().unwrap().render();
+ element.initialize(view, cx);
+ element
+ })
+ })
+ }
+
+ fn layout(
+ &mut self,
+ _: &mut ParentViewState,
+ element: &mut Self::ElementState,
+ cx: &mut ViewContext<ParentViewState>,
+ ) -> LayoutId {
+ cx.with_element_id(Some(self.view.entity_id()), |cx| {
+ self.view.update(cx, |view, cx| element.layout(view, cx))
+ })
+ }
+
+ fn paint(
+ &mut self,
+ _: Bounds<Pixels>,
+ _: &mut ParentViewState,
+ element: &mut Self::ElementState,
+ cx: &mut ViewContext<ParentViewState>,
+ ) {
+ cx.with_element_id(Some(self.view.entity_id()), |cx| {
+ self.view.update(cx, |view, cx| element.paint(view, cx))
+ })
+ }
+}
+
+pub fn render_view<C, V>(view: &View<V>, component: C) -> RenderView<C, V>
+where
+ C: 'static + Component<V>,
+ V: 'static,
+{
+ RenderView {
+ view: view.clone(),
+ component: Some(component),
+ }
+}
+
mod any_view {
use crate::{AnyElement, AnyView, BorrowWindow, LayoutId, Render, WindowContext};
use std::any::Any;