mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
Use a block decoration for entering rename text
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
d705244210
commit
f0a6e8cb9c
@ -480,7 +480,9 @@ struct SnippetState {
|
||||
|
||||
struct RenameState {
|
||||
range: Range<Anchor>,
|
||||
first_transaction: Option<TransactionId>,
|
||||
old_name: String,
|
||||
editor: ViewHandle<Editor>,
|
||||
block_id: BlockId,
|
||||
}
|
||||
|
||||
struct InvalidationStack<T>(Vec<T>);
|
||||
@ -3161,6 +3163,26 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
|
||||
if let Some((range, column, _, _)) = self.take_rename(cx) {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let position = snapshot.clip_point(
|
||||
range.start.to_point(&snapshot) + Point::new(0, column),
|
||||
Bias::Left,
|
||||
);
|
||||
self.update_selections(
|
||||
vec![Selection {
|
||||
id: self.newest_anchor_selection().id,
|
||||
start: position,
|
||||
end: position,
|
||||
reversed: false,
|
||||
goal: SelectionGoal::None,
|
||||
}],
|
||||
None,
|
||||
cx,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(context_menu) = self.context_menu.as_mut() {
|
||||
if context_menu.select_prev(cx) {
|
||||
return;
|
||||
@ -4118,20 +4140,51 @@ impl Editor {
|
||||
let start = offset - lookbehind;
|
||||
let end = offset + lookahead;
|
||||
let rename_range = buffer.anchor_before(start)..buffer.anchor_after(end);
|
||||
let old_name = buffer.text_for_range(start..end).collect::<String>();
|
||||
drop(buffer);
|
||||
|
||||
this.buffer
|
||||
.update(cx, |buffer, cx| buffer.finalize_last_transaction(cx));
|
||||
this.pending_rename = Some(RenameState {
|
||||
range: rename_range.clone(),
|
||||
first_transaction: None,
|
||||
});
|
||||
this.select_ranges([start..end], None, cx);
|
||||
this.highlight_ranges::<Rename>(
|
||||
vec![rename_range],
|
||||
settings.style.highlighted_line_background,
|
||||
let editor = cx.add_view(|cx| {
|
||||
let mut editor = Editor::single_line(this.build_settings.clone(), cx);
|
||||
editor
|
||||
.buffer
|
||||
.update(cx, |buffer, cx| buffer.edit([0..0], &old_name, cx));
|
||||
editor.select_ranges([0..old_name.len()], None, cx);
|
||||
editor.highlight_ranges::<Rename>(
|
||||
vec![Anchor::min()..Anchor::max()],
|
||||
settings.style.diff_background_inserted,
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
});
|
||||
this.highlight_ranges::<Rename>(
|
||||
vec![rename_range.clone()],
|
||||
settings.style.diff_background_deleted,
|
||||
cx,
|
||||
);
|
||||
cx.focus(&editor);
|
||||
let block_id = this.insert_blocks(
|
||||
[BlockProperties {
|
||||
position: rename_range.start.clone(),
|
||||
height: 1,
|
||||
render: Arc::new({
|
||||
let editor = editor.clone();
|
||||
move |cx: &BlockContext| {
|
||||
ChildView::new(editor.clone())
|
||||
.contained()
|
||||
.with_padding_left(cx.anchor_x)
|
||||
.boxed()
|
||||
}
|
||||
}),
|
||||
disposition: BlockDisposition::Below,
|
||||
}],
|
||||
cx,
|
||||
)[0];
|
||||
this.pending_rename = Some(RenameState {
|
||||
range: rename_range,
|
||||
old_name,
|
||||
editor,
|
||||
block_id,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -4146,13 +4199,13 @@ impl Editor {
|
||||
) -> Option<Task<Result<()>>> {
|
||||
let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?;
|
||||
|
||||
let (buffer, range, new_name) = editor.update(cx, |editor, cx| {
|
||||
let (range, new_name) = editor.take_rename(cx)?;
|
||||
let (buffer, range, old_name, new_name) = editor.update(cx, |editor, cx| {
|
||||
let (range, _, old_name, new_name) = editor.take_rename(cx)?;
|
||||
let buffer = editor.buffer.read(cx);
|
||||
let (start_buffer, start) = buffer.text_anchor_for_position(range.start.clone(), cx)?;
|
||||
let (end_buffer, end) = buffer.text_anchor_for_position(range.end.clone(), cx)?;
|
||||
if start_buffer == end_buffer {
|
||||
Some((start_buffer, start..end, new_name))
|
||||
Some((start_buffer, start..end, old_name, new_name))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -4168,55 +4221,36 @@ impl Editor {
|
||||
)
|
||||
});
|
||||
|
||||
let transaction = buffer.update(cx, |buffer, cx| {
|
||||
buffer.finalize_last_transaction();
|
||||
buffer.start_transaction();
|
||||
buffer.edit([range], &new_name, cx);
|
||||
if buffer.end_transaction(cx).is_some() {
|
||||
let transaction = buffer.finalize_last_transaction().unwrap().clone();
|
||||
buffer.forget_transaction(transaction.id);
|
||||
Some(transaction)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
Some(cx.spawn(|workspace, mut cx| async move {
|
||||
Some(cx.spawn(|workspace, cx| async move {
|
||||
let project_transaction = rename.await?;
|
||||
if let Some(transaction) = transaction {
|
||||
buffer.update(&mut cx, |buffer, cx| {
|
||||
buffer.push_transaction(transaction, Instant::now());
|
||||
buffer.undo(cx);
|
||||
});
|
||||
}
|
||||
Self::open_project_transaction(
|
||||
editor,
|
||||
workspace,
|
||||
project_transaction,
|
||||
format!("Rename: {}", new_name),
|
||||
format!("Rename: {} → {}", old_name, new_name),
|
||||
cx,
|
||||
)
|
||||
.await
|
||||
}))
|
||||
}
|
||||
|
||||
fn take_rename(&mut self, cx: &mut ViewContext<Self>) -> Option<(Range<Anchor>, String)> {
|
||||
fn take_rename(
|
||||
&mut self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<(Range<Anchor>, u32, String, String)> {
|
||||
let rename = self.pending_rename.take()?;
|
||||
let new_name = self
|
||||
.buffer
|
||||
.read(cx)
|
||||
.read(cx)
|
||||
.text_for_range(rename.range.clone())
|
||||
.collect::<String>();
|
||||
|
||||
let editor = rename.editor.read(cx);
|
||||
let new_name = editor.text(cx);
|
||||
let buffer = editor.buffer.read(cx).snapshot(cx);
|
||||
let rename_position = editor.newest_selection::<Point>(&buffer);
|
||||
self.remove_blocks([rename.block_id].into_iter().collect(), cx);
|
||||
self.clear_highlighted_ranges::<Rename>(cx);
|
||||
if let Some(transaction_id) = rename.first_transaction {
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
buffer.undo_to_transaction(transaction_id, false, cx)
|
||||
});
|
||||
}
|
||||
|
||||
Some((rename.range, new_name))
|
||||
Some((
|
||||
rename.range,
|
||||
rename_position.head().column,
|
||||
rename.old_name,
|
||||
new_name,
|
||||
))
|
||||
}
|
||||
|
||||
fn invalidate_rename_range(
|
||||
@ -4722,12 +4756,6 @@ impl Editor {
|
||||
.buffer
|
||||
.update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
|
||||
{
|
||||
if let Some(rename) = self.pending_rename.as_mut() {
|
||||
if rename.first_transaction.is_none() {
|
||||
rename.first_transaction = Some(tx_id);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((_, end_selections)) = self.selection_history.get_mut(&tx_id) {
|
||||
*end_selections = Some(self.selections.clone());
|
||||
} else {
|
||||
@ -5146,6 +5174,8 @@ impl EditorSettings {
|
||||
gutter_padding_factor: 2.,
|
||||
active_line_background: Default::default(),
|
||||
highlighted_line_background: Default::default(),
|
||||
diff_background_deleted: Default::default(),
|
||||
diff_background_inserted: Default::default(),
|
||||
line_number: Default::default(),
|
||||
line_number_active: Default::default(),
|
||||
selection: Default::default(),
|
||||
|
@ -299,7 +299,7 @@ impl EditorElement {
|
||||
if let Some((row, indicator)) = layout.code_actions_indicator.as_mut() {
|
||||
let mut x = bounds.width() - layout.gutter_padding;
|
||||
let mut y = *row as f32 * layout.line_height - scroll_top;
|
||||
x += ((layout.gutter_padding + layout.text_offset.x()) - indicator.size().x()) / 2.;
|
||||
x += ((layout.gutter_padding + layout.gutter_margin) - indicator.size().x()) / 2.;
|
||||
y += (layout.line_height - indicator.size().y()) / 2.;
|
||||
indicator.paint(bounds.origin() + vec2f(x, y), visible_bounds, cx);
|
||||
}
|
||||
@ -321,7 +321,7 @@ impl EditorElement {
|
||||
let end_row = ((scroll_top + bounds.height()) / layout.line_height).ceil() as u32 + 1; // Add 1 to ensure selections bleed off screen
|
||||
let max_glyph_width = layout.em_width;
|
||||
let scroll_left = scroll_position.x() * max_glyph_width;
|
||||
let content_origin = bounds.origin() + layout.text_offset;
|
||||
let content_origin = bounds.origin() + layout.gutter_margin;
|
||||
|
||||
cx.scene.push_layer(Some(bounds));
|
||||
|
||||
@ -776,22 +776,24 @@ impl Element for EditorElement {
|
||||
|
||||
let gutter_padding;
|
||||
let gutter_width;
|
||||
let gutter_margin;
|
||||
if snapshot.mode == EditorMode::Full {
|
||||
gutter_padding = style.text.em_width(cx.font_cache) * style.gutter_padding_factor;
|
||||
gutter_width = self.max_line_number_width(&snapshot, cx) + gutter_padding * 2.0;
|
||||
gutter_margin = -style.text.descent(cx.font_cache);
|
||||
} else {
|
||||
gutter_padding = 0.0;
|
||||
gutter_width = 0.0
|
||||
gutter_width = 0.0;
|
||||
gutter_margin = 0.0;
|
||||
};
|
||||
|
||||
let text_width = size.x() - gutter_width;
|
||||
let text_offset = vec2f(-style.text.descent(cx.font_cache), 0.);
|
||||
let em_width = style.text.em_width(cx.font_cache);
|
||||
let em_advance = style.text.em_advance(cx.font_cache);
|
||||
let overscroll = vec2f(em_width, 0.);
|
||||
let wrap_width = match self.settings.soft_wrap {
|
||||
SoftWrap::None => None,
|
||||
SoftWrap::EditorWidth => Some(text_width - text_offset.x() - overscroll.x() - em_width),
|
||||
SoftWrap::EditorWidth => Some(text_width - gutter_margin - overscroll.x() - em_width),
|
||||
SoftWrap::Column(column) => Some(column as f32 * em_advance),
|
||||
};
|
||||
let snapshot = self.update_view(cx.app, |view, cx| {
|
||||
@ -991,7 +993,7 @@ impl Element for EditorElement {
|
||||
gutter_padding,
|
||||
gutter_width,
|
||||
em_width,
|
||||
gutter_width + text_offset.x(),
|
||||
gutter_width + gutter_margin,
|
||||
line_height,
|
||||
&style,
|
||||
&line_layouts,
|
||||
@ -1006,7 +1008,7 @@ impl Element for EditorElement {
|
||||
gutter_size,
|
||||
gutter_padding,
|
||||
text_size,
|
||||
text_offset,
|
||||
gutter_margin,
|
||||
snapshot,
|
||||
active_rows,
|
||||
highlighted_rows,
|
||||
@ -1080,6 +1082,12 @@ impl Element for EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
for (_, block) in &mut layout.blocks {
|
||||
if block.dispatch_event(event, cx) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
match event {
|
||||
Event::LeftMouseDown {
|
||||
position,
|
||||
@ -1123,6 +1131,7 @@ pub struct LayoutState {
|
||||
scroll_max: Vector2F,
|
||||
gutter_size: Vector2F,
|
||||
gutter_padding: f32,
|
||||
gutter_margin: f32,
|
||||
text_size: Vector2F,
|
||||
snapshot: EditorSnapshot,
|
||||
active_rows: BTreeMap<u32, bool>,
|
||||
@ -1135,7 +1144,6 @@ pub struct LayoutState {
|
||||
em_advance: f32,
|
||||
highlighted_ranges: Vec<(Range<DisplayPoint>, Color)>,
|
||||
selections: HashMap<ReplicaId, Vec<text::Selection<DisplayPoint>>>,
|
||||
text_offset: Vector2F,
|
||||
context_menu: Option<(DisplayPoint, ElementBox)>,
|
||||
code_actions_indicator: Option<(u32, ElementBox)>,
|
||||
}
|
||||
|
@ -278,6 +278,8 @@ pub struct EditorStyle {
|
||||
pub gutter_padding_factor: f32,
|
||||
pub active_line_background: Color,
|
||||
pub highlighted_line_background: Color,
|
||||
pub diff_background_deleted: Color,
|
||||
pub diff_background_inserted: Color,
|
||||
pub line_number: Color,
|
||||
pub line_number_active: Color,
|
||||
pub guest_selections: Vec<SelectionStyle>,
|
||||
@ -383,6 +385,8 @@ impl InputEditorStyle {
|
||||
gutter_padding_factor: Default::default(),
|
||||
active_line_background: Default::default(),
|
||||
highlighted_line_background: Default::default(),
|
||||
diff_background_deleted: Default::default(),
|
||||
diff_background_inserted: Default::default(),
|
||||
line_number: Default::default(),
|
||||
line_number_active: Default::default(),
|
||||
guest_selections: Default::default(),
|
||||
|
@ -248,6 +248,8 @@ gutter_background = "$surface.1"
|
||||
gutter_padding_factor = 2.5
|
||||
active_line_background = "$state.active_line"
|
||||
highlighted_line_background = "$state.highlighted_line"
|
||||
diff_background_deleted = "$state.deleted_line"
|
||||
diff_background_inserted = "$state.inserted_line"
|
||||
line_number = "$text.2.color"
|
||||
line_number_active = "$text.0.color"
|
||||
selection = "$selection.host"
|
||||
|
@ -39,6 +39,8 @@ bad = "#b7372e"
|
||||
[state]
|
||||
active_line = "#161313"
|
||||
highlighted_line = "#faca5033"
|
||||
deleted_line = "#dd000022"
|
||||
inserted_line = "#00dd0022"
|
||||
hover = "#00000033"
|
||||
selected = "#00000088"
|
||||
|
||||
|
@ -39,6 +39,8 @@ bad = "#b7372e"
|
||||
[state]
|
||||
active_line = "#00000022"
|
||||
highlighted_line = "#faca5033"
|
||||
deleted_line = "#dd000044"
|
||||
inserted_line = "#00dd0044"
|
||||
hover = "#00000033"
|
||||
selected = "#00000088"
|
||||
|
||||
|
@ -39,6 +39,8 @@ bad = "#b7372e"
|
||||
[state]
|
||||
active_line = "#00000008"
|
||||
highlighted_line = "#faca5033"
|
||||
deleted_line = "#dd000044"
|
||||
inserted_line = "#00dd0044"
|
||||
hover = "#0000000D"
|
||||
selected = "#0000001c"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user