mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-18 14:21:32 +03:00
perf: add BufWriter
to Stderr
to avoid frequent system calls and increase rendering frame rate (#849)
This commit is contained in:
parent
06e9fb8e67
commit
66d12da09d
@ -1,4 +1,4 @@
|
|||||||
use std::{env, io::Read};
|
use std::{env, io::{stderr, LineWriter, Read}};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use crossterm::{cursor::{RestorePosition, SavePosition}, execute, style::Print, terminal::{disable_raw_mode, enable_raw_mode}};
|
use crossterm::{cursor::{RestorePosition, SavePosition}, execute, style::Print, terminal::{disable_raw_mode, enable_raw_mode}};
|
||||||
@ -114,7 +114,7 @@ impl Emulator {
|
|||||||
pub fn via_csi() -> Result<Self> {
|
pub fn via_csi() -> Result<Self> {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
execute!(
|
execute!(
|
||||||
std::io::stderr(),
|
LineWriter::new(stderr()),
|
||||||
SavePosition,
|
SavePosition,
|
||||||
Print("\x1b[>q\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c"),
|
Print("\x1b[>q\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c"),
|
||||||
RestorePosition
|
RestorePosition
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{io::{stderr, BufWriter, Write}, path::Path};
|
use std::{io::Write, path::Path};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::{engine::general_purpose, Engine};
|
use base64::{engine::general_purpose, Engine};
|
||||||
@ -19,16 +19,15 @@ impl Iterm2 {
|
|||||||
|
|
||||||
Adaptor::Iterm2.image_hide()?;
|
Adaptor::Iterm2.image_hide()?;
|
||||||
Adaptor::shown_store(rect, size);
|
Adaptor::shown_store(rect, size);
|
||||||
Term::move_lock(stderr().lock(), (rect.x, rect.y), |stderr| {
|
Term::move_lock((rect.x, rect.y), |stderr| {
|
||||||
stderr.write_all(&b)?;
|
stderr.write_all(&b)?;
|
||||||
Ok(size)
|
Ok(size)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn image_erase(rect: Rect) -> Result<()> {
|
pub(super) fn image_erase(rect: Rect) -> Result<()> {
|
||||||
let stderr = BufWriter::new(stderr().lock());
|
|
||||||
let s = " ".repeat(rect.width as usize);
|
let s = " ".repeat(rect.width as usize);
|
||||||
Term::move_lock(stderr, (0, 0), |stderr| {
|
Term::move_lock((0, 0), |stderr| {
|
||||||
for y in rect.top()..rect.bottom() {
|
for y in rect.top()..rect.bottom() {
|
||||||
Term::move_to(stderr, rect.x, y)?;
|
Term::move_to(stderr, rect.x, y)?;
|
||||||
write!(stderr, "{s}")?;
|
write!(stderr, "{s}")?;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use core::str;
|
use core::str;
|
||||||
use std::{io::{stderr, BufWriter, Write}, path::Path};
|
use std::{io::Write, path::Path};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::{engine::general_purpose, Engine};
|
use base64::{engine::general_purpose, Engine};
|
||||||
@ -322,7 +322,7 @@ impl Kitty {
|
|||||||
|
|
||||||
Adaptor::Kitty.image_hide()?;
|
Adaptor::Kitty.image_hide()?;
|
||||||
Adaptor::shown_store(rect, size);
|
Adaptor::shown_store(rect, size);
|
||||||
Term::move_lock(stderr().lock(), (rect.x, rect.y), |stderr| {
|
Term::move_lock((rect.x, rect.y), |stderr| {
|
||||||
stderr.write_all(&b1)?;
|
stderr.write_all(&b1)?;
|
||||||
stderr.write_all(&b2)?;
|
stderr.write_all(&b2)?;
|
||||||
Ok(size)
|
Ok(size)
|
||||||
@ -330,9 +330,8 @@ impl Kitty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn image_erase(rect: Rect) -> Result<()> {
|
pub(super) fn image_erase(rect: Rect) -> Result<()> {
|
||||||
let stderr = BufWriter::new(stderr().lock());
|
|
||||||
let s = " ".repeat(rect.width as usize);
|
let s = " ".repeat(rect.width as usize);
|
||||||
Term::move_lock(stderr, (0, 0), |stderr| {
|
Term::move_lock((0, 0), |stderr| {
|
||||||
for y in rect.top()..rect.bottom() {
|
for y in rect.top()..rect.bottom() {
|
||||||
Term::move_to(stderr, rect.x, y)?;
|
Term::move_to(stderr, rect.x, y)?;
|
||||||
write!(stderr, "{s}")?;
|
write!(stderr, "{s}")?;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use core::str;
|
use core::str;
|
||||||
use std::{io::{stderr, Write}, path::Path};
|
use std::{io::{stderr, LineWriter, Write}, path::Path};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::{engine::general_purpose, Engine};
|
use base64::{engine::general_purpose, Engine};
|
||||||
@ -20,7 +20,7 @@ impl KittyOld {
|
|||||||
|
|
||||||
Adaptor::KittyOld.image_hide()?;
|
Adaptor::KittyOld.image_hide()?;
|
||||||
Adaptor::shown_store(rect, size);
|
Adaptor::shown_store(rect, size);
|
||||||
Term::move_lock(stderr().lock(), (rect.x, rect.y), |stderr| {
|
Term::move_lock((rect.x, rect.y), |stderr| {
|
||||||
stderr.write_all(&b)?;
|
stderr.write_all(&b)?;
|
||||||
Ok(size)
|
Ok(size)
|
||||||
})
|
})
|
||||||
@ -28,7 +28,7 @@ impl KittyOld {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn image_erase() -> Result<()> {
|
pub(super) fn image_erase() -> Result<()> {
|
||||||
let mut stderr = stderr().lock();
|
let mut stderr = LineWriter::new(stderr());
|
||||||
write!(stderr, "{}_Gq=1,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?;
|
write!(stderr, "{}_Gq=1,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?;
|
||||||
stderr.flush()?;
|
stderr.flush()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{io::{stderr, BufWriter, Write}, path::Path};
|
use std::{io::Write, path::Path};
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use color_quant::NeuQuant;
|
use color_quant::NeuQuant;
|
||||||
@ -19,16 +19,15 @@ impl Sixel {
|
|||||||
|
|
||||||
Adaptor::Sixel.image_hide()?;
|
Adaptor::Sixel.image_hide()?;
|
||||||
Adaptor::shown_store(rect, size);
|
Adaptor::shown_store(rect, size);
|
||||||
Term::move_lock(stderr().lock(), (rect.x, rect.y), |stderr| {
|
Term::move_lock((rect.x, rect.y), |stderr| {
|
||||||
stderr.write_all(&b)?;
|
stderr.write_all(&b)?;
|
||||||
Ok(size)
|
Ok(size)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn image_erase(rect: Rect) -> Result<()> {
|
pub(super) fn image_erase(rect: Rect) -> Result<()> {
|
||||||
let stderr = BufWriter::new(stderr().lock());
|
|
||||||
let s = " ".repeat(rect.width as usize);
|
let s = " ".repeat(rect.width as usize);
|
||||||
Term::move_lock(stderr, (0, 0), |stderr| {
|
Term::move_lock((0, 0), |stderr| {
|
||||||
for y in rect.top()..rect.bottom() {
|
for y in rect.top()..rect.bottom() {
|
||||||
Term::move_to(stderr, rect.x, y)?;
|
Term::move_to(stderr, rect.x, y)?;
|
||||||
write!(stderr, "{s}")?;
|
write!(stderr, "{s}")?;
|
||||||
|
@ -54,7 +54,7 @@ impl Clipboard {
|
|||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub async fn set(&self, s: impl AsRef<std::ffi::OsStr>) {
|
pub async fn set(&self, s: impl AsRef<std::ffi::OsStr>) {
|
||||||
use std::{io::stderr, process::Stdio};
|
use std::{io::{stderr, BufWriter}, process::Stdio};
|
||||||
|
|
||||||
use crossterm::execute;
|
use crossterm::execute;
|
||||||
use tokio::{io::AsyncWriteExt, process::Command};
|
use tokio::{io::AsyncWriteExt, process::Command};
|
||||||
@ -62,7 +62,7 @@ impl Clipboard {
|
|||||||
|
|
||||||
*self.content.lock() = s.as_ref().to_owned();
|
*self.content.lock() = s.as_ref().to_owned();
|
||||||
if in_ssh_connection() {
|
if in_ssh_connection() {
|
||||||
execute!(stderr(), osc52::SetClipboard::new(s.as_ref())).ok();
|
execute!(BufWriter::new(stderr()), osc52::SetClipboard::new(s.as_ref())).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
let all = [
|
let all = [
|
||||||
|
@ -78,7 +78,7 @@ impl Selected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn remove_same(&mut self, urls: &[impl AsRef<Url>]) -> usize {
|
fn remove_same(&mut self, urls: &[impl AsRef<Url>]) -> usize {
|
||||||
let count = urls.iter().map(|u| self.inner.remove(u.as_ref())).filter_map(|v| v).count();
|
let count = urls.iter().filter_map(|u| self.inner.remove(u.as_ref())).count();
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io::{stderr, Write};
|
use std::{io::{stderr, BufWriter, LineWriter, Write}, mem};
|
||||||
|
|
||||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||||
use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time};
|
use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time};
|
||||||
@ -18,7 +18,7 @@ impl Tasks {
|
|||||||
let _permit = HIDER.acquire().await.unwrap();
|
let _permit = HIDER.acquire().await.unwrap();
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel();
|
let (tx, mut rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
let buffered = {
|
let mut buffered = {
|
||||||
let mut ongoing = scheduler.ongoing.lock();
|
let mut ongoing = scheduler.ongoing.lock();
|
||||||
let Some(task) = ongoing.get_mut(id) else { return };
|
let Some(task) = ongoing.get_mut(id) else { return };
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ impl Tasks {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Term::clear(&mut stderr()).ok();
|
Term::clear(&mut stderr()).ok();
|
||||||
stderr().write_all(buffered.as_bytes()).ok();
|
BufWriter::new(stderr().lock()).write_all(mem::take(&mut buffered).as_bytes()).ok();
|
||||||
enable_raw_mode().ok();
|
enable_raw_mode().ok();
|
||||||
|
|
||||||
let mut stdin = stdin();
|
let mut stdin = stdin();
|
||||||
@ -41,7 +41,7 @@ impl Tasks {
|
|||||||
loop {
|
loop {
|
||||||
select! {
|
select! {
|
||||||
Some(line) = rx.recv() => {
|
Some(line) = rx.recv() => {
|
||||||
let mut stderr = stderr().lock();
|
let mut stderr = LineWriter::new(stderr().lock());
|
||||||
stderr.write_all(line.as_bytes()).ok();
|
stderr.write_all(line.as_bytes()).ok();
|
||||||
stderr.write_all(b"\r\n").ok();
|
stderr.write_all(b"\r\n").ok();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::sync::atomic::Ordering;
|
use std::{io::{stderr, BufWriter}, sync::atomic::Ordering};
|
||||||
|
|
||||||
use ratatui::{backend::{Backend, CrosstermBackend}, CompletedFrame};
|
use ratatui::{backend::{Backend, CrosstermBackend}, CompletedFrame};
|
||||||
use yazi_plugin::elements::COLLISION;
|
use yazi_plugin::elements::COLLISION;
|
||||||
@ -71,7 +71,7 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut backend = CrosstermBackend::new(std::io::stderr().lock());
|
let mut backend = CrosstermBackend::new(BufWriter::new(stderr().lock()));
|
||||||
backend.draw(patches.into_iter()).ok();
|
backend.draw(patches.into_iter()).ok();
|
||||||
if let Some((x, y)) = cursor {
|
if let Some((x, y)) = cursor {
|
||||||
backend.show_cursor().ok();
|
backend.show_cursor().ok();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::io::{stderr, Write};
|
use std::io::{stderr, BufWriter, StderrLock, Write};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossterm::{cursor::{MoveTo, RestorePosition, SavePosition, SetCursorStyle}, queue};
|
use crossterm::{cursor::{MoveTo, RestorePosition, SavePosition, SetCursorStyle}, queue};
|
||||||
@ -11,34 +11,34 @@ impl Term {
|
|||||||
|
|
||||||
// FIXME: remove this function
|
// FIXME: remove this function
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn move_lock<W, F, T>(mut w: W, (x, y): (u16, u16), cb: F) -> Result<T>
|
pub fn move_lock<F, T>((x, y): (u16, u16), cb: F) -> Result<T>
|
||||||
where
|
where
|
||||||
W: Write,
|
F: FnOnce(&mut BufWriter<StderrLock>) -> Result<T>,
|
||||||
F: FnOnce(&mut W) -> Result<T>,
|
|
||||||
{
|
{
|
||||||
|
let mut buf = BufWriter::new(stderr().lock());
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
use std::{thread, time::Duration};
|
use std::{thread, time::Duration};
|
||||||
|
|
||||||
use crossterm::cursor::{Hide, Show};
|
use crossterm::cursor::{Hide, Show};
|
||||||
queue!(&mut w, SavePosition, MoveTo(x, y), Show)?;
|
queue!(buf, SavePosition, MoveTo(x, y), Show)?;
|
||||||
|
|
||||||
// I really don't want to add this,
|
// I really don't want to add this,
|
||||||
// but on Windows the cursor position will not synchronize in time occasionally
|
// but on Windows the cursor position will not synchronize in time occasionally
|
||||||
w.flush()?;
|
buf.flush()?;
|
||||||
thread::sleep(Duration::from_millis(1));
|
thread::sleep(Duration::from_millis(1));
|
||||||
|
|
||||||
let result = cb(&mut w);
|
let result = cb(&mut buf);
|
||||||
queue!(&mut w, Hide, RestorePosition)?;
|
queue!(buf, Hide, RestorePosition)?;
|
||||||
w.flush()?;
|
buf.flush()?;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
queue!(&mut w, SavePosition, MoveTo(x, y))?;
|
queue!(buf, SavePosition, MoveTo(x, y))?;
|
||||||
let result = cb(&mut w);
|
let result = cb(&mut buf);
|
||||||
queue!(&mut w, RestorePosition)?;
|
queue!(buf, RestorePosition)?;
|
||||||
w.flush()?;
|
buf.flush()?;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{io::{self, stderr, Stderr, Write}, mem, ops::{Deref, DerefMut}, sync::atomic::{AtomicBool, Ordering}};
|
use std::{io::{self, stderr, BufWriter, Stderr, Write}, mem, ops::{Deref, DerefMut}, sync::atomic::{AtomicBool, Ordering}};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossterm::{event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
|
use crossterm::{event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
|
||||||
@ -7,7 +7,7 @@ use ratatui::{backend::CrosstermBackend, buffer::Buffer, layout::Rect, Completed
|
|||||||
static CSI_U: AtomicBool = AtomicBool::new(false);
|
static CSI_U: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
pub struct Term {
|
pub struct Term {
|
||||||
inner: Terminal<CrosstermBackend<Stderr>>,
|
inner: Terminal<CrosstermBackend<BufWriter<Stderr>>>,
|
||||||
last_area: Rect,
|
last_area: Rect,
|
||||||
last_buffer: Buffer,
|
last_buffer: Buffer,
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ pub struct Term {
|
|||||||
impl Term {
|
impl Term {
|
||||||
pub fn start() -> Result<Self> {
|
pub fn start() -> Result<Self> {
|
||||||
let mut term = Self {
|
let mut term = Self {
|
||||||
inner: Terminal::new(CrosstermBackend::new(stderr()))?,
|
inner: Terminal::new(CrosstermBackend::new(BufWriter::new(stderr())))?,
|
||||||
last_area: Default::default(),
|
last_area: Default::default(),
|
||||||
last_buffer: Default::default(),
|
last_buffer: Default::default(),
|
||||||
};
|
};
|
||||||
@ -144,7 +144,7 @@ impl Drop for Term {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Term {
|
impl Deref for Term {
|
||||||
type Target = Terminal<CrosstermBackend<Stderr>>;
|
type Target = Terminal<CrosstermBackend<BufWriter<Stderr>>>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target { &self.inner }
|
fn deref(&self) -> &Self::Target { &self.inner }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user