@@ -289,7 +289,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
cx.add_action(Editor::fold);
cx.add_action(Editor::unfold);
cx.add_action(Editor::fold_selected_ranges);
- cx.add_action(Editor::show_autocomplete);
+ cx.add_action(Editor::show_completions);
}
trait SelectionExt {
@@ -1505,7 +1505,7 @@ impl Editor {
}
}
- fn show_autocomplete(&mut self, _: &ShowAutocomplete, cx: &mut ViewContext<Self>) {
+ fn show_completions(&mut self, _: &ShowAutocomplete, cx: &mut ViewContext<Self>) {
let position = self
.newest_selection::<usize>(&self.buffer.read(cx).read(cx))
.head();
@@ -1531,6 +1531,10 @@ impl Editor {
.detach_and_log_err(cx);
}
+ pub fn has_completions(&self) -> bool {
+ self.completion_state.is_some()
+ }
+
pub fn render_completions(&self) -> Option<ElementBox> {
self.completion_state.as_ref().map(|state| {
let build_settings = self.build_settings.clone();
@@ -1542,7 +1546,8 @@ impl Editor {
let settings = build_settings(cx);
for completion in &completions[range] {
items.push(
- Label::new(completion.label().to_string(), settings.style.text.clone()).boxed(),
+ Label::new(completion.label().to_string(), settings.style.text.clone())
+ .boxed(),
);
}
},
@@ -300,7 +300,7 @@ impl EditorElement {
&mut self,
bounds: RectF,
visible_bounds: RectF,
- layout: &LayoutState,
+ layout: &mut LayoutState,
cx: &mut PaintContext,
) {
let view = self.view(cx.app);
@@ -392,6 +392,28 @@ impl EditorElement {
}
cx.scene.pop_layer();
+ if let Some((position, completions_list)) = layout.completions.as_mut() {
+ cx.scene.push_stacking_context(None);
+
+ let cursor_row_layout = &layout.line_layouts[(position.row() - start_row) as usize];
+ let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
+ let y = (position.row() + 1) as f32 * layout.line_height - scroll_top;
+ let mut list_origin = content_origin + vec2f(x, y);
+ let list_height = completions_list.size().y();
+
+ if list_origin.y() + list_height > bounds.lower_left().y() {
+ list_origin.set_y(list_origin.y() - layout.line_height - list_height);
+ }
+
+ completions_list.paint(
+ list_origin,
+ RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor
+ cx,
+ );
+
+ cx.scene.pop_stacking_context();
+ }
+
cx.scene.pop_layer();
}
@@ -857,9 +879,29 @@ impl Element for EditorElement {
snapshot = view.snapshot(cx);
}
- completions = view.render_completions();
+ if view.has_completions() {
+ let newest_selection_head = view
+ .newest_selection::<usize>(&snapshot.buffer_snapshot)
+ .head()
+ .to_display_point(&snapshot);
+
+ if (start_row..end_row).contains(&newest_selection_head.row()) {
+ let list = view.render_completions().unwrap();
+ completions = Some((newest_selection_head, list));
+ }
+ }
});
+ if let Some((_, completions_list)) = completions.as_mut() {
+ completions_list.layout(
+ SizeConstraint {
+ min: Vector2F::zero(),
+ max: vec2f(800., (12. * line_height).min((size.y() - line_height) / 2.)),
+ },
+ cx,
+ );
+ }
+
let blocks = self.layout_blocks(
start_row..end_row,
&snapshot,
@@ -1004,7 +1046,7 @@ pub struct LayoutState {
highlighted_ranges: Vec<(Range<DisplayPoint>, Color)>,
selections: HashMap<ReplicaId, Vec<text::Selection<DisplayPoint>>>,
text_offset: Vector2F,
- completions: Option<ElementBox>,
+ completions: Option<(DisplayPoint, ElementBox)>,
}
fn layout_line(