aboutsummaryrefslogtreecommitdiff
path: root/helix-view
diff options
context:
space:
mode:
authorBlaž Hrastnik2022-06-21 16:38:21 +0000
committerGitHub2022-06-21 16:38:21 +0000
commit458b89e21dcf76bbf9ca6ba237bd334f4922722d (patch)
treef859642d007db7274d3cd657ecaa59b1ec014cd8 /helix-view
parent5f7c247430998fabceb55d4689118dd75e2bdfb1 (diff)
parent6a3f7f2c399f0b92cef97b0c85ebe976fd7cfcac (diff)
Merge branch 'master' into test-harness
Diffstat (limited to 'helix-view')
-rw-r--r--helix-view/src/gutter.rs13
-rw-r--r--helix-view/src/view.rs53
2 files changed, 24 insertions, 42 deletions
diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs
index eb6796be..05fec758 100644
--- a/helix-view/src/gutter.rs
+++ b/helix-view/src/gutter.rs
@@ -26,7 +26,18 @@ pub fn diagnostic<'doc>(
Box::new(move |line: usize, _selected: bool, out: &mut String| {
use helix_core::diagnostic::Severity;
if let Ok(index) = diagnostics.binary_search_by_key(&line, |d| d.line) {
- let diagnostic = &diagnostics[index];
+ let after = diagnostics[index..].iter().take_while(|d| d.line == line);
+
+ let before = diagnostics[..index]
+ .iter()
+ .rev()
+ .take_while(|d| d.line == line);
+
+ let diagnostics_on_line = after.chain(before);
+
+ // This unwrap is safe because the iterator cannot be empty as it contains at least the item found by the binary search.
+ let diagnostic = diagnostics_on_line.max_by_key(|d| d.severity).unwrap();
+
write!(out, "●").unwrap();
return Some(match diagnostic.severity {
Some(Severity::Error) => error,
diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs
index a496fe33..bfae12a4 100644
--- a/helix-view/src/view.rs
+++ b/helix-view/src/view.rs
@@ -1,15 +1,9 @@
-use std::borrow::Cow;
-
use crate::{
graphics::Rect,
gutter::{self, Gutter},
Document, DocumentId, ViewId,
};
-use helix_core::{
- graphemes::{grapheme_width, RopeGraphemes},
- line_ending::line_end_char_index,
- visual_coords_at_pos, Position, RopeSlice, Selection,
-};
+use helix_core::{pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection};
use std::fmt;
@@ -251,44 +245,21 @@ impl View {
return None;
}
- let line_number = (row - inner.y) as usize + self.offset.row;
-
- if line_number > text.len_lines() - 1 {
+ let text_row = (row - inner.y) as usize + self.offset.row;
+ if text_row > text.len_lines() - 1 {
return Some(text.len_chars());
}
- let mut pos = text.line_to_char(line_number);
-
- let current_line = text.line(line_number);
-
- let target = (column - inner.x) as usize + self.offset.col;
- let mut col = 0;
-
- // TODO: extract this part as pos_at_visual_coords
- for grapheme in RopeGraphemes::new(current_line) {
- if col >= target {
- break;
- }
-
- let width = if grapheme == "\t" {
- tab_width - (col % tab_width)
- } else {
- let grapheme = Cow::from(grapheme);
- grapheme_width(&grapheme)
- };
-
- // If pos is in the middle of a wider grapheme (tab for example)
- // return the starting offset.
- if col + width > target {
- break;
- }
+ let text_col = (column - inner.x) as usize + self.offset.col;
- col += width;
- // TODO: use byte pos that converts back to char pos?
- pos += grapheme.chars().count();
- }
-
- Some(pos.min(line_end_char_index(&text.slice(..), line_number)))
+ Some(pos_at_visual_coords(
+ *text,
+ Position {
+ row: text_row,
+ col: text_col,
+ },
+ tab_width,
+ ))
}
/// Translates a screen position to position in the text document.