summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-term/src/ui/editor.rs3
-rw-r--r--helix-term/src/ui/info.rs36
-rw-r--r--helix-view/src/graphics.rs27
3 files changed, 51 insertions, 15 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 496edf42..ffe755e6 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -699,7 +699,8 @@ impl Component for EditorView {
match event {
Event::Resize(width, height) => {
// HAXX: offset the render area height by 1 to account for prompt/commandline
- cx.editor.resize(Rect::new(0, 0, width, height - 1));
+ cx.editor
+ .resize(Rect::new(0, 0, width, height.saturating_sub(1)));
EventResult::Consumed(None)
}
Event::Key(key) => {
diff --git a/helix-term/src/ui/info.rs b/helix-term/src/ui/info.rs
index 36b096db..6e810b86 100644
--- a/helix-term/src/ui/info.rs
+++ b/helix-term/src/ui/info.rs
@@ -7,24 +7,32 @@ use tui::widgets::{Block, Borders, Widget};
impl Component for Info {
fn render(&self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
let style = cx.editor.theme.get("ui.popup");
+
+ // Calculate the area of the terminal to modify. Because we want to
+ // render at the bottom right, we use the viewport's width and height
+ // which evaluate to the most bottom right coordinate.
+ let (width, height) = (self.width + 2, self.height + 2);
+ let area = viewport.intersection(Rect::new(
+ viewport.width.saturating_sub(width),
+ viewport.height.saturating_sub(height + 2),
+ width,
+ height,
+ ));
+ surface.clear_with(area, style);
+
let block = Block::default()
.title(self.title.as_str())
.borders(Borders::ALL)
.border_style(style);
- let Info { width, height, .. } = self;
- let (w, h) = (*width + 2, *height + 2);
- // -2 to subtract command line + statusline. a bit of a hack, because of splits.
- let area = viewport.intersection(Rect::new(
- viewport.width.saturating_sub(w),
- viewport.height.saturating_sub(h + 2),
- w,
- h,
- ));
- surface.clear_with(area, style);
- let Rect { x, y, .. } = block.inner(area);
- for (y, line) in (y..).zip(self.text.lines()) {
- surface.set_string(x, y, line, style);
- }
+ let inner = block.inner(area);
block.render(area, surface);
+
+ // Only write as many lines as there are rows available.
+ for (y, line) in (inner.y..)
+ .zip(self.text.lines())
+ .take(inner.height as usize)
+ {
+ surface.set_string(inner.x, y, line, style);
+ }
}
}
diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs
index 5138e923..ed530533 100644
--- a/helix-view/src/graphics.rs
+++ b/helix-view/src/graphics.rs
@@ -64,22 +64,27 @@ impl Rect {
}
}
+ #[inline]
pub fn area(self) -> u16 {
self.width * self.height
}
+ #[inline]
pub fn left(self) -> u16 {
self.x
}
+ #[inline]
pub fn right(self) -> u16 {
self.x.saturating_add(self.width)
}
+ #[inline]
pub fn top(self) -> u16 {
self.y
}
+ #[inline]
pub fn bottom(self) -> u16 {
self.y.saturating_add(self.height)
}
@@ -97,7 +102,18 @@ impl Rect {
}
}
+ /// Calculate the union between two [`Rect`]s.
pub fn union(self, other: Rect) -> Rect {
+ // Example:
+ //
+ // If `Rect` A is positioned at `(0, 0)` with a width and height of `5`,
+ // and `Rect` B is positioned at `(5, 0)` with a width and height of `2`,
+ // then this is the resulting union:
+ //
+ // x1 = min(0, 5) => x1 = 0
+ // y1 = min(0, 0) => y1 = 0
+ // x2 = max(0 + 5, 5 + 2) => x2 = 7
+ // y2 = max(0 + 5, 0 + 2) => y2 = 5
let x1 = min(self.x, other.x);
let y1 = min(self.y, other.y);
let x2 = max(self.x + self.width, other.x + other.width);
@@ -110,7 +126,18 @@ impl Rect {
}
}
+ /// Calculate the intersection between two [`Rect`]s.
pub fn intersection(self, other: Rect) -> Rect {
+ // Example:
+ //
+ // If `Rect` A is positioned at `(0, 0)` with a width and height of `5`,
+ // and `Rect` B is positioned at `(5, 0)` with a width and height of `2`,
+ // then this is the resulting intersection:
+ //
+ // x1 = max(0, 5) => x1 = 5
+ // y1 = max(0, 0) => y1 = 0
+ // x2 = min(0 + 5, 5 + 2) => x2 = 5
+ // y2 = min(0 + 5, 0 + 2) => y2 = 2
let x1 = max(self.x, other.x);
let y1 = max(self.y, other.y);
let x2 = min(self.x + self.width, other.x + other.width);