feat(core): add cursor hint handling in RenderMiddleware

This commit is contained in:
Federico Terzi 2021-04-16 20:59:55 +02:00
parent 9b1c57d217
commit d7e841bf03

View File

@ -17,10 +17,16 @@
* along with espanso. If not, see <https://www.gnu.org/licenses/>. * along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/ */
use log::{debug, error}; use log::{error};
use super::super::Middleware; use super::super::Middleware;
use crate::engine::{event::{Event, text::{TextInjectRequest, TextInjectMode}, matches::MatchSelectedEvent, render::RenderedEvent}, process::{MatchFilter, MatchSelector, Renderer, RendererError}}; use crate::engine::{
event::{
render::RenderedEvent,
Event,
},
process::{Renderer, RendererError},
};
pub struct RenderMiddleware<'a> { pub struct RenderMiddleware<'a> {
renderer: &'a dyn Renderer<'a>, renderer: &'a dyn Renderer<'a>,
@ -33,23 +39,28 @@ impl<'a> RenderMiddleware<'a> {
} }
impl<'a> Middleware for RenderMiddleware<'a> { impl<'a> Middleware for RenderMiddleware<'a> {
fn name(&self) -> &'static str {
"render"
}
fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
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, cursor_hint_back_count) = process_cursor_hint(body);
return Event::Rendered(RenderedEvent { return Event::Rendered(RenderedEvent {
trigger: m_event.trigger, trigger: m_event.trigger,
body, body,
}) cursor_hint_back_count,
});
} }
Err(err) => { Err(err) => {
match err.downcast_ref::<RendererError>() { match err.downcast_ref::<RendererError>() {
Some(RendererError::Aborted) => { Some(RendererError::Aborted) => return Event::NOOP,
return Event::NOOP
}
_ => { _ => {
error!("error during rendering: {}", err); error!("error during rendering: {}", err);
return Event::ProcessingError("An error has occurred during rendering, please examine the logs or contact support.".to_string()) return Event::ProcessingError("An error has occurred during rendering, please examine the logs or contact support.".to_string());
} }
} }
} }
@ -61,3 +72,23 @@ impl<'a> Middleware for RenderMiddleware<'a> {
} }
// TODO: test // TODO: test
fn process_cursor_hint(body: String) -> (String, Option<usize>) {
if let Some(index) = body.find("$|$") {
// Convert the byte index to a char index
let char_str = &body[0..index];
let char_index = char_str.chars().count();
let total_size = body.chars().count();
// Remove the $|$ placeholder
let body = body.replace("$|$", "");
// Calculate the amount of rewind moves needed (LEFT ARROW).
// Subtract also 3, equal to the number of chars of the placeholder "$|$"
let moves = total_size - char_index - 3;
(body, Some(moves))
} else {
(body, None)
}
}
// TODO: test