diff options
author | Dmitry Sharshakov | 2021-08-25 16:22:01 +0000 |
---|---|---|
committer | Dmitry Sharshakov | 2021-08-25 16:22:01 +0000 |
commit | c7759a5aa0b5381e0a71ba58f3f7a5f7d98c9777 (patch) | |
tree | 66fe309913b5d7fad40e21def56b724cabc61127 /helix-term/src/ui/picker.rs | |
parent | 4ee66b876613c3d2c06945520e0c5e392d9315d1 (diff) | |
parent | 44a0512d951806cc98ab30ccc73009ba2631e42f (diff) |
Merge remote-tracking branch 'origin/master' into debug
Diffstat (limited to 'helix-term/src/ui/picker.rs')
-rw-r--r-- | helix-term/src/ui/picker.rs | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 2cc25c24..ef2c434c 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -17,16 +17,15 @@ use std::{borrow::Cow, collections::HashMap, path::PathBuf}; use crate::ui::{Prompt, PromptEvent}; use helix_core::Position; use helix_view::{ - document::canonicalize_path, editor::Action, - graphics::{Color, CursorKind, Rect, Style}, + graphics::{Color, CursorKind, Margin, Rect, Style}, Document, Editor, }; 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>, @@ -54,7 +53,11 @@ impl<T> FilePicker<T> { self.picker .selection() .and_then(|current| (self.file_fn)(editor, current)) - .and_then(|(path, line)| canonicalize_path(&path).ok().zip(Some(line))) + .and_then(|(path, line)| { + helix_core::path::get_canonicalized_path(&path) + .ok() + .zip(Some(line)) + }) } fn calculate_preview(&mut self, editor: &Editor) { @@ -90,34 +93,40 @@ impl<T: 'static> Component for FilePicker<T> { area.width }; - let picker_area = Rect::new(area.x, area.y, picker_width, area.height); + let picker_area = area.with_width(picker_width); self.picker.render(picker_area, surface, cx); if !render_preview { return; } - let preview_area = Rect::new(area.x + picker_width, area.y, area.width / 2, area.height); + let preview_area = area.clip_left(picker_width); // don't like this but the lifetime sucks let block = Block::default().borders(Borders::ALL); // calculate the inner area inside the box - let mut inner = block.inner(preview_area); + let inner = block.inner(preview_area); // 1 column gap on either side - inner.x += 1; - inner.width = inner.width.saturating_sub(2); + let margin = Margin { + vertical: 0, + horizontal: 1, + }; + let inner = inner.inner(&margin); 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( @@ -137,12 +146,21 @@ 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 + .try_get("ui.highlight") + .unwrap_or_else(|| cx.editor.theme.get("ui.selection")), + ); } } } @@ -282,15 +300,11 @@ impl<T> Picker<T> { // - score all the names in relation to input fn inner_rect(area: Rect) -> Rect { - let padding_vertical = area.height * 10 / 100; - let padding_horizontal = area.width * 10 / 100; - - Rect::new( - area.x + padding_horizontal, - area.y + padding_vertical, - area.width - padding_horizontal * 2, - area.height - padding_vertical * 2, - ) + let margin = Margin { + vertical: area.height * 10 / 100, + horizontal: area.width * 10 / 100, + }; + area.inner(&margin) } impl<T: 'static> Component for Picker<T> { @@ -410,7 +424,7 @@ impl<T: 'static> Component for Picker<T> { // -- Render the input bar: - let area = Rect::new(inner.x + 1, inner.y, inner.width - 1, 1); + let area = inner.clip_left(1).with_height(1); let count = format!("{}/{}", self.matches.len(), self.options.len()); surface.set_stringn( @@ -434,8 +448,8 @@ impl<T: 'static> Component for Picker<T> { } // -- Render the contents: - // subtract the area of the prompt (-2) and current item marker " > " (-3) - let inner = Rect::new(inner.x + 3, inner.y + 2, inner.width - 3, inner.height - 2); + // subtract area of prompt from top and current item marker " > " from left + let inner = inner.clip_top(2).clip_left(3); let selected = cx.editor.theme.get("ui.text.focus"); @@ -474,7 +488,7 @@ impl<T: 'static> Component for Picker<T> { let inner = block.inner(area); // prompt area - let area = Rect::new(inner.x + 1, inner.y, inner.width - 1, 1); + let area = inner.clip_left(1).with_height(1); self.prompt.cursor(area, editor) } |