feat(core): improve support for word matches
This commit is contained in:
parent
97b789e946
commit
04f1449046
|
@ -17,7 +17,10 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use espanso_match::rolling::{matcher::RollingMatcher, RollingMatch};
|
use espanso_match::rolling::{
|
||||||
|
matcher::{RollingMatcher, RollingMatcherOptions},
|
||||||
|
RollingMatch,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
event::keyboard::Key,
|
event::keyboard::Key,
|
||||||
|
@ -32,7 +35,24 @@ pub struct RollingMatcherAdapter {
|
||||||
|
|
||||||
impl RollingMatcherAdapter {
|
impl RollingMatcherAdapter {
|
||||||
pub fn new(matches: &[RollingMatch<i32>]) -> Self {
|
pub fn new(matches: &[RollingMatch<i32>]) -> Self {
|
||||||
let matcher = RollingMatcher::new(matches, Default::default());
|
// TODO: load them from config
|
||||||
|
|
||||||
|
let matcher = RollingMatcher::new(
|
||||||
|
matches,
|
||||||
|
RollingMatcherOptions {
|
||||||
|
char_word_separators: vec![
|
||||||
|
" ".to_string(),
|
||||||
|
",".to_string(),
|
||||||
|
".".to_string(),
|
||||||
|
"?".to_string(),
|
||||||
|
"!".to_string(),
|
||||||
|
"\r".to_string(),
|
||||||
|
"\n".to_string(),
|
||||||
|
(22u8 as char).to_string(),
|
||||||
|
],
|
||||||
|
key_word_separators: vec![],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Self { matcher }
|
Self { matcher }
|
||||||
}
|
}
|
||||||
|
@ -81,6 +101,8 @@ impl From<espanso_match::MatchResult<i32>> for MatchResult {
|
||||||
Self {
|
Self {
|
||||||
id: result.id,
|
id: result.id,
|
||||||
trigger: result.trigger,
|
trigger: result.trigger,
|
||||||
|
left_separator: result.left_separator,
|
||||||
|
right_separator: result.right_separator,
|
||||||
args: result.vars,
|
args: result.vars,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use espanso_config::matches::{Match, MatchEffect};
|
use espanso_config::matches::{Match, MatchEffect};
|
||||||
|
|
||||||
use crate::engine::{
|
use crate::engine::{event::{Event, matches::DetectedMatch, render::RenderingRequestedEvent}, process::Multiplexer};
|
||||||
event::{render::RenderingRequestedEvent, Event},
|
|
||||||
process::Multiplexer,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait MatchProvider<'a> {
|
pub trait MatchProvider<'a> {
|
||||||
fn get(&self, match_id: i32) -> Option<&'a Match>;
|
fn get(&self, match_id: i32) -> Option<&'a Match>;
|
||||||
|
@ -41,14 +38,16 @@ impl<'a> MultiplexAdapter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Multiplexer for MultiplexAdapter<'a> {
|
impl<'a> Multiplexer for MultiplexAdapter<'a> {
|
||||||
fn convert(&self, match_id: i32, trigger: Option<String>, trigger_args: HashMap<String, String>) -> Option<Event> {
|
fn convert(&self, detected_match: DetectedMatch) -> Option<Event> {
|
||||||
let m = self.provider.get(match_id)?;
|
let m = self.provider.get(detected_match.id)?;
|
||||||
|
|
||||||
match &m.effect {
|
match &m.effect {
|
||||||
MatchEffect::Text(_) => Some(Event::RenderingRequested(RenderingRequestedEvent {
|
MatchEffect::Text(_) => Some(Event::RenderingRequested(RenderingRequestedEvent {
|
||||||
match_id,
|
match_id: detected_match.id,
|
||||||
trigger,
|
trigger: detected_match.trigger,
|
||||||
trigger_args,
|
left_separator: detected_match.left_separator,
|
||||||
|
right_separator: detected_match.right_separator,
|
||||||
|
trigger_args: detected_match.args,
|
||||||
})),
|
})),
|
||||||
// TODO: think about rich text and image
|
// TODO: think about rich text and image
|
||||||
MatchEffect::None => None,
|
MatchEffect::None => None,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct TriggerCompensationEvent {
|
pub struct TriggerCompensationEvent {
|
||||||
pub trigger: String,
|
pub trigger: String,
|
||||||
|
pub left_separator: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|
|
@ -28,6 +28,8 @@ pub struct MatchesDetectedEvent {
|
||||||
pub struct DetectedMatch {
|
pub struct DetectedMatch {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub trigger: Option<String>,
|
pub trigger: Option<String>,
|
||||||
|
pub left_separator: Option<String>,
|
||||||
|
pub right_separator: Option<String>,
|
||||||
pub args: HashMap<String, String>,
|
pub args: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ use std::collections::HashMap;
|
||||||
pub struct RenderingRequestedEvent {
|
pub struct RenderingRequestedEvent {
|
||||||
pub match_id: i32,
|
pub match_id: i32,
|
||||||
pub trigger: Option<String>,
|
pub trigger: Option<String>,
|
||||||
|
pub left_separator: Option<String>,
|
||||||
|
pub right_separator: Option<String>,
|
||||||
pub trigger_args: HashMap<String, String>,
|
pub trigger_args: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,11 +61,18 @@ impl<'a> Middleware for ActionMiddleware<'a> {
|
||||||
.collect(),
|
.collect(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Event::TriggerCompensation(m_event) => Event::KeySequenceInject(KeySequenceInjectRequest {
|
Event::TriggerCompensation(m_event) => {
|
||||||
keys: (0..m_event.trigger.chars().count())
|
let mut backspace_count = m_event.trigger.chars().count();
|
||||||
.map(|_| Key::Backspace)
|
|
||||||
.collect(),
|
// We want to preserve the left separator if present
|
||||||
}),
|
if let Some(left_separator) = &m_event.left_separator {
|
||||||
|
backspace_count -= left_separator.chars().count();
|
||||||
|
}
|
||||||
|
|
||||||
|
Event::KeySequenceInject(KeySequenceInjectRequest {
|
||||||
|
keys: (0..backspace_count).map(|_| Key::Backspace).collect(),
|
||||||
|
})
|
||||||
|
}
|
||||||
_ => event,
|
_ => event,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ impl Middleware for CauseCompensateMiddleware {
|
||||||
// Before the event, place a trigger compensation
|
// Before the event, place a trigger compensation
|
||||||
return Event::TriggerCompensation(TriggerCompensationEvent {
|
return Event::TriggerCompensation(TriggerCompensationEvent {
|
||||||
trigger: trigger.clone(),
|
trigger: trigger.clone(),
|
||||||
|
left_separator: m_event.chosen.left_separator.clone(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return compensated_event;
|
return compensated_event;
|
||||||
|
|
|
@ -105,6 +105,8 @@ impl<'a, State> Middleware for MatcherMiddleware<'a, State> {
|
||||||
.map(|result| DetectedMatch {
|
.map(|result| DetectedMatch {
|
||||||
id: result.id,
|
id: result.id,
|
||||||
trigger: Some(result.trigger),
|
trigger: Some(result.trigger),
|
||||||
|
right_separator: result.right_separator,
|
||||||
|
left_separator: result.left_separator,
|
||||||
args: result.args,
|
args: result.args,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl<'a> Middleware for MultiplexMiddleware<'a> {
|
||||||
|
|
||||||
fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
|
fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
|
||||||
if let Event::CauseCompensatedMatch(m_event) = event {
|
if let Event::CauseCompensatedMatch(m_event) = event {
|
||||||
return match self.multiplexer.convert(m_event.m.id, m_event.m.trigger, m_event.m.args) {
|
return match self.multiplexer.convert(m_event.m) {
|
||||||
Some(event) => event,
|
Some(event) => event,
|
||||||
None => {
|
None => {
|
||||||
error!("match multiplexing failed");
|
error!("match multiplexing failed");
|
||||||
|
|
|
@ -48,6 +48,12 @@ impl<'a> Middleware for RenderMiddleware<'a> {
|
||||||
if let Event::RenderingRequested(m_event) = event {
|
if let Event::RenderingRequested(m_event) = event {
|
||||||
match self.renderer.render(m_event.match_id, m_event.trigger_args) {
|
match self.renderer.render(m_event.match_id, m_event.trigger_args) {
|
||||||
Ok(body) => {
|
Ok(body) => {
|
||||||
|
let body = if let Some(right_separator) = m_event.right_separator {
|
||||||
|
format!("{}{}", body, right_separator)
|
||||||
|
} else {
|
||||||
|
body
|
||||||
|
};
|
||||||
|
|
||||||
return Event::Rendered(RenderedEvent {
|
return Event::Rendered(RenderedEvent {
|
||||||
match_id: m_event.match_id,
|
match_id: m_event.match_id,
|
||||||
body,
|
body,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{event::keyboard::Key, Event};
|
use super::{Event, event::{keyboard::Key, matches::DetectedMatch}};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -56,6 +56,8 @@ pub enum MatcherEvent {
|
||||||
pub struct MatchResult {
|
pub struct MatchResult {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub trigger: String,
|
pub trigger: String,
|
||||||
|
pub left_separator: Option<String>,
|
||||||
|
pub right_separator: Option<String>,
|
||||||
pub args: HashMap<String, String>,
|
pub args: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +72,7 @@ pub trait MatchSelector {
|
||||||
pub trait Multiplexer {
|
pub trait Multiplexer {
|
||||||
fn convert(
|
fn convert(
|
||||||
&self,
|
&self,
|
||||||
match_id: i32,
|
m: DetectedMatch,
|
||||||
trigger: Option<String>,
|
|
||||||
trigger_args: HashMap<String, String>,
|
|
||||||
) -> Option<Event>;
|
) -> Option<Event>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user