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/>.
|
||||
*/
|
||||
|
||||
use espanso_match::rolling::{matcher::RollingMatcher, RollingMatch};
|
||||
use espanso_match::rolling::{
|
||||
matcher::{RollingMatcher, RollingMatcherOptions},
|
||||
RollingMatch,
|
||||
};
|
||||
|
||||
use crate::engine::{
|
||||
event::keyboard::Key,
|
||||
|
@ -32,13 +35,30 @@ pub struct RollingMatcherAdapter {
|
|||
|
||||
impl RollingMatcherAdapter {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> Matcher<'a, MatcherState<'a>> for RollingMatcherAdapter {
|
||||
impl<'a> Matcher<'a, MatcherState<'a>> for RollingMatcherAdapter {
|
||||
fn process(
|
||||
&'a self,
|
||||
prev_state: Option<&MatcherState<'a>>,
|
||||
|
@ -81,6 +101,8 @@ impl From<espanso_match::MatchResult<i32>> for MatchResult {
|
|||
Self {
|
||||
id: result.id,
|
||||
trigger: result.trigger,
|
||||
left_separator: result.left_separator,
|
||||
right_separator: result.right_separator,
|
||||
args: result.vars,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,7 @@ use std::collections::HashMap;
|
|||
|
||||
use espanso_config::matches::{Match, MatchEffect};
|
||||
|
||||
use crate::engine::{
|
||||
event::{render::RenderingRequestedEvent, Event},
|
||||
process::Multiplexer,
|
||||
};
|
||||
use crate::engine::{event::{Event, matches::DetectedMatch, render::RenderingRequestedEvent}, process::Multiplexer};
|
||||
|
||||
pub trait MatchProvider<'a> {
|
||||
fn get(&self, match_id: i32) -> Option<&'a Match>;
|
||||
|
@ -41,14 +38,16 @@ impl<'a> MultiplexAdapter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Multiplexer for MultiplexAdapter<'a> {
|
||||
fn convert(&self, match_id: i32, trigger: Option<String>, trigger_args: HashMap<String, String>) -> Option<Event> {
|
||||
let m = self.provider.get(match_id)?;
|
||||
fn convert(&self, detected_match: DetectedMatch) -> Option<Event> {
|
||||
let m = self.provider.get(detected_match.id)?;
|
||||
|
||||
match &m.effect {
|
||||
MatchEffect::Text(_) => Some(Event::RenderingRequested(RenderingRequestedEvent {
|
||||
match_id,
|
||||
trigger,
|
||||
trigger_args,
|
||||
match_id: detected_match.id,
|
||||
trigger: detected_match.trigger,
|
||||
left_separator: detected_match.left_separator,
|
||||
right_separator: detected_match.right_separator,
|
||||
trigger_args: detected_match.args,
|
||||
})),
|
||||
// TODO: think about rich text and image
|
||||
MatchEffect::None => None,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TriggerCompensationEvent {
|
||||
pub trigger: String,
|
||||
pub left_separator: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
|
|
@ -28,6 +28,8 @@ pub struct MatchesDetectedEvent {
|
|||
pub struct DetectedMatch {
|
||||
pub id: i32,
|
||||
pub trigger: Option<String>,
|
||||
pub left_separator: Option<String>,
|
||||
pub right_separator: Option<String>,
|
||||
pub args: HashMap<String, String>,
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ use std::collections::HashMap;
|
|||
pub struct RenderingRequestedEvent {
|
||||
pub match_id: i32,
|
||||
pub trigger: Option<String>,
|
||||
pub left_separator: Option<String>,
|
||||
pub right_separator: Option<String>,
|
||||
pub trigger_args: HashMap<String, String>,
|
||||
}
|
||||
|
||||
|
|
|
@ -61,11 +61,18 @@ impl<'a> Middleware for ActionMiddleware<'a> {
|
|||
.collect(),
|
||||
})
|
||||
}
|
||||
Event::TriggerCompensation(m_event) => Event::KeySequenceInject(KeySequenceInjectRequest {
|
||||
keys: (0..m_event.trigger.chars().count())
|
||||
.map(|_| Key::Backspace)
|
||||
.collect(),
|
||||
}),
|
||||
Event::TriggerCompensation(m_event) => {
|
||||
let mut backspace_count = m_event.trigger.chars().count();
|
||||
|
||||
// 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,
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ impl Middleware for CauseCompensateMiddleware {
|
|||
// Before the event, place a trigger compensation
|
||||
return Event::TriggerCompensation(TriggerCompensationEvent {
|
||||
trigger: trigger.clone(),
|
||||
left_separator: m_event.chosen.left_separator.clone(),
|
||||
});
|
||||
} else {
|
||||
return compensated_event;
|
||||
|
|
|
@ -105,6 +105,8 @@ impl<'a, State> Middleware for MatcherMiddleware<'a, State> {
|
|||
.map(|result| DetectedMatch {
|
||||
id: result.id,
|
||||
trigger: Some(result.trigger),
|
||||
right_separator: result.right_separator,
|
||||
left_separator: result.left_separator,
|
||||
args: result.args,
|
||||
})
|
||||
.collect(),
|
||||
|
|
|
@ -39,7 +39,7 @@ impl<'a> Middleware for MultiplexMiddleware<'a> {
|
|||
|
||||
fn next(&self, event: Event, _: &mut dyn FnMut(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,
|
||||
None => {
|
||||
error!("match multiplexing failed");
|
||||
|
|
|
@ -48,6 +48,12 @@ impl<'a> Middleware for RenderMiddleware<'a> {
|
|||
if let Event::RenderingRequested(m_event) = event {
|
||||
match self.renderer.render(m_event.match_id, m_event.trigger_args) {
|
||||
Ok(body) => {
|
||||
let body = if let Some(right_separator) = m_event.right_separator {
|
||||
format!("{}{}", body, right_separator)
|
||||
} else {
|
||||
body
|
||||
};
|
||||
|
||||
return Event::Rendered(RenderedEvent {
|
||||
match_id: m_event.match_id,
|
||||
body,
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* 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 std::collections::HashMap;
|
||||
use thiserror::Error;
|
||||
|
@ -56,6 +56,8 @@ pub enum MatcherEvent {
|
|||
pub struct MatchResult {
|
||||
pub id: i32,
|
||||
pub trigger: String,
|
||||
pub left_separator: Option<String>,
|
||||
pub right_separator: Option<String>,
|
||||
pub args: HashMap<String, String>,
|
||||
}
|
||||
|
||||
|
@ -70,9 +72,7 @@ pub trait MatchSelector {
|
|||
pub trait Multiplexer {
|
||||
fn convert(
|
||||
&self,
|
||||
match_id: i32,
|
||||
trigger: Option<String>,
|
||||
trigger_args: HashMap<String, String>,
|
||||
m: DetectedMatch,
|
||||
) -> Option<Event>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user