Skip to content

Commit bf40d4f

Browse files
iamnbutleras-ciirtfeldman
authored andcommitted
Prompt Library Refinements (zed-industries#13470)
TODO: - [x] Moving the cursor out of the title editor should unselect any selected text Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <[email protected]> Co-authored-by: Richard <[email protected]>
1 parent c09ed2e commit bf40d4f

File tree

15 files changed

+454
-226
lines changed

15 files changed

+454
-226
lines changed

assets/icons/book.svg

Lines changed: 1 addition & 0 deletions
Loading

assets/icons/book_copy.svg

Lines changed: 1 addition & 0 deletions
Loading

assets/icons/book_plus.svg

Lines changed: 1 addition & 0 deletions
Loading

crates/assistant/src/prompt_library.rs

Lines changed: 288 additions & 181 deletions
Large diffs are not rendered by default.

crates/editor/src/editor.rs

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ pub enum SelectMode {
335335

336336
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
337337
pub enum EditorMode {
338-
SingleLine,
338+
SingleLine { auto_width: bool },
339339
AutoHeight { max_lines: usize },
340340
Full,
341341
}
@@ -1580,7 +1580,13 @@ impl Editor {
15801580
pub fn single_line(cx: &mut ViewContext<Self>) -> Self {
15811581
let buffer = cx.new_model(|cx| Buffer::local("", cx));
15821582
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
1583-
Self::new(EditorMode::SingleLine, buffer, None, false, cx)
1583+
Self::new(
1584+
EditorMode::SingleLine { auto_width: false },
1585+
buffer,
1586+
None,
1587+
false,
1588+
cx,
1589+
)
15841590
}
15851591

15861592
pub fn multi_line(cx: &mut ViewContext<Self>) -> Self {
@@ -1589,6 +1595,18 @@ impl Editor {
15891595
Self::new(EditorMode::Full, buffer, None, false, cx)
15901596
}
15911597

1598+
pub fn auto_width(cx: &mut ViewContext<Self>) -> Self {
1599+
let buffer = cx.new_model(|cx| Buffer::local("", cx));
1600+
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
1601+
Self::new(
1602+
EditorMode::SingleLine { auto_width: true },
1603+
buffer,
1604+
None,
1605+
false,
1606+
cx,
1607+
)
1608+
}
1609+
15921610
pub fn auto_height(max_lines: usize, cx: &mut ViewContext<Self>) -> Self {
15931611
let buffer = cx.new_model(|cx| Buffer::local("", cx));
15941612
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
@@ -1701,8 +1719,8 @@ impl Editor {
17011719

17021720
let blink_manager = cx.new_model(|cx| BlinkManager::new(CURSOR_BLINK_INTERVAL, cx));
17031721

1704-
let soft_wrap_mode_override =
1705-
(mode == EditorMode::SingleLine).then(|| language_settings::SoftWrap::PreferLine);
1722+
let soft_wrap_mode_override = matches!(mode, EditorMode::SingleLine { .. })
1723+
.then(|| language_settings::SoftWrap::PreferLine);
17061724

17071725
let mut project_subscriptions = Vec::new();
17081726
if mode == EditorMode::Full {
@@ -1749,7 +1767,7 @@ impl Editor {
17491767
.detach();
17501768
cx.on_blur(&focus_handle, Self::handle_blur).detach();
17511769

1752-
let show_indent_guides = if mode == EditorMode::SingleLine {
1770+
let show_indent_guides = if matches!(mode, EditorMode::SingleLine { .. }) {
17531771
Some(false)
17541772
} else {
17551773
None
@@ -1905,7 +1923,7 @@ impl Editor {
19051923
let mut key_context = KeyContext::new_with_defaults();
19061924
key_context.add("Editor");
19071925
let mode = match self.mode {
1908-
EditorMode::SingleLine => "single_line",
1926+
EditorMode::SingleLine { .. } => "single_line",
19091927
EditorMode::AutoHeight { .. } => "auto_height",
19101928
EditorMode::Full => "full",
19111929
};
@@ -6660,7 +6678,7 @@ impl Editor {
66606678
return;
66616679
}
66626680

6663-
if matches!(self.mode, EditorMode::SingleLine) {
6681+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
66646682
cx.propagate();
66656683
return;
66666684
}
@@ -6697,7 +6715,7 @@ impl Editor {
66976715
return;
66986716
}
66996717

6700-
if matches!(self.mode, EditorMode::SingleLine) {
6718+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
67016719
cx.propagate();
67026720
return;
67036721
}
@@ -6728,7 +6746,7 @@ impl Editor {
67286746
return;
67296747
}
67306748

6731-
if matches!(self.mode, EditorMode::SingleLine) {
6749+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
67326750
cx.propagate();
67336751
return;
67346752
}
@@ -6791,7 +6809,7 @@ impl Editor {
67916809
return;
67926810
}
67936811

6794-
if matches!(self.mode, EditorMode::SingleLine) {
6812+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
67956813
cx.propagate();
67966814
return;
67976815
}
@@ -6839,7 +6857,7 @@ impl Editor {
68396857
pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext<Self>) {
68406858
self.take_rename(true, cx);
68416859

6842-
if self.mode == EditorMode::SingleLine {
6860+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
68436861
cx.propagate();
68446862
return;
68456863
}
@@ -6900,7 +6918,7 @@ impl Editor {
69006918
return;
69016919
}
69026920

6903-
if matches!(self.mode, EditorMode::SingleLine) {
6921+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
69046922
cx.propagate();
69056923
return;
69066924
}
@@ -7248,7 +7266,7 @@ impl Editor {
72487266
_: &MoveToStartOfParagraph,
72497267
cx: &mut ViewContext<Self>,
72507268
) {
7251-
if matches!(self.mode, EditorMode::SingleLine) {
7269+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
72527270
cx.propagate();
72537271
return;
72547272
}
@@ -7268,7 +7286,7 @@ impl Editor {
72687286
_: &MoveToEndOfParagraph,
72697287
cx: &mut ViewContext<Self>,
72707288
) {
7271-
if matches!(self.mode, EditorMode::SingleLine) {
7289+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
72727290
cx.propagate();
72737291
return;
72747292
}
@@ -7288,7 +7306,7 @@ impl Editor {
72887306
_: &SelectToStartOfParagraph,
72897307
cx: &mut ViewContext<Self>,
72907308
) {
7291-
if matches!(self.mode, EditorMode::SingleLine) {
7309+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
72927310
cx.propagate();
72937311
return;
72947312
}
@@ -7308,7 +7326,7 @@ impl Editor {
73087326
_: &SelectToEndOfParagraph,
73097327
cx: &mut ViewContext<Self>,
73107328
) {
7311-
if matches!(self.mode, EditorMode::SingleLine) {
7329+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
73127330
cx.propagate();
73137331
return;
73147332
}
@@ -7324,7 +7342,7 @@ impl Editor {
73247342
}
73257343

73267344
pub fn move_to_beginning(&mut self, _: &MoveToBeginning, cx: &mut ViewContext<Self>) {
7327-
if matches!(self.mode, EditorMode::SingleLine) {
7345+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
73287346
cx.propagate();
73297347
return;
73307348
}
@@ -7344,7 +7362,7 @@ impl Editor {
73447362
}
73457363

73467364
pub fn move_to_end(&mut self, _: &MoveToEnd, cx: &mut ViewContext<Self>) {
7347-
if matches!(self.mode, EditorMode::SingleLine) {
7365+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
73487366
cx.propagate();
73497367
return;
73507368
}
@@ -8203,7 +8221,7 @@ impl Editor {
82038221
let advance_downwards = action.advance_downwards
82048222
&& selections_on_single_row
82058223
&& !selections_selecting
8206-
&& this.mode != EditorMode::SingleLine;
8224+
&& !matches!(this.mode, EditorMode::SingleLine { .. });
82078225

82088226
if advance_downwards {
82098227
let snapshot = this.buffer.read(cx).snapshot(cx);
@@ -12079,7 +12097,7 @@ impl Render for Editor {
1207912097
let settings = ThemeSettings::get_global(cx);
1208012098

1208112099
let text_style = match self.mode {
12082-
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
12100+
EditorMode::SingleLine { .. } | EditorMode::AutoHeight { .. } => TextStyle {
1208312101
color: cx.theme().colors().editor_foreground,
1208412102
font_family: settings.ui_font.family.clone(),
1208512103
font_features: settings.ui_font.features.clone(),
@@ -12108,7 +12126,7 @@ impl Render for Editor {
1210812126
};
1210912127

1211012128
let background = match self.mode {
12111-
EditorMode::SingleLine => cx.theme().system().transparent,
12129+
EditorMode::SingleLine { .. } => cx.theme().system().transparent,
1211212130
EditorMode::AutoHeight { max_lines: _ } => cx.theme().system().transparent,
1211312131
EditorMode::Full => cx.theme().colors().editor_background,
1211412132
};

crates/editor/src/element.rs

Lines changed: 82 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,10 +1831,10 @@ impl EditorElement {
18311831
}
18321832

18331833
fn layout_lines(
1834-
&self,
18351834
rows: Range<DisplayRow>,
18361835
line_number_layouts: &[Option<ShapedLine>],
18371836
snapshot: &EditorSnapshot,
1837+
style: &EditorStyle,
18381838
cx: &mut WindowContext,
18391839
) -> Vec<LineWithInvisibles> {
18401840
if rows.start >= rows.end {
@@ -1843,7 +1843,7 @@ impl EditorElement {
18431843

18441844
// Show the placeholder when the editor is empty
18451845
if snapshot.is_empty() {
1846-
let font_size = self.style.text.font_size.to_pixels(cx.rem_size());
1846+
let font_size = style.text.font_size.to_pixels(cx.rem_size());
18471847
let placeholder_color = cx.theme().colors().text_placeholder;
18481848
let placeholder_text = snapshot.placeholder_text();
18491849

@@ -1858,7 +1858,7 @@ impl EditorElement {
18581858
.filter_map(move |line| {
18591859
let run = TextRun {
18601860
len: line.len(),
1861-
font: self.style.text.font(),
1861+
font: style.text.font(),
18621862
color: placeholder_color,
18631863
background_color: None,
18641864
underline: Default::default(),
@@ -1877,10 +1877,10 @@ impl EditorElement {
18771877
})
18781878
.collect()
18791879
} else {
1880-
let chunks = snapshot.highlighted_chunks(rows.clone(), true, &self.style);
1880+
let chunks = snapshot.highlighted_chunks(rows.clone(), true, style);
18811881
LineWithInvisibles::from_chunks(
18821882
chunks,
1883-
&self.style.text,
1883+
&style.text,
18841884
MAX_LINE_LEN,
18851885
rows.len(),
18861886
line_number_layouts,
@@ -4475,7 +4475,7 @@ impl EditorElement {
44754475
// We currently use single-line and auto-height editors in UI contexts,
44764476
// so we don't want to scale everything with the buffer font size, as it
44774477
// ends up looking off.
4478-
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => None,
4478+
EditorMode::SingleLine { .. } | EditorMode::AutoHeight { .. } => None,
44794479
}
44804480
}
44814481
}
@@ -4499,12 +4499,43 @@ impl Element for EditorElement {
44994499
editor.set_style(self.style.clone(), cx);
45004500

45014501
let layout_id = match editor.mode {
4502-
EditorMode::SingleLine => {
4502+
EditorMode::SingleLine { auto_width } => {
45034503
let rem_size = cx.rem_size();
4504-
let mut style = Style::default();
4505-
style.size.width = relative(1.).into();
4506-
style.size.height = self.style.text.line_height_in_pixels(rem_size).into();
4507-
cx.request_layout(style, None)
4504+
4505+
let height = self.style.text.line_height_in_pixels(rem_size);
4506+
if auto_width {
4507+
let editor_handle = cx.view().clone();
4508+
let style = self.style.clone();
4509+
cx.request_measured_layout(Style::default(), move |_, _, cx| {
4510+
let editor_snapshot =
4511+
editor_handle.update(cx, |editor, cx| editor.snapshot(cx));
4512+
let line = Self::layout_lines(
4513+
DisplayRow(0)..DisplayRow(1),
4514+
&[],
4515+
&editor_snapshot,
4516+
&style,
4517+
cx,
4518+
)
4519+
.pop()
4520+
.unwrap();
4521+
4522+
let font_id = cx.text_system().resolve_font(&style.text.font());
4523+
let font_size = style.text.font_size.to_pixels(cx.rem_size());
4524+
let em_width = cx
4525+
.text_system()
4526+
.typographic_bounds(font_id, font_size, 'm')
4527+
.unwrap()
4528+
.size
4529+
.width;
4530+
4531+
size(line.width + em_width, height)
4532+
})
4533+
} else {
4534+
let mut style = Style::default();
4535+
style.size.height = height.into();
4536+
style.size.width = relative(1.).into();
4537+
cx.request_layout(style, None)
4538+
}
45084539
}
45094540
EditorMode::AutoHeight { max_lines } => {
45104541
let editor_handle = cx.view().clone();
@@ -4763,8 +4794,13 @@ impl Element for EditorElement {
47634794
);
47644795

47654796
let mut max_visible_line_width = Pixels::ZERO;
4766-
let mut line_layouts =
4767-
self.layout_lines(start_row..end_row, &line_numbers, &snapshot, cx);
4797+
let mut line_layouts = Self::layout_lines(
4798+
start_row..end_row,
4799+
&line_numbers,
4800+
&snapshot,
4801+
&self.style,
4802+
cx,
4803+
);
47684804
for line_with_invisibles in &line_layouts {
47694805
if line_with_invisibles.width > max_visible_line_width {
47704806
max_visible_line_width = line_with_invisibles.width;
@@ -4792,16 +4828,43 @@ impl Element for EditorElement {
47924828
)
47934829
});
47944830

4795-
let scroll_pixel_position = point(
4796-
scroll_position.x * em_width,
4797-
scroll_position.y * line_height,
4798-
);
4799-
48004831
let start_buffer_row =
48014832
MultiBufferRow(start_anchor.to_point(&snapshot.buffer_snapshot).row);
48024833
let end_buffer_row =
48034834
MultiBufferRow(end_anchor.to_point(&snapshot.buffer_snapshot).row);
48044835

4836+
let scroll_max = point(
4837+
((scroll_width - text_hitbox.size.width) / em_width).max(0.0),
4838+
max_row.as_f32(),
4839+
);
4840+
4841+
self.editor.update(cx, |editor, cx| {
4842+
let clamped = editor.scroll_manager.clamp_scroll_left(scroll_max.x);
4843+
4844+
let autoscrolled = if autoscroll_horizontally {
4845+
editor.autoscroll_horizontally(
4846+
start_row,
4847+
text_hitbox.size.width,
4848+
scroll_width,
4849+
em_width,
4850+
&line_layouts,
4851+
cx,
4852+
)
4853+
} else {
4854+
false
4855+
};
4856+
4857+
if clamped || autoscrolled {
4858+
snapshot = editor.snapshot(cx);
4859+
scroll_position = snapshot.scroll_position();
4860+
}
4861+
});
4862+
4863+
let scroll_pixel_position = point(
4864+
scroll_position.x * em_width,
4865+
scroll_position.y * line_height,
4866+
);
4867+
48054868
let indent_guides = self.layout_indent_guides(
48064869
content_origin,
48074870
text_hitbox.origin,
@@ -6065,7 +6128,7 @@ mod tests {
60656128
});
60666129

60676130
for editor_mode_without_invisibles in [
6068-
EditorMode::SingleLine,
6131+
EditorMode::SingleLine { auto_width: false },
60696132
EditorMode::AutoHeight { max_lines: 100 },
60706133
] {
60716134
let invisibles = collect_invisibles_from_new_editor(

crates/editor/src/scroll.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ impl Editor {
455455
}
456456

457457
pub fn scroll_screen(&mut self, amount: &ScrollAmount, cx: &mut ViewContext<Self>) {
458-
if matches!(self.mode, EditorMode::SingleLine) {
458+
if matches!(self.mode, EditorMode::SingleLine { .. }) {
459459
cx.propagate();
460460
return;
461461
}

0 commit comments

Comments
 (0)