mirror of https://github.com/helix-editor/helix
mouse: Remove verify_screen_coords, refactor primary selection modification
parent
6bb744aeac
commit
62eb8c6b40
|
@ -329,11 +329,18 @@ pub struct Selection {
|
||||||
impl Selection {
|
impl Selection {
|
||||||
// eq
|
// eq
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn primary(&self) -> Range {
|
pub fn primary(&self) -> Range {
|
||||||
self.ranges[self.primary_index]
|
self.ranges[self.primary_index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn primary_mut(&mut self) -> &mut Range {
|
||||||
|
&mut self.ranges[self.primary_index]
|
||||||
|
}
|
||||||
|
|
||||||
/// Ensure selection containing only the primary selection.
|
/// Ensure selection containing only the primary selection.
|
||||||
pub fn into_single(self) -> Self {
|
pub fn into_single(self) -> Self {
|
||||||
if self.ranges.len() == 1 {
|
if self.ranges.len() == 1 {
|
||||||
|
|
|
@ -815,25 +815,21 @@ impl Component for EditorView {
|
||||||
let editor = &mut cx.editor;
|
let editor = &mut cx.editor;
|
||||||
|
|
||||||
let result = editor.tree.views().find_map(|(view, _focus)| {
|
let result = editor.tree.views().find_map(|(view, _focus)| {
|
||||||
view.pos_at_screen_coords(
|
view.pos_at_screen_coords(&editor.documents[view.doc], row, column)
|
||||||
&editor.documents[view.doc],
|
.map(|pos| (pos, view.id))
|
||||||
row as usize,
|
|
||||||
column as usize,
|
|
||||||
)
|
|
||||||
.map(|pos| (pos, view.id))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((pos, id)) = result {
|
if let Some((pos, view_id)) = result {
|
||||||
let doc = &mut editor.documents[editor.tree.get(id).doc];
|
let doc = &mut editor.documents[editor.tree.get(view_id).doc];
|
||||||
|
|
||||||
if modifiers == crossterm::event::KeyModifiers::ALT {
|
if modifiers == crossterm::event::KeyModifiers::ALT {
|
||||||
let selection = doc.selection(id).clone();
|
let selection = doc.selection(view_id).clone();
|
||||||
doc.set_selection(id, selection.push(Range::point(pos)));
|
doc.set_selection(view_id, selection.push(Range::point(pos)));
|
||||||
} else {
|
} else {
|
||||||
doc.set_selection(id, Selection::point(pos));
|
doc.set_selection(view_id, Selection::point(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.tree.focus = id;
|
editor.tree.focus = view_id;
|
||||||
|
|
||||||
return EventResult::Consumed(None);
|
return EventResult::Consumed(None);
|
||||||
}
|
}
|
||||||
|
@ -849,22 +845,15 @@ impl Component for EditorView {
|
||||||
}) => {
|
}) => {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
|
|
||||||
let pos = view.pos_at_screen_coords(doc, row as usize, column as usize);
|
let pos = match view.pos_at_screen_coords(doc, row, column) {
|
||||||
|
Some(pos) => pos,
|
||||||
|
None => return EventResult::Ignored,
|
||||||
|
};
|
||||||
|
|
||||||
if pos == None {
|
let mut selection = doc.selection(view.id).clone();
|
||||||
return EventResult::Ignored;
|
let primary = selection.primary_mut();
|
||||||
}
|
*primary = Range::new(primary.anchor, pos);
|
||||||
|
doc.set_selection(view.id, selection);
|
||||||
let selection = doc.selection(view.id).clone();
|
|
||||||
let primary_anchor = selection.primary().anchor;
|
|
||||||
let new_selection = selection.transform(|range| -> Range {
|
|
||||||
if range.anchor == primary_anchor {
|
|
||||||
return Range::new(primary_anchor, pos.unwrap());
|
|
||||||
}
|
|
||||||
range
|
|
||||||
});
|
|
||||||
|
|
||||||
doc.set_selection(view.id, new_selection);
|
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::Mouse(_) => EventResult::Ignored,
|
Event::Mouse(_) => EventResult::Ignored,
|
||||||
|
|
|
@ -166,38 +166,26 @@ impl View {
|
||||||
Some(Position::new(row, col))
|
Some(Position::new(row, col))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifies whether a screen position is inside the view
|
|
||||||
/// Returns true when position is inside the view
|
|
||||||
pub fn verify_screen_coords(&self, row: usize, column: usize) -> bool {
|
|
||||||
// 2 for status
|
|
||||||
if row < self.area.y as usize || row > self.area.y as usize + self.area.height as usize - 2
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: not ideal
|
|
||||||
const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
|
|
||||||
|
|
||||||
if column < self.area.x as usize + OFFSET
|
|
||||||
|| column > self.area.x as usize + self.area.width as usize
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn text_pos_at_screen_coords(
|
pub fn text_pos_at_screen_coords(
|
||||||
&self,
|
&self,
|
||||||
text: &RopeSlice,
|
text: &RopeSlice,
|
||||||
row: usize,
|
row: u16,
|
||||||
column: usize,
|
column: u16,
|
||||||
tab_width: usize,
|
tab_width: usize,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
if !self.verify_screen_coords(row, column) {
|
// TODO: not ideal
|
||||||
|
const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
|
||||||
|
|
||||||
|
// 2 for status
|
||||||
|
if row < self.area.top() || row > self.area.bottom().saturating_sub(2) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let line_number = row - self.area.y as usize + self.first_line;
|
if column < self.area.left() + OFFSET || column > self.area.right() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let line_number = (row - self.area.y) as usize + self.first_line;
|
||||||
|
|
||||||
if line_number > text.len_lines() - 1 {
|
if line_number > text.len_lines() - 1 {
|
||||||
return Some(text.len_chars());
|
return Some(text.len_chars());
|
||||||
|
@ -207,10 +195,7 @@ impl View {
|
||||||
|
|
||||||
let current_line = text.line(line_number);
|
let current_line = text.line(line_number);
|
||||||
|
|
||||||
// TODO: not ideal
|
let target = (column - OFFSET - self.area.x) as usize + self.first_col;
|
||||||
const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
|
|
||||||
|
|
||||||
let target = column - OFFSET - self.area.x as usize + self.first_col;
|
|
||||||
let mut selected = 0;
|
let mut selected = 0;
|
||||||
|
|
||||||
for grapheme in RopeGraphemes::new(current_line) {
|
for grapheme in RopeGraphemes::new(current_line) {
|
||||||
|
@ -231,7 +216,7 @@ impl View {
|
||||||
|
|
||||||
/// Translates a screen position to position in the text document.
|
/// Translates a screen position to position in the text document.
|
||||||
/// Returns a usize typed position in bounds of the text if found in this view, None if out of view.
|
/// Returns a usize typed position in bounds of the text if found in this view, None if out of view.
|
||||||
pub fn pos_at_screen_coords(&self, doc: &Document, row: usize, column: usize) -> Option<usize> {
|
pub fn pos_at_screen_coords(&self, doc: &Document, row: u16, column: u16) -> Option<usize> {
|
||||||
self.text_pos_at_screen_coords(&doc.text().slice(..), row, column, doc.tab_width())
|
self.text_pos_at_screen_coords(&doc.text().slice(..), row, column, doc.tab_width())
|
||||||
}
|
}
|
||||||
// pub fn traverse<F>(&self, text: RopeSlice, start: usize, end: usize, fun: F)
|
// pub fn traverse<F>(&self, text: RopeSlice, start: usize, end: usize, fun: F)
|
||||||
|
|
Loading…
Reference in New Issue