@@ -22,6 +22,7 @@ pub struct Popup<T: Component> {
22 auto_close: bool,
22 auto_close: bool,
23 ignore_escape_key: bool,
23 ignore_escape_key: bool,
24 id: &'static str,
24 id: &'static str,
27impl<T: Component> Popup<T> {
28impl<T: Component> Popup<T> {
@@ -37,6 +38,7 @@ impl<T: Component> Popup<T> {
37 auto_close: false,
38 auto_close: false,
38 ignore_escape_key: false,
39 ignore_escape_key: false,
@@ -128,6 +130,14 @@ impl<T: Component> Popup<T> {
133+ /// Toggles the Popup's scrollbar.
134+ /// Consider disabling the scrollbar in case the child
135+ /// already has its own.
136+ pub fn with_scrollbar(mut self, enable_scrollbar: bool) -> Self {
137+ self.has_scrollbar = enable_scrollbar;
131 pub fn contents(&self) -> &T {
141 pub fn contents(&self) -> &T {
132 &self.contents
142 &self.contents
@@ -228,6 +238,40 @@ impl<T: Component> Component for Popup<T> {
229 let inner = area.inner(&self.margin);
239 let inner = area.inner(&self.margin);
230 self.contents.render(inner, surface, cx);
240 self.contents.render(inner, surface, cx);
242+ // render scrollbar if contents do not fit
243+ if self.has_scrollbar {
244+ let win_height = inner.height as usize;
245+ let len = self.child_size.1 as usize;
246+ let fits = len <= win_height;
247+ let scroll = self.scroll;
248+ let scroll_style = cx.editor.theme.get("ui.menu.scroll");
250+ const fn div_ceil(a: usize, b: usize) -> usize {
255+ let scroll_height = div_ceil(win_height.pow(2), len).min(win_height);
256+ let scroll_line = (win_height - scroll_height) * scroll
257+ / std::cmp::max(1, len.saturating_sub(win_height));
260+ for i in 0..win_height {
261+ cell = &mut surface[(inner.right() - 1, inner.top() + i as u16)];
263+ cell.set_symbol("▐"); // right half block
265+ if scroll_line <= i && i < scroll_line + scroll_height {
266+ // Draw scroll thumb
267+ cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));
269+ // Draw scroll track
270+ cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));
233 fn id(&self) -> Option<&'static str> {
277 fn id(&self) -> Option<&'static str> {