From a5c3c6c6a9e21e850440130e00ebaff57e7d4f4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= <blaz@mxxn.io>
Date: Tue, 24 Aug 2021 13:21:06 +0900
Subject: [PATCH] ui: Highlight line ranges in the preview

---
 helix-term/src/commands.rs  | 12 +++++++++---
 helix-term/src/ui/picker.rs | 29 +++++++++++++++++++----------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 7434d4cd..89855cbb 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -2314,7 +2314,7 @@ fn buffer_picker(cx: &mut Context) {
                 .selection(view_id)
                 .primary()
                 .cursor_line(doc.text().slice(..));
-            Some((path.clone()?, Some(line)))
+            Some((path.clone()?, Some((line, line))))
         },
     );
     cx.push_layer(Box::new(picker));
@@ -2387,7 +2387,10 @@ fn symbol_picker(cx: &mut Context) {
                     },
                     move |_editor, symbol| {
                         let path = symbol.location.uri.to_file_path().unwrap();
-                        let line = Some(symbol.location.range.start.line as usize);
+                        let line = Some((
+                            symbol.location.range.start.line as usize,
+                            symbol.location.range.end.line as usize,
+                        ));
                         Some((path, line))
                     },
                 );
@@ -2820,7 +2823,10 @@ fn goto_impl(
                 },
                 |_editor, location| {
                     let path = location.uri.to_file_path().unwrap();
-                    let line = Some(location.range.start.line as usize);
+                    let line = Some((
+                        location.range.start.line as usize,
+                        location.range.end.line as usize,
+                    ));
                     Some((path, line))
                 },
             );
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index ecf9d528..036b41c8 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -26,7 +26,7 @@ use helix_view::{
 pub const MIN_SCREEN_WIDTH_FOR_PREVIEW: u16 = 80;
 
 /// File path and line number (used to align and highlight a line)
-type FileLocation = (PathBuf, Option<usize>);
+type FileLocation = (PathBuf, Option<(usize, usize)>);
 
 pub struct FilePicker<T> {
     picker: Picker<T>,
@@ -113,14 +113,17 @@ impl<T: 'static> Component for FilePicker<T> {
 
         block.render(preview_area, surface);
 
-        if let Some((doc, line)) = self.current_file(cx.editor).and_then(|(path, line)| {
+        if let Some((doc, line)) = self.current_file(cx.editor).and_then(|(path, range)| {
             cx.editor
                 .document_by_path(&path)
                 .or_else(|| self.preview_cache.get(&path))
-                .zip(Some(line))
+                .zip(Some(range))
         }) {
             // align to middle
-            let first_line = line.unwrap_or(0).saturating_sub(inner.height as usize / 2);
+            let first_line = line
+                .map(|(start, _)| start)
+                .unwrap_or(0)
+                .saturating_sub(inner.height as usize / 2);
             let offset = Position::new(first_line, 0);
 
             let highlights = EditorView::doc_syntax_highlights(
@@ -140,12 +143,18 @@ impl<T: 'static> Component for FilePicker<T> {
             );
 
             // highlight the line
-            if let Some(line) = line {
-                for x in inner.left()..inner.right() {
-                    surface
-                        .get_mut(x, inner.y + line.saturating_sub(first_line) as u16)
-                        .set_style(cx.editor.theme.get("ui.selection"));
-                }
+            if let Some((start, end)) = line {
+                let offset = start.saturating_sub(first_line) as u16;
+                surface.set_style(
+                    Rect::new(
+                        inner.x,
+                        inner.y + offset,
+                        inner.width,
+                        (end.saturating_sub(start) as u16 + 1)
+                            .min(inner.height.saturating_sub(offset)),
+                    ),
+                    cx.editor.theme.get("ui.selection"),
+                );
             }
         }
     }