on master help sign in
ui: Highlight line ranges in the preview
a5c3c6cBlaž Hrastnik
helix-term/src/commands.rs+9−3
@@ -2314,7 +2314,7 @@ fn buffer_picker(cx: &mut Context) {
2314 .selection(view_id)
2314 .selection(view_id)
2315 .primary()
2315 .primary()
2316 .cursor_line(doc.text().slice(..));
2316 .cursor_line(doc.text().slice(..));
2317− Some((path.clone()?, Some(line)))
2317+ Some((path.clone()?, Some((line, line))))
2318 },
2318 },
2319 );
2319 );
2320 cx.push_layer(Box::new(picker));
2320 cx.push_layer(Box::new(picker));
@@ -2387,7 +2387,10 @@ fn symbol_picker(cx: &mut Context) {
2387 },
2387 },
2388 move |_editor, symbol| {
2388 move |_editor, symbol| {
2389 let path = symbol.location.uri.to_file_path().unwrap();
2389 let path = symbol.location.uri.to_file_path().unwrap();
2390+ let line = Some((
2390− let line = Some(symbol.location.range.start.line as usize);
2391+ symbol.location.range.start.line as usize,
2392+ symbol.location.range.end.line as usize,
2393+ ));
2391 Some((path, line))
2394 Some((path, line))
2392 },
2395 },
2393 );
2396 );
@@ -2820,7 +2823,10 @@ fn goto_impl(
2820 },
2823 },
2821 |_editor, location| {
2824 |_editor, location| {
2822 let path = location.uri.to_file_path().unwrap();
2825 let path = location.uri.to_file_path().unwrap();
2826+ let line = Some((
2823− let line = Some(location.range.start.line as usize);
2827+ location.range.start.line as usize,
2828+ location.range.end.line as usize,
2829+ ));
2824 Some((path, line))
2830 Some((path, line))
2825 },
2831 },
2826 );
2832 );
helix-term/src/ui/picker.rs+19−10
@@ -26,7 +26,7 @@ use helix_view::{
26pub const MIN_SCREEN_WIDTH_FOR_PREVIEW: u16 = 80;
26pub const MIN_SCREEN_WIDTH_FOR_PREVIEW: u16 = 80;
27
27
28/// File path and line number (used to align and highlight a line)
28/// File path and line number (used to align and highlight a line)
29−type FileLocation = (PathBuf, Option<usize>);
29+type FileLocation = (PathBuf, Option<(usize, usize)>);
30
30
31pub struct FilePicker<T> {
31pub struct FilePicker<T> {
32 picker: Picker<T>,
32 picker: Picker<T>,
@@ -113,14 +113,17 @@ impl<T: 'static> Component for FilePicker<T> {
113
113
114 block.render(preview_area, surface);
114 block.render(preview_area, surface);
115
115
116− if let Some((doc, line)) = self.current_file(cx.editor).and_then(|(path, line)| {
116+ if let Some((doc, line)) = self.current_file(cx.editor).and_then(|(path, range)| {
117 cx.editor
117 cx.editor
118 .document_by_path(&path)
118 .document_by_path(&path)
119 .or_else(|| self.preview_cache.get(&path))
119 .or_else(|| self.preview_cache.get(&path))
120− .zip(Some(line))
120+ .zip(Some(range))
121 }) {
121 }) {
122 // align to middle
122 // align to middle
123+ let first_line = line
124+ .map(|(start, _)| start)
125+ .unwrap_or(0)
123− let first_line = line.unwrap_or(0).saturating_sub(inner.height as usize / 2);
126+ .saturating_sub(inner.height as usize / 2);
124 let offset = Position::new(first_line, 0);
127 let offset = Position::new(first_line, 0);
125
128
126 let highlights = EditorView::doc_syntax_highlights(
129 let highlights = EditorView::doc_syntax_highlights(
@@ -140,12 +143,18 @@ impl<T: 'static> Component for FilePicker<T> {
140 );
143 );
141
144
142 // highlight the line
145 // highlight the line
143− if let Some(line) = line {
146+ if let Some((start, end)) = line {
144− for x in inner.left()..inner.right() {
147+ let offset = start.saturating_sub(first_line) as u16;
145− surface
148+ surface.set_style(
149+ Rect::new(
150+ inner.x,
151+ inner.y + offset,
152+ inner.width,
146− .get_mut(x, inner.y + line.saturating_sub(first_line) as u16)
153+ (end.saturating_sub(start) as u16 + 1)
154+ .min(inner.height.saturating_sub(offset)),
155+ ),
147− .set_style(cx.editor.theme.get("ui.selection"));
156+ cx.editor.theme.get("ui.selection"),
148− }
157+ );
149 }
158 }
150 }
159 }
151 }
160 }