Skip to content

Commit

Permalink
added mouse support for terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
curlpipe committed Dec 16, 2024
1 parent ed3ae29 commit fc7a4cd
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/editor/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ impl Editor {
let n_lines = term.output.matches('\n').count();
let shift_down = n_lines.saturating_sub(h.saturating_sub(1));
// Calculate the contents and amount of padding for this line of the terminal
let (line, pad) = if let Some(line) = term.output.split('\n').skip(shift_down).nth(y) {
let (line, pad) = if let Some(line) = term.output.split('\n').nth(shift_down + y) {
// Calculate line and padding
let line = line.replace(['\n', '\r'], "");
let mut visible_line = strip_escape_codes(&line);
Expand Down
2 changes: 1 addition & 1 deletion src/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ impl Editor {
Some(FileLayout::Terminal(term)) => match (modifiers, code) {
(KMod::NONE, KCode::Enter) => term.lock().unwrap().char_input('\n')?,
(KMod::SHIFT | KMod::NONE, KCode::Char(ch)) => {
term.lock().unwrap().char_input(ch)?
term.lock().unwrap().char_input(ch)?;
}
(KMod::NONE, KCode::Backspace) => term.lock().unwrap().char_pop(),
(KMod::CONTROL, KCode::Char('l')) => term.lock().unwrap().clear()?,
Expand Down
104 changes: 58 additions & 46 deletions src/editor/mouse.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::editor::FileLayout;
/// For handling mouse events
use crate::{config, Result};
use crossterm::event::{KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
Expand All @@ -15,6 +16,8 @@ enum MouseLocation {
Tabs(Vec<usize>, usize),
/// Where the mouse has clicked in the file tree
FileTree(usize),
/// Where the mouse has clicked in the terminal
Terminal(Vec<usize>),
/// Mouse has clicked nothing of importance
Out,
}
Expand All @@ -36,53 +39,55 @@ impl Editor {
if let Some((idx, rows, cols)) = at_idx {
let idx = idx.clone();
// Calculate the current dent in this split
if let Some((_, doc_idx)) = self.files.get_atom(idx.clone()) {
let dent = self.dent_for(&idx, doc_idx);
// Split that user clicked in located - adjust event location
let clicked = Loc {
x: col.saturating_sub(cols.start),
y: row.saturating_sub(rows.start),
};
// Work out where the user clicked
if clicked.y == 0 && tab_enabled {
// Clicked on tab line
let (tabs, _, offset) =
self.get_tab_parts(&idx, lua, cols.end.saturating_sub(cols.start));
// Try to work out which tab we clicked on
let mut c = u16::try_from(clicked.x).unwrap_or(u16::MAX) + 2;
for (i, header) in tabs.iter().enumerate() {
let header_len = width(header, 4) + 1;
c = c.saturating_sub(u16::try_from(header_len).unwrap_or(u16::MAX));
if c == 0 {
// This tab was clicked on
return MouseLocation::Tabs(idx.clone(), i + offset);
match self.files.get_raw(idx.clone()) {
Some(FileLayout::Atom(_, doc_idx)) => {
let dent = self.dent_for(&idx, *doc_idx);
// Split that user clicked in located - adjust event location
let clicked = Loc {
x: col.saturating_sub(cols.start),
y: row.saturating_sub(rows.start),
};
// Work out where the user clicked
if clicked.y == 0 && tab_enabled {
// Clicked on tab line
let (tabs, _, offset) =
self.get_tab_parts(&idx, lua, cols.end.saturating_sub(cols.start));
// Try to work out which tab we clicked on
let mut c = u16::try_from(clicked.x).unwrap_or(u16::MAX) + 2;
for (i, header) in tabs.iter().enumerate() {
let header_len = width(header, 4) + 1;
c = c.saturating_sub(u16::try_from(header_len).unwrap_or(u16::MAX));
if c == 0 {
// This tab was clicked on
return MouseLocation::Tabs(idx.clone(), i + offset);
}
}
// Did not click on a tab
MouseLocation::Out
} else if clicked.y == rows.end.saturating_sub(1) {
// Clicked on status line
MouseLocation::Out
} else if clicked.x < dent {
// Clicked on line numbers
MouseLocation::Out
} else if let Some((fcs, ptr)) = self.files.get_atom(idx.clone()) {
// Clicked on document
let offset = fcs[ptr].doc.offset;
MouseLocation::File(
idx.clone(),
Loc {
x: clicked.x.saturating_sub(dent) + offset.x,
y: clicked.y.saturating_sub(tab) + offset.y,
},
)
} else {
// We can't seem to get the atom for some reason, just default to Out
MouseLocation::Out
}
// Did not click on a tab
MouseLocation::Out
} else if clicked.y == rows.end.saturating_sub(1) {
// Clicked on status line
MouseLocation::Out
} else if clicked.x < dent {
// Clicked on line numbers
MouseLocation::Out
} else if let Some((fcs, ptr)) = self.files.get_atom(idx.clone()) {
// Clicked on document
let offset = fcs[ptr].doc.offset;
MouseLocation::File(
idx.clone(),
Loc {
x: clicked.x.saturating_sub(dent) + offset.x,
y: clicked.y.saturating_sub(tab) + offset.y,
},
)
} else {
// We can't seem to get the atom for some reason, just default to Out
MouseLocation::Out
}
} else {
// Pretty sure we just clicked on the file tree (split with no atom!)
MouseLocation::FileTree(row)
Some(FileLayout::FileTree) => MouseLocation::FileTree(row),
Some(FileLayout::Terminal(_)) => MouseLocation::Terminal(idx),
_ => MouseLocation::Out,
}
} else {
MouseLocation::Out
Expand Down Expand Up @@ -139,6 +144,11 @@ impl Editor {
}
}
}
MouseLocation::Terminal(idx) => {
// Move focus to the index
self.cache_old_ptr(&idx);
self.ptr.clone_from(&idx);
}
MouseLocation::Out => (),
}
}
Expand Down Expand Up @@ -207,7 +217,8 @@ impl Editor {
}
MouseLocation::Tabs(_, _)
| MouseLocation::Out
| MouseLocation::FileTree(_) => (),
| MouseLocation::FileTree(_)
| MouseLocation::Terminal(_) => (),
}
}
MouseEventKind::Drag(MouseButton::Right) => {
Expand Down Expand Up @@ -241,7 +252,8 @@ impl Editor {
}
MouseLocation::Tabs(_, _)
| MouseLocation::Out
| MouseLocation::FileTree(_) => (),
| MouseLocation::FileTree(_)
| MouseLocation::Terminal(_) => (),
}
}
// Mouse scroll behaviour
Expand Down
5 changes: 1 addition & 4 deletions src/pty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,7 @@ impl Pty {
self.output += &output;
Ok(!output.is_empty())
}
Err(e) => {
// Handle polling errors
return Err(e);
}
Err(e) => Err(e),
}
}
}

0 comments on commit fc7a4cd

Please sign in to comment.