refactor(preview): improve overall previewer scheduling logic (#415)

This commit is contained in:
Alexandre Pasmantier 2025-03-20 14:10:27 +01:00 committed by GitHub
parent d09f6708bc
commit fc2f6cde46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 18 deletions

View File

@ -2,7 +2,7 @@ use rustc_hash::FxHashSet;
use anyhow::Result; use anyhow::Result;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::{debug, info, trace}; use tracing::{debug, trace};
use crate::channels::entry::Entry; use crate::channels::entry::Entry;
use crate::channels::TelevisionChannel; use crate::channels::TelevisionChannel;
@ -207,6 +207,9 @@ impl App {
{ {
for event in event_buf.drain(..) { for event in event_buf.drain(..) {
if let Some(action) = self.convert_event_to_action(event) { if let Some(action) = self.convert_event_to_action(event) {
if action != Action::Tick {
debug!("Queuing new action: {action:?}");
}
action_tx.send(action)?; action_tx.send(action)?;
} }
} }
@ -251,7 +254,7 @@ impl App {
fn convert_event_to_action(&self, event: Event<Key>) -> Option<Action> { fn convert_event_to_action(&self, event: Event<Key>) -> Option<Action> {
let action = match event { let action = match event {
Event::Input(keycode) => { Event::Input(keycode) => {
info!("{:?}", keycode); debug!("Converting {:?} to action", keycode);
// get action based on keybindings // get action based on keybindings
if let Some(action) = self.keymap.get(&keycode) { if let Some(action) = self.keymap.get(&keycode) {
action.clone() action.clone()

View File

@ -226,6 +226,16 @@ impl Previewer {
} }
} }
fn cached(&self, entry: &Entry) -> Option<Arc<Preview>> {
match &entry.preview_type {
PreviewType::Basic => Some(self.basic.preview(entry)),
PreviewType::EnvVar => Some(self.env_var.preview(entry)),
PreviewType::Files => self.file.cached(entry),
PreviewType::Command(_) => self.command.cached(entry),
PreviewType::None => None,
}
}
// we could use a target scroll here to make the previewer // we could use a target scroll here to make the previewer
// faster, but since it's already running in the background and quite // faster, but since it's already running in the background and quite
// fast for most standard file sizes, plus we're caching the previews, // fast for most standard file sizes, plus we're caching the previews,
@ -235,13 +245,14 @@ impl Previewer {
entry: &Entry, entry: &Entry,
preview_window: Option<Rect>, preview_window: Option<Rect>,
) -> Option<Arc<Preview>> { ) -> Option<Arc<Preview>> {
// if we haven't acknowledged the request yet, acknowledge it // check if we have a preview for the current request
self.requests.push(entry.clone()); if let Some(preview) = self.cached(entry) {
if let Some(preview) = self.dispatch_request(entry, preview_window) {
return Some(preview); return Some(preview);
} }
// otherwise, if we haven't acknowledged the request yet, acknowledge it
self.requests.push(entry.clone());
// lookup request stack and return the most recent preview available // lookup request stack and return the most recent preview available
for request in self.requests.back_to_front() { for request in self.requests.back_to_front() {
if let Some(preview) = if let Some(preview) =

View File

@ -1,4 +1,3 @@
use rustc_hash::FxHashMap;
use std::sync::Arc; use std::sync::Arc;
use crate::channels::entry; use crate::channels::entry;
@ -6,7 +5,6 @@ use crate::preview::{Preview, PreviewContent};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EnvVarPreviewer { pub struct EnvVarPreviewer {
cache: FxHashMap<entry::Entry, Arc<Preview>>,
_config: EnvVarPreviewerConfig, _config: EnvVarPreviewerConfig,
} }
@ -16,16 +14,11 @@ pub struct EnvVarPreviewerConfig {}
impl EnvVarPreviewer { impl EnvVarPreviewer {
pub fn new(config: Option<EnvVarPreviewerConfig>) -> Self { pub fn new(config: Option<EnvVarPreviewerConfig>) -> Self {
EnvVarPreviewer { EnvVarPreviewer {
cache: FxHashMap::default(),
_config: config.unwrap_or_default(), _config: config.unwrap_or_default(),
} }
} }
pub fn preview(&mut self, entry: &entry::Entry) -> Arc<Preview> { pub fn preview(&self, entry: &entry::Entry) -> Arc<Preview> {
// check if we have that preview in the cache
if let Some(preview) = self.cache.get(entry) {
return preview.clone();
}
let content = entry.value.as_ref().map(|preview| { let content = entry.value.as_ref().map(|preview| {
maybe_add_newline_after_colon(preview, &entry.name) maybe_add_newline_after_colon(preview, &entry.name)
}); });
@ -33,7 +26,8 @@ impl EnvVarPreviewer {
|| 1, || 1,
|c| u16::try_from(c.lines().count()).unwrap_or(u16::MAX), |c| u16::try_from(c.lines().count()).unwrap_or(u16::MAX),
); );
let preview = Arc::new(Preview {
Arc::new(Preview {
title: entry.name.clone(), title: entry.name.clone(),
content: match content { content: match content {
Some(content) => PreviewContent::PlainTextWrapped(content), Some(content) => PreviewContent::PlainTextWrapped(content),
@ -42,9 +36,7 @@ impl EnvVarPreviewer {
icon: entry.icon, icon: entry.icon,
partial_offset: None, partial_offset: None,
total_lines, total_lines,
}); })
self.cache.insert(entry.clone(), preview.clone());
preview
} }
} }

View File

@ -114,6 +114,7 @@ impl FilePreviewer {
) { ) {
if self.in_flight_previews.lock().contains(&entry.name) { if self.in_flight_previews.lock().contains(&entry.name) {
trace!("Preview already in flight for {:?}", entry.name); trace!("Preview already in flight for {:?}", entry.name);
return;
} }
if self.concurrent_preview_tasks.load(Ordering::Relaxed) if self.concurrent_preview_tasks.load(Ordering::Relaxed)