Skip to content

Commit

Permalink
Position signature help above to not block completion
Browse files Browse the repository at this point in the history
  • Loading branch information
sudormrfbin committed Mar 12, 2022
1 parent 4a48370 commit a23536e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
9 changes: 5 additions & 4 deletions helix-term/src/commands/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use helix_view::editor::Action;
use crate::{
compositor::{self, Compositor},
ui::{
self, lsp::SignatureHelp, overlay::overlayed, FileLocation, FilePicker, Popup, Prompt,
PromptEvent,
self, lsp::SignatureHelp, overlay::overlayed, popup, FileLocation, FilePicker, Popup,
Prompt, PromptEvent,
},
};

Expand Down Expand Up @@ -633,9 +633,10 @@ pub fn signature_help(cx: &mut Context) {
};
contents.set_active_param_range(active_param_range());

let mut popup = Popup::new(SignatureHelp::ID, contents);
let old_popup = compositor.find_id::<Popup<SignatureHelp>>(SignatureHelp::ID);
popup.set_position(old_popup.and_then(|p| p.position()));
let popup = Popup::new(SignatureHelp::ID, contents)
.position(old_popup.and_then(|p| p.get_position()))
.position_bias(popup::PositionBias::Above);
compositor.replace_or_push(SignatureHelp::ID, popup);
},
);
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod markdown;
pub mod menu;
pub mod overlay;
mod picker;
mod popup;
pub mod popup;
mod prompt;
mod spinner;
mod text;
Expand Down
42 changes: 33 additions & 9 deletions helix-term/src/ui/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ use helix_view::graphics::{Margin, Rect};
// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
// a width/height hint. maybe Popup(Box<Component>)

#[derive(PartialEq)]
pub enum PositionBias {
Above,
Below,
}

pub struct Popup<T: Component> {
contents: T,
position: Option<Position>,
margin: Margin,
size: (u16, u16),
child_size: (u16, u16),
position_bias: PositionBias,
scroll: usize,
auto_close: bool,
id: &'static str,
Expand All @@ -32,21 +39,28 @@ impl<T: Component> Popup<T> {
horizontal: 0,
},
size: (0, 0),
position_bias: PositionBias::Below,
child_size: (0, 0),
scroll: 0,
auto_close: false,
id,
}
}

pub fn set_position(&mut self, pos: Option<Position>) {
pub fn position(mut self, pos: Option<Position>) -> Self {
self.position = pos;
self
}

pub fn position(&self) -> Option<Position> {
pub fn get_position(&self) -> Option<Position> {
self.position
}

pub fn position_bias(mut self, bias: PositionBias) -> Self {
self.position_bias = bias;
self
}

pub fn margin(mut self, margin: Margin) -> Self {
self.margin = margin;
self
Expand Down Expand Up @@ -75,13 +89,23 @@ impl<T: Component> Popup<T> {
rel_x = rel_x.saturating_sub((rel_x + width).saturating_sub(viewport.width));
}

// TODO: be able to specify orientation preference. We want above for most popups, below
// for menus/autocomplete.
if viewport.height > rel_y + height {
rel_y += 1 // position below point
} else {
rel_y = rel_y.saturating_sub(height) // position above point
}
let can_put_below = viewport.height > rel_y + height;
let can_put_above = rel_y.checked_sub(height).is_some();
let final_pos = match self.position_bias {
PositionBias::Below => match can_put_below {
true => PositionBias::Below,
false => PositionBias::Above,
},
PositionBias::Above => match can_put_above {
true => PositionBias::Above,
false => PositionBias::Below,
},
};

rel_y = match final_pos {
PositionBias::Above => rel_y.saturating_sub(height),
PositionBias::Below => rel_y + 1,
};

(rel_x, rel_y)
}
Expand Down

0 comments on commit a23536e

Please sign in to comment.