mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
refactor: improve stdout performance by using BufWriter (#55)
This commit is contained in:
parent
053652c740
commit
7e32b5de6a
11 changed files with 58 additions and 53 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -11,7 +11,6 @@ dependencies = [
|
|||
"color_quant",
|
||||
"config",
|
||||
"image",
|
||||
"md-5",
|
||||
"once_cell",
|
||||
"ratatui",
|
||||
"shared",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ anyhow = "^1"
|
|||
base64 = "^0"
|
||||
color_quant = "^1"
|
||||
image = "^0"
|
||||
md-5 = "^0"
|
||||
once_cell = "^1"
|
||||
ratatui = "^0"
|
||||
tokio = { version = "^1", features = [ "parking_lot" ] }
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ impl Adaptor {
|
|||
|
||||
pub async fn image_show(mut path: &Path, rect: Rect) -> Result<()> {
|
||||
if IMAGE_SHOWN.swap(true, Ordering::Relaxed) {
|
||||
Self::image_hide(rect);
|
||||
Self::image_hide(rect).ok();
|
||||
}
|
||||
|
||||
let cache = BOOT.cache(path);
|
||||
|
|
@ -34,29 +34,24 @@ impl Adaptor {
|
|||
PreviewAdaptor::Kitty => Kitty::image_show(path, rect).await,
|
||||
PreviewAdaptor::Iterm2 => Iterm2::image_show(path, rect).await,
|
||||
PreviewAdaptor::Sixel => Sixel::image_show(path, rect).await,
|
||||
_ => {
|
||||
if let Some(tx) = &*UEBERZUG {
|
||||
tx.send(Some((path.to_path_buf(), rect))).ok();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(if let Some(tx) = &*UEBERZUG {
|
||||
tx.send(Some((path.to_path_buf(), rect)))?;
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn image_hide(rect: Rect) {
|
||||
pub fn image_hide(rect: Rect) -> Result<()> {
|
||||
if !IMAGE_SHOWN.swap(false, Ordering::Relaxed) {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match PREVIEW.adaptor {
|
||||
PreviewAdaptor::Kitty => Kitty::image_hide(),
|
||||
PreviewAdaptor::Iterm2 => Iterm2::image_hide(rect),
|
||||
PreviewAdaptor::Sixel => Sixel::image_hide(rect),
|
||||
_ => {
|
||||
if let Some(tx) = &*UEBERZUG {
|
||||
tx.send(None).ok();
|
||||
}
|
||||
}
|
||||
_ => Ok(if let Some(tx) = &*UEBERZUG {
|
||||
tx.send(None)?;
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{io::{stdout, Write}, path::Path};
|
||||
use std::{io::{stdout, BufWriter, Write}, path::Path};
|
||||
|
||||
use anyhow::Result;
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
|
|
@ -15,18 +15,21 @@ impl Iterm2 {
|
|||
let img = Image::crop(path, (rect.width, rect.height)).await?;
|
||||
let b = Self::encode(img).await?;
|
||||
|
||||
Term::move_to(rect.x, rect.y).ok();
|
||||
stdout().write_all(&b).ok();
|
||||
Ok(())
|
||||
let mut stdout = stdout().lock();
|
||||
Term::move_to(&mut stdout, rect.x, rect.y)?;
|
||||
Ok(stdout.write_all(&b)?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn image_hide(rect: Rect) {
|
||||
pub(super) fn image_hide(rect: Rect) -> Result<()> {
|
||||
let s = " ".repeat(rect.width as usize);
|
||||
let mut stdout = BufWriter::new(stdout().lock());
|
||||
|
||||
for y in rect.top()..=rect.bottom() {
|
||||
Term::move_to(rect.x, y).ok();
|
||||
stdout().write_all(s.as_bytes()).ok();
|
||||
Term::move_to(&mut stdout, rect.x, y)?;
|
||||
stdout.write_all(s.as_bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ impl Kitty {
|
|||
let img = Image::crop(path, (rect.width, rect.height)).await?;
|
||||
let b = Self::encode(img).await?;
|
||||
|
||||
Term::move_to(rect.x, rect.y).ok();
|
||||
stdout().write_all(&b).ok();
|
||||
Ok(())
|
||||
let mut stdout = stdout().lock();
|
||||
Term::move_to(&mut stdout, rect.x, rect.y)?;
|
||||
Ok(stdout.write_all(&b)?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn image_hide() { stdout().write_all(b"\x1b\\\x1b_Ga=d\x1b\\").ok(); }
|
||||
pub(super) fn image_hide() -> Result<()> { Ok(stdout().write_all(b"\x1b\\\x1b_Ga=d\x1b\\")?) }
|
||||
|
||||
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
|
||||
fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{io::{stdout, Write}, path::Path};
|
||||
use std::{io::{stdout, BufWriter, Write}, path::Path};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use color_quant::NeuQuant;
|
||||
|
|
@ -15,18 +15,21 @@ impl Sixel {
|
|||
let img = Image::crop(path, (rect.width, rect.height)).await?;
|
||||
let b = Self::encode(img).await?;
|
||||
|
||||
Term::move_to(rect.x, rect.y).ok();
|
||||
stdout().write_all(&b).ok();
|
||||
Ok(())
|
||||
let mut stdout = stdout().lock();
|
||||
Term::move_to(&mut stdout, rect.x, rect.y)?;
|
||||
Ok(stdout.write_all(&b)?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn image_hide(rect: Rect) {
|
||||
pub(super) fn image_hide(rect: Rect) -> Result<()> {
|
||||
let s = " ".repeat(rect.width as usize);
|
||||
let mut stdout = BufWriter::new(stdout().lock());
|
||||
|
||||
for y in rect.top()..=rect.bottom() {
|
||||
Term::move_to(rect.x, y).ok();
|
||||
stdout().write_all(s.as_bytes()).ok();
|
||||
Term::move_to(&mut stdout, rect.x, y)?;
|
||||
stdout.write_all(s.as_bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{env, fs, path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
use std::{env, fs, os::unix::prelude::OsStrExt, path::{Path, PathBuf}, time::{self, SystemTime}};
|
||||
|
||||
use clap::Parser;
|
||||
use md5::{Digest, Md5};
|
||||
|
|
@ -44,7 +44,7 @@ impl Boot {
|
|||
pub fn cache(&self, path: &Path) -> PathBuf {
|
||||
self
|
||||
.cache_dir
|
||||
.join(format!("{:x}", Md5::new_with_prefix(path.to_string_lossy().as_bytes()).finalize()))
|
||||
.join(format!("{:x}", Md5::new_with_prefix(path.as_os_str().as_bytes()).finalize()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ impl Manager {
|
|||
}
|
||||
|
||||
async fn bulk_rename_do(root: PathBuf, old: Vec<PathBuf>, new: Vec<PathBuf>) -> Result<()> {
|
||||
Term::clear()?;
|
||||
Term::clear(&mut stdout())?;
|
||||
if old.len() != new.len() {
|
||||
println!("Number of old and new differ, press ENTER to exit");
|
||||
stdin().read_exact(&mut [0]).await?;
|
||||
|
|
@ -303,7 +303,7 @@ impl Manager {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
Term::clear()?;
|
||||
Term::clear(&mut stdout())?;
|
||||
{
|
||||
let mut stdout = BufWriter::new(stdout().lock());
|
||||
writeln!(stdout, "Failed to rename:")?;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ impl Preview {
|
|||
pub fn reset(&mut self) -> bool {
|
||||
self.handle.take().map(|h| h.abort());
|
||||
self.incr.fetch_add(1, Ordering::Relaxed);
|
||||
Adaptor::image_hide(Self::rect());
|
||||
Adaptor::image_hide(Self::rect()).ok();
|
||||
|
||||
self.lock = None;
|
||||
!matches!(
|
||||
|
|
@ -89,7 +89,7 @@ impl Preview {
|
|||
pub fn reset_image(&mut self) -> bool {
|
||||
self.handle.take().map(|h| h.abort());
|
||||
self.incr.fetch_add(1, Ordering::Relaxed);
|
||||
Adaptor::image_hide(Self::rect());
|
||||
Adaptor::image_hide(Self::rect()).ok();
|
||||
|
||||
if matches!(self.data, PreviewData::Image) {
|
||||
self.lock = None;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::{collections::{BTreeMap, HashMap, HashSet}, ffi::OsStr, io::{stdout, Wr
|
|||
|
||||
use config::{manager::SortBy, open::Opener, OPEN};
|
||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||
use shared::{tty_size, Defer, MimeKind};
|
||||
use tokio::{io::AsyncReadExt, select, sync::mpsc, time};
|
||||
use shared::{tty_size, Defer, MimeKind, Term};
|
||||
use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time};
|
||||
use tracing::trace;
|
||||
|
||||
use super::{task::TaskSummary, Scheduler, TASKS_PADDING, TASKS_PERCENT};
|
||||
|
|
@ -85,17 +85,18 @@ impl Tasks {
|
|||
Event::Stop(false, None).emit();
|
||||
});
|
||||
|
||||
stdout().write_all("\n".repeat(tty_size().ws_row as usize).as_bytes()).ok();
|
||||
Term::clear(&mut stdout()).ok();
|
||||
stdout().write_all(buffered.as_bytes()).ok();
|
||||
enable_raw_mode().ok();
|
||||
|
||||
let mut stdin = tokio::io::stdin();
|
||||
let mut quit = [0; 1];
|
||||
let mut stdin = stdin();
|
||||
let mut quit = [0; 10];
|
||||
loop {
|
||||
select! {
|
||||
Some(line) = rx.recv() => {
|
||||
stdout().write_all(line.as_bytes()).ok();
|
||||
stdout().write_all(b"\r\n").ok();
|
||||
let mut stdout = stdout().lock();
|
||||
stdout.write_all(line.as_bytes()).ok();
|
||||
stdout.write_all(b"\r\n").ok();
|
||||
}
|
||||
_ = time::sleep(time::Duration::from_millis(100)) => {
|
||||
if scheduler.running.read().get(id).is_none() {
|
||||
|
|
|
|||
|
|
@ -32,17 +32,22 @@ impl Term {
|
|||
Ok(term)
|
||||
}
|
||||
|
||||
pub fn clear() -> Result<()> {
|
||||
execute!(stdout(), Clear(ClearType::All))?;
|
||||
println!();
|
||||
stdout().flush()?;
|
||||
Ok(())
|
||||
#[inline]
|
||||
pub fn clear(stdout: &mut impl Write) -> Result<()> {
|
||||
execute!(stdout, Clear(ClearType::All))?;
|
||||
writeln!(stdout)?;
|
||||
Ok(stdout.flush()?)
|
||||
}
|
||||
|
||||
pub fn move_to(x: u16, y: u16) -> Result<()> { Ok(execute!(stdout(), MoveTo(x, y))?) }
|
||||
#[inline]
|
||||
pub fn move_to(stdout: &mut impl Write, x: u16, y: u16) -> Result<()> {
|
||||
Ok(execute!(stdout, MoveTo(x, y))?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_block() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBlock)?) }
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_bar() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBar)?) }
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue