Add context menu for opening links
This commit is contained in:
parent
8c409f5be3
commit
e7e47d5bac
6 changed files with 154 additions and 41 deletions
|
|
@ -86,6 +86,9 @@ select-all = Select all
|
||||||
find = Find
|
find = Find
|
||||||
clear-scrollback = Clear scrollback
|
clear-scrollback = Clear scrollback
|
||||||
|
|
||||||
|
## Open
|
||||||
|
open-link = Open Link
|
||||||
|
|
||||||
## View
|
## View
|
||||||
view = View
|
view = View
|
||||||
zoom-in = Larger text
|
zoom-in = Larger text
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,9 @@ paste = Klistra in
|
||||||
select-all = Välj alla
|
select-all = Välj alla
|
||||||
find = Sök
|
find = Sök
|
||||||
|
|
||||||
|
## Öppna
|
||||||
|
open-link = Öppna länk
|
||||||
|
|
||||||
## Visa
|
## Visa
|
||||||
|
|
||||||
view = Visa
|
view = Visa
|
||||||
|
|
|
||||||
56
src/main.rs
56
src/main.rs
|
|
@ -12,7 +12,7 @@ use cosmic::{
|
||||||
cosmic_config::{self, ConfigSet, CosmicConfigEntry},
|
cosmic_config::{self, ConfigSet, CosmicConfigEntry},
|
||||||
cosmic_theme, executor,
|
cosmic_theme, executor,
|
||||||
iced::{
|
iced::{
|
||||||
self, Alignment, Color, Event, Length, Limits, Padding, Point, Subscription,
|
self, Alignment, Color, Event, Length, Limits, Padding, Subscription,
|
||||||
advanced::graphics::text::font_system,
|
advanced::graphics::text::font_system,
|
||||||
clipboard, event,
|
clipboard, event,
|
||||||
futures::SinkExt,
|
futures::SinkExt,
|
||||||
|
|
@ -63,6 +63,7 @@ mod terminal;
|
||||||
use terminal_box::terminal_box;
|
use terminal_box::terminal_box;
|
||||||
|
|
||||||
use crate::dnd::DndDrop;
|
use crate::dnd::DndDrop;
|
||||||
|
use crate::menu::MenuState;
|
||||||
mod terminal_box;
|
mod terminal_box;
|
||||||
|
|
||||||
#[cfg(feature = "password_manager")]
|
#[cfg(feature = "password_manager")]
|
||||||
|
|
@ -225,6 +226,7 @@ pub enum Action {
|
||||||
CopyOrSigint,
|
CopyOrSigint,
|
||||||
CopyPrimary,
|
CopyPrimary,
|
||||||
Find,
|
Find,
|
||||||
|
LaunchUrlByMenu,
|
||||||
PaneFocusDown,
|
PaneFocusDown,
|
||||||
PaneFocusLeft,
|
PaneFocusLeft,
|
||||||
PaneFocusRight,
|
PaneFocusRight,
|
||||||
|
|
@ -275,6 +277,7 @@ impl Action {
|
||||||
Self::CopyOrSigint => Message::CopyOrSigint(entity_opt),
|
Self::CopyOrSigint => Message::CopyOrSigint(entity_opt),
|
||||||
Self::CopyPrimary => Message::CopyPrimary(entity_opt),
|
Self::CopyPrimary => Message::CopyPrimary(entity_opt),
|
||||||
Self::Find => Message::Find(true),
|
Self::Find => Message::Find(true),
|
||||||
|
Self::LaunchUrlByMenu => Message::LaunchUrlByMenu,
|
||||||
Self::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down),
|
Self::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down),
|
||||||
Self::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left),
|
Self::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left),
|
||||||
Self::PaneFocusRight => Message::PaneFocusAdjacent(pane_grid::Direction::Right),
|
Self::PaneFocusRight => Message::PaneFocusAdjacent(pane_grid::Direction::Right),
|
||||||
|
|
@ -359,6 +362,7 @@ pub enum Message {
|
||||||
FocusFollowMouse(bool),
|
FocusFollowMouse(bool),
|
||||||
Key(Modifiers, Key),
|
Key(Modifiers, Key),
|
||||||
LaunchUrl(String),
|
LaunchUrl(String),
|
||||||
|
LaunchUrlByMenu,
|
||||||
Modifiers(Modifiers),
|
Modifiers(Modifiers),
|
||||||
MouseEnter(pane_grid::Pane),
|
MouseEnter(pane_grid::Pane),
|
||||||
Opacity(u8),
|
Opacity(u8),
|
||||||
|
|
@ -396,7 +400,7 @@ pub enum Message {
|
||||||
TabActivateJump(usize),
|
TabActivateJump(usize),
|
||||||
TabClose(Option<segmented_button::Entity>),
|
TabClose(Option<segmented_button::Entity>),
|
||||||
TabContextAction(segmented_button::Entity, Action),
|
TabContextAction(segmented_button::Entity, Action),
|
||||||
TabContextMenu(pane_grid::Pane, Option<Point>),
|
TabContextMenu(pane_grid::Pane, MenuState),
|
||||||
TabNew,
|
TabNew,
|
||||||
TabNewNoProfile,
|
TabNewNoProfile,
|
||||||
TabNext,
|
TabNext,
|
||||||
|
|
@ -2118,6 +2122,23 @@ impl Application for App {
|
||||||
log::warn!("failed to open {:?}: {}", url, err);
|
log::warn!("failed to open {:?}: {}", url, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::LaunchUrlByMenu => {
|
||||||
|
if let Some(tab_model) = self.pane_model.active() {
|
||||||
|
let entity = tab_model.active();
|
||||||
|
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
|
||||||
|
// Update context menu position
|
||||||
|
let mut terminal = terminal.lock().unwrap();
|
||||||
|
if let Some(url) =
|
||||||
|
terminal.context_menu.as_ref().and_then(|m| m.link.as_ref())
|
||||||
|
{
|
||||||
|
if let Err(err) = open::that_detached(url) {
|
||||||
|
log::warn!("failed to open {:?}: {}", url, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
terminal.context_menu = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::Modifiers(modifiers) => {
|
Message::Modifiers(modifiers) => {
|
||||||
self.modifiers = modifiers;
|
self.modifiers = modifiers;
|
||||||
}
|
}
|
||||||
|
|
@ -2413,14 +2434,25 @@ impl Application for App {
|
||||||
// Close context menu
|
// Close context menu
|
||||||
{
|
{
|
||||||
let mut terminal = terminal.lock().unwrap();
|
let mut terminal = terminal.lock().unwrap();
|
||||||
|
//Some actions need the menu_state,
|
||||||
|
//so only clear the position for them.
|
||||||
|
match action {
|
||||||
|
Action::LaunchUrlByMenu => {
|
||||||
|
if let Some(context_menu) = terminal.context_menu.as_mut() {
|
||||||
|
context_menu.position = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
terminal.context_menu = None;
|
terminal.context_menu = None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Run action's message
|
// Run action's message
|
||||||
return self.update(action.message(Some(entity)));
|
return self.update(action.message(Some(entity)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::TabContextMenu(pane, position_opt) => {
|
Message::TabContextMenu(pane, menu_state) => {
|
||||||
// Close any existing context menues
|
// Close any existing context menues
|
||||||
let panes: Vec<_> = self.pane_model.panes.iter().collect();
|
let panes: Vec<_> = self.pane_model.panes.iter().collect();
|
||||||
for (_pane, tab_model) in panes {
|
for (_pane, tab_model) in panes {
|
||||||
|
|
@ -2437,7 +2469,7 @@ impl Application for App {
|
||||||
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
|
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
|
||||||
// Update context menu position
|
// Update context menu position
|
||||||
let mut terminal = terminal.lock().unwrap();
|
let mut terminal = terminal.lock().unwrap();
|
||||||
terminal.context_menu = position_opt;
|
terminal.context_menu = Some(menu_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2797,9 +2829,7 @@ impl Application for App {
|
||||||
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
|
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
|
||||||
let mut terminal_box = terminal_box(terminal)
|
let mut terminal_box = terminal_box(terminal)
|
||||||
.id(terminal_id)
|
.id(terminal_id)
|
||||||
.on_context_menu(move |position_opt| {
|
.on_context_menu(move |menu_state| Message::TabContextMenu(pane, menu_state))
|
||||||
Message::TabContextMenu(pane, position_opt)
|
|
||||||
})
|
|
||||||
.on_middle_click(move || Message::MiddleClick(pane, Some(entity_middle_click)))
|
.on_middle_click(move || Message::MiddleClick(pane, Some(entity_middle_click)))
|
||||||
.on_open_hyperlink(Some(Box::new(Message::LaunchUrl)))
|
.on_open_hyperlink(Some(Box::new(Message::LaunchUrl)))
|
||||||
.on_window_focused(|| Message::WindowFocused)
|
.on_window_focused(|| Message::WindowFocused)
|
||||||
|
|
@ -2815,15 +2845,23 @@ impl Application for App {
|
||||||
|
|
||||||
let context_menu = {
|
let context_menu = {
|
||||||
let terminal = terminal.lock().unwrap();
|
let terminal = terminal.lock().unwrap();
|
||||||
terminal.context_menu
|
terminal.context_menu.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let tab_element: Element<'_, Message> = match context_menu {
|
let tab_element: Element<'_, Message> = match context_menu {
|
||||||
|
Some(menu_state) => match menu_state.position {
|
||||||
Some(point) => widget::popover(terminal_box.context_menu(point))
|
Some(point) => widget::popover(terminal_box.context_menu(point))
|
||||||
.popup(menu::context_menu(&self.config, &self.key_binds, entity))
|
.popup(menu::context_menu(
|
||||||
|
&self.config,
|
||||||
|
&self.key_binds,
|
||||||
|
entity,
|
||||||
|
menu_state.link,
|
||||||
|
))
|
||||||
.position(widget::popover::Position::Point(point))
|
.position(widget::popover::Position::Point(point))
|
||||||
.into(),
|
.into(),
|
||||||
None => terminal_box.into(),
|
None => terminal_box.into(),
|
||||||
|
},
|
||||||
|
None => terminal_box.into(),
|
||||||
};
|
};
|
||||||
tab_column = tab_column.push(tab_element);
|
tab_column = tab_column.push(tab_element);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
src/menu.rs
25
src/menu.rs
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
use cosmic::iced::Point;
|
||||||
use cosmic::widget::menu::key_bind::KeyBind;
|
use cosmic::widget::menu::key_bind::KeyBind;
|
||||||
use cosmic::widget::menu::{Item as MenuItem, menu_button};
|
use cosmic::widget::menu::{Item as MenuItem, menu_button};
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
|
|
@ -25,10 +26,17 @@ use crate::{Action, ColorSchemeId, ColorSchemeKind, Config, Message, fl};
|
||||||
static MENU_ID: LazyLock<cosmic::widget::Id> =
|
static MENU_ID: LazyLock<cosmic::widget::Id> =
|
||||||
LazyLock::new(|| cosmic::widget::Id::new("responsive-menu"));
|
LazyLock::new(|| cosmic::widget::Id::new("responsive-menu"));
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct MenuState {
|
||||||
|
pub position: Option<Point>,
|
||||||
|
pub link: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn context_menu<'a>(
|
pub fn context_menu<'a>(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
key_binds: &HashMap<KeyBind, Action>,
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
entity: segmented_button::Entity,
|
entity: segmented_button::Entity,
|
||||||
|
link: Option<String>,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let find_key = |action: &Action| -> String {
|
let find_key = |action: &Action| -> String {
|
||||||
for (key_bind, key_action) in key_binds {
|
for (key_bind, key_action) in key_binds {
|
||||||
|
|
@ -58,6 +66,21 @@ pub fn context_menu<'a>(
|
||||||
.on_press(Message::TabContextAction(entity, action))
|
.on_press(Message::TabContextAction(entity, action))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let menu_item_conditional = |label, action, condition| {
|
||||||
|
let key = find_key(&action);
|
||||||
|
let mut button = menu_button(vec![
|
||||||
|
widget::text(label).into(),
|
||||||
|
horizontal_space().into(),
|
||||||
|
widget::text(key)
|
||||||
|
.class(theme::Text::Custom(key_style))
|
||||||
|
.into(),
|
||||||
|
]);
|
||||||
|
if condition {
|
||||||
|
button = button.on_press(Message::TabContextAction(entity, action));
|
||||||
|
}
|
||||||
|
button
|
||||||
|
};
|
||||||
|
|
||||||
let menu_checkbox = |label, value, action| {
|
let menu_checkbox = |label, value, action| {
|
||||||
menu_button(vec![
|
menu_button(vec![
|
||||||
widget::text(label).into(),
|
widget::text(label).into(),
|
||||||
|
|
@ -75,6 +98,8 @@ pub fn context_menu<'a>(
|
||||||
menu_item(fl!("paste"), Action::Paste),
|
menu_item(fl!("paste"), Action::Paste),
|
||||||
menu_item(fl!("select-all"), Action::SelectAll),
|
menu_item(fl!("select-all"), Action::SelectAll),
|
||||||
divider::horizontal::light(),
|
divider::horizontal::light(),
|
||||||
|
menu_item_conditional(fl!("open-link"), Action::LaunchUrlByMenu, link.is_some()),
|
||||||
|
divider::horizontal::light(),
|
||||||
menu_item(fl!("clear-scrollback"), Action::ClearScrollback),
|
menu_item(fl!("clear-scrollback"), Action::ClearScrollback),
|
||||||
divider::horizontal::light(),
|
divider::horizontal::light(),
|
||||||
menu_item(fl!("split-horizontal"), Action::PaneSplitHorizontal),
|
menu_item(fl!("split-horizontal"), Action::PaneSplitHorizontal),
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ pub use alacritty_terminal::grid::Scroll as TerminalScroll;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{ColorSchemeKind, Config as AppConfig, ProfileId},
|
config::{ColorSchemeKind, Config as AppConfig, ProfileId},
|
||||||
|
menu::MenuState,
|
||||||
mouse_reporter::MouseReporter,
|
mouse_reporter::MouseReporter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -236,7 +237,7 @@ impl Metadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Terminal {
|
pub struct Terminal {
|
||||||
pub context_menu: Option<cosmic::iced::Point>,
|
pub context_menu: Option<MenuState>,
|
||||||
pub metadata_set: IndexSet<Metadata>,
|
pub metadata_set: IndexSet<Metadata>,
|
||||||
pub needs_update: bool,
|
pub needs_update: bool,
|
||||||
pub profile_id_opt: Option<ProfileId>,
|
pub profile_id_opt: Option<ProfileId>,
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Action, Terminal, TerminalScroll, key_bind::key_binds, mouse_reporter::MouseReporter,
|
Action, Terminal, TerminalScroll, key_bind::key_binds, menu::MenuState,
|
||||||
terminal::Metadata,
|
mouse_reporter::MouseReporter, terminal::Metadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TerminalBox<'a, Message> {
|
pub struct TerminalBox<'a, Message> {
|
||||||
|
|
@ -56,7 +56,7 @@ pub struct TerminalBox<'a, Message> {
|
||||||
show_headerbar: bool,
|
show_headerbar: bool,
|
||||||
click_timing: Duration,
|
click_timing: Duration,
|
||||||
context_menu: Option<Point>,
|
context_menu: Option<Point>,
|
||||||
on_context_menu: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
|
on_context_menu: Option<Box<dyn Fn(MenuState) -> Message + 'a>>,
|
||||||
on_mouse_enter: Option<Box<dyn Fn() -> Message + 'a>>,
|
on_mouse_enter: Option<Box<dyn Fn() -> Message + 'a>>,
|
||||||
opacity: Option<f32>,
|
opacity: Option<f32>,
|
||||||
mouse_inside_boundary: Option<bool>,
|
mouse_inside_boundary: Option<bool>,
|
||||||
|
|
@ -124,10 +124,7 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_context_menu(
|
pub fn on_context_menu(mut self, on_context_menu: impl Fn(MenuState) -> Message + 'a) -> Self {
|
||||||
mut self,
|
|
||||||
on_context_menu: impl Fn(Option<Point>) -> Message + 'a,
|
|
||||||
) -> Self {
|
|
||||||
self.on_context_menu = Some(Box::new(on_context_menu));
|
self.on_context_menu = Some(Box::new(on_context_menu));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
@ -927,7 +924,7 @@ where
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
update_active_regex_match(&mut terminal, location, &state.modifiers);
|
update_active_regex_match(&mut terminal, location, Some(&state.modifiers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Keyboard(KeyEvent::KeyPressed {
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
|
|
@ -1101,10 +1098,37 @@ where
|
||||||
// Update context menu state
|
// Update context menu state
|
||||||
if let Some(on_context_menu) = &self.on_context_menu {
|
if let Some(on_context_menu) = &self.on_context_menu {
|
||||||
shell.publish((on_context_menu)(match self.context_menu {
|
shell.publish((on_context_menu)(match self.context_menu {
|
||||||
Some(_) => None,
|
Some(_) => MenuState {
|
||||||
|
position: None,
|
||||||
|
link: None,
|
||||||
|
},
|
||||||
None => match button {
|
None => match button {
|
||||||
Button::Right => Some(p),
|
Button::Right => {
|
||||||
_ => None,
|
let x = p.x - self.padding.left;
|
||||||
|
let y = p.y - self.padding.top;
|
||||||
|
//TODO: better calculation of position
|
||||||
|
let col = x / terminal.size().cell_width;
|
||||||
|
let row = y / terminal.size().cell_height;
|
||||||
|
|
||||||
|
let location = terminal.viewport_to_point(TermPoint::new(
|
||||||
|
row as usize,
|
||||||
|
TermColumn(col as usize),
|
||||||
|
));
|
||||||
|
update_active_regex_match(
|
||||||
|
&mut terminal,
|
||||||
|
Some(location),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let link = get_hyperlink(&terminal, location);
|
||||||
|
MenuState {
|
||||||
|
position: Some(p),
|
||||||
|
link,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => MenuState {
|
||||||
|
position: None,
|
||||||
|
link: None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -1125,14 +1149,7 @@ where
|
||||||
.viewport_to_point(TermPoint::new(row as usize, TermColumn(col as usize)));
|
.viewport_to_point(TermPoint::new(row as usize, TermColumn(col as usize)));
|
||||||
if state.modifiers.control() {
|
if state.modifiers.control() {
|
||||||
if let Some(on_open_hyperlink) = &self.on_open_hyperlink {
|
if let Some(on_open_hyperlink) = &self.on_open_hyperlink {
|
||||||
if let Some(match_) = terminal
|
if let Some(hyperlink) = get_hyperlink(&terminal, location) {
|
||||||
.regex_matches
|
|
||||||
.iter()
|
|
||||||
.find(|bounds| bounds.contains(&location))
|
|
||||||
{
|
|
||||||
let term = terminal.term.lock();
|
|
||||||
let hyperlink =
|
|
||||||
term.bounds_to_string(*match_.start(), *match_.end());
|
|
||||||
shell.publish(on_open_hyperlink(hyperlink));
|
shell.publish(on_open_hyperlink(hyperlink));
|
||||||
status = Status::Captured;
|
status = Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -1182,7 +1199,11 @@ where
|
||||||
let row = y / terminal.size().cell_height;
|
let row = y / terminal.size().cell_height;
|
||||||
let location = terminal
|
let location = terminal
|
||||||
.viewport_to_point(TermPoint::new(row as usize, TermColumn(col as usize)));
|
.viewport_to_point(TermPoint::new(row as usize, TermColumn(col as usize)));
|
||||||
update_active_regex_match(&mut terminal, Some(location), &state.modifiers);
|
update_active_regex_match(
|
||||||
|
&mut terminal,
|
||||||
|
Some(location),
|
||||||
|
Some(&state.modifiers),
|
||||||
|
);
|
||||||
|
|
||||||
if is_mouse_mode {
|
if is_mouse_mode {
|
||||||
terminal.report_mouse(event, &state.modifiers, col as u32, row as u32);
|
terminal.report_mouse(event, &state.modifiers, col as u32, row as u32);
|
||||||
|
|
@ -1283,7 +1304,11 @@ where
|
||||||
row as usize,
|
row as usize,
|
||||||
TermColumn(col as usize),
|
TermColumn(col as usize),
|
||||||
));
|
));
|
||||||
update_active_regex_match(&mut terminal, Some(location), &state.modifiers);
|
update_active_regex_match(
|
||||||
|
&mut terminal,
|
||||||
|
Some(location),
|
||||||
|
Some(&state.modifiers),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1294,11 +1319,28 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_hyperlink(
|
||||||
|
terminal: &std::sync::MutexGuard<'_, Terminal>,
|
||||||
|
location: TermPoint,
|
||||||
|
) -> Option<String> {
|
||||||
|
if let Some(match_) = terminal
|
||||||
|
.regex_matches
|
||||||
|
.iter()
|
||||||
|
.find(|bounds| bounds.contains(&location))
|
||||||
|
{
|
||||||
|
let term = terminal.term.lock();
|
||||||
|
Some(term.bounds_to_string(*match_.start(), *match_.end()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_active_regex_match(
|
fn update_active_regex_match(
|
||||||
terminal: &mut std::sync::MutexGuard<'_, Terminal>,
|
terminal: &mut std::sync::MutexGuard<'_, Terminal>,
|
||||||
location: Option<TermPoint>,
|
location: Option<TermPoint>,
|
||||||
modifiers: &Modifiers,
|
modifiers: Option<&Modifiers>,
|
||||||
) {
|
) {
|
||||||
|
if let Some(modifiers) = modifiers {
|
||||||
if !modifiers.contains(Modifiers::CTRL) {
|
if !modifiers.contains(Modifiers::CTRL) {
|
||||||
if terminal.active_regex_match.is_some() {
|
if terminal.active_regex_match.is_some() {
|
||||||
terminal.active_regex_match = None;
|
terminal.active_regex_match = None;
|
||||||
|
|
@ -1306,6 +1348,7 @@ fn update_active_regex_match(
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let Some(location) = location else {
|
let Some(location) = location else {
|
||||||
if terminal.active_regex_match.is_some() {
|
if terminal.active_regex_match.is_some() {
|
||||||
terminal.active_regex_match = None;
|
terminal.active_regex_match = None;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue