diff --git a/yazi-adaptor/src/emulator.rs b/yazi-adaptor/src/emulator.rs index 0a6b4868..12f1e78c 100644 --- a/yazi-adaptor/src/emulator.rs +++ b/yazi-adaptor/src/emulator.rs @@ -1,4 +1,4 @@ -use std::{env, io::Read}; +use std::{env, io::{stderr, LineWriter, Read}}; use anyhow::{anyhow, Result}; 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 { enable_raw_mode()?; execute!( - std::io::stderr(), + LineWriter::new(stderr()), SavePosition, Print("\x1b[>q\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c"), RestorePosition diff --git a/yazi-adaptor/src/iterm2.rs b/yazi-adaptor/src/iterm2.rs index 9b128364..5efcfce6 100644 --- a/yazi-adaptor/src/iterm2.rs +++ b/yazi-adaptor/src/iterm2.rs @@ -1,4 +1,4 @@ -use std::{io::{stderr, BufWriter, Write}, path::Path}; +use std::{io::Write, path::Path}; use anyhow::Result; use base64::{engine::general_purpose, Engine}; @@ -19,16 +19,15 @@ impl Iterm2 { Adaptor::Iterm2.image_hide()?; 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)?; Ok(size) }) } pub(super) fn image_erase(rect: Rect) -> Result<()> { - let stderr = BufWriter::new(stderr().lock()); 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() { Term::move_to(stderr, rect.x, y)?; write!(stderr, "{s}")?; diff --git a/yazi-adaptor/src/kitty.rs b/yazi-adaptor/src/kitty.rs index 8b1d3a98..d86990f2 100644 --- a/yazi-adaptor/src/kitty.rs +++ b/yazi-adaptor/src/kitty.rs @@ -1,5 +1,5 @@ use core::str; -use std::{io::{stderr, BufWriter, Write}, path::Path}; +use std::{io::Write, path::Path}; use anyhow::Result; use base64::{engine::general_purpose, Engine}; @@ -322,7 +322,7 @@ impl Kitty { Adaptor::Kitty.image_hide()?; 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(&b2)?; Ok(size) @@ -330,9 +330,8 @@ impl Kitty { } pub(super) fn image_erase(rect: Rect) -> Result<()> { - let stderr = BufWriter::new(stderr().lock()); 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() { Term::move_to(stderr, rect.x, y)?; write!(stderr, "{s}")?; diff --git a/yazi-adaptor/src/kitty_old.rs b/yazi-adaptor/src/kitty_old.rs index 9f409948..cf0a2df9 100644 --- a/yazi-adaptor/src/kitty_old.rs +++ b/yazi-adaptor/src/kitty_old.rs @@ -1,5 +1,5 @@ use core::str; -use std::{io::{stderr, Write}, path::Path}; +use std::{io::{stderr, LineWriter, Write}, path::Path}; use anyhow::Result; use base64::{engine::general_purpose, Engine}; @@ -20,7 +20,7 @@ impl KittyOld { Adaptor::KittyOld.image_hide()?; 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)?; Ok(size) }) @@ -28,7 +28,7 @@ impl KittyOld { #[inline] 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)?; stderr.flush()?; Ok(()) diff --git a/yazi-adaptor/src/sixel.rs b/yazi-adaptor/src/sixel.rs index 8ab3a2e5..eb4b22ab 100644 --- a/yazi-adaptor/src/sixel.rs +++ b/yazi-adaptor/src/sixel.rs @@ -1,4 +1,4 @@ -use std::{io::{stderr, BufWriter, Write}, path::Path}; +use std::{io::Write, path::Path}; use anyhow::{bail, Result}; use color_quant::NeuQuant; @@ -19,16 +19,15 @@ impl Sixel { Adaptor::Sixel.image_hide()?; 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)?; Ok(size) }) } pub(super) fn image_erase(rect: Rect) -> Result<()> { - let stderr = BufWriter::new(stderr().lock()); 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() { Term::move_to(stderr, rect.x, y)?; write!(stderr, "{s}")?; diff --git a/yazi-core/src/clipboard.rs b/yazi-core/src/clipboard.rs index fe329de7..710fd3a7 100644 --- a/yazi-core/src/clipboard.rs +++ b/yazi-core/src/clipboard.rs @@ -54,7 +54,7 @@ impl Clipboard { #[cfg(unix)] pub async fn set(&self, s: impl AsRef) { - use std::{io::stderr, process::Stdio}; + use std::{io::{stderr, BufWriter}, process::Stdio}; use crossterm::execute; use tokio::{io::AsyncWriteExt, process::Command}; @@ -62,7 +62,7 @@ impl Clipboard { *self.content.lock() = s.as_ref().to_owned(); 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 = [ diff --git a/yazi-core/src/tab/selected.rs b/yazi-core/src/tab/selected.rs index 8f6f3c06..8d75a1d3 100644 --- a/yazi-core/src/tab/selected.rs +++ b/yazi-core/src/tab/selected.rs @@ -78,7 +78,7 @@ impl Selected { } fn remove_same(&mut self, urls: &[impl AsRef]) -> 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 { return 0; } diff --git a/yazi-core/src/tasks/commands/inspect.rs b/yazi-core/src/tasks/commands/inspect.rs index 2fa8495e..4910a79b 100644 --- a/yazi-core/src/tasks/commands/inspect.rs +++ b/yazi-core/src/tasks/commands/inspect.rs @@ -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 tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time}; @@ -18,7 +18,7 @@ impl Tasks { let _permit = HIDER.acquire().await.unwrap(); let (tx, mut rx) = mpsc::unbounded_channel(); - let buffered = { + let mut buffered = { let mut ongoing = scheduler.ongoing.lock(); let Some(task) = ongoing.get_mut(id) else { return }; @@ -33,7 +33,7 @@ impl Tasks { }); 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(); let mut stdin = stdin(); @@ -41,7 +41,7 @@ impl Tasks { loop { select! { 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(b"\r\n").ok(); } diff --git a/yazi-fm/src/app/commands/render.rs b/yazi-fm/src/app/commands/render.rs index 6940560a..df5808d0 100644 --- a/yazi-fm/src/app/commands/render.rs +++ b/yazi-fm/src/app/commands/render.rs @@ -1,4 +1,4 @@ -use std::sync::atomic::Ordering; +use std::{io::{stderr, BufWriter}, sync::atomic::Ordering}; use ratatui::{backend::{Backend, CrosstermBackend}, CompletedFrame}; 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(); if let Some((x, y)) = cursor { backend.show_cursor().ok(); diff --git a/yazi-shared/src/term/cursor.rs b/yazi-shared/src/term/cursor.rs index b74a87c6..4cbbd0f2 100644 --- a/yazi-shared/src/term/cursor.rs +++ b/yazi-shared/src/term/cursor.rs @@ -1,4 +1,4 @@ -use std::io::{stderr, Write}; +use std::io::{stderr, BufWriter, StderrLock, Write}; use anyhow::Result; use crossterm::{cursor::{MoveTo, RestorePosition, SavePosition, SetCursorStyle}, queue}; @@ -11,34 +11,34 @@ impl Term { // FIXME: remove this function #[inline] - pub fn move_lock(mut w: W, (x, y): (u16, u16), cb: F) -> Result + pub fn move_lock((x, y): (u16, u16), cb: F) -> Result where - W: Write, - F: FnOnce(&mut W) -> Result, + F: FnOnce(&mut BufWriter) -> Result, { + let mut buf = BufWriter::new(stderr().lock()); #[cfg(windows)] { use std::{thread, time::Duration}; 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, // but on Windows the cursor position will not synchronize in time occasionally - w.flush()?; + buf.flush()?; thread::sleep(Duration::from_millis(1)); - let result = cb(&mut w); - queue!(&mut w, Hide, RestorePosition)?; - w.flush()?; + let result = cb(&mut buf); + queue!(buf, Hide, RestorePosition)?; + buf.flush()?; result } #[cfg(unix)] { - queue!(&mut w, SavePosition, MoveTo(x, y))?; - let result = cb(&mut w); - queue!(&mut w, RestorePosition)?; - w.flush()?; + queue!(buf, SavePosition, MoveTo(x, y))?; + let result = cb(&mut buf); + queue!(buf, RestorePosition)?; + buf.flush()?; result } } diff --git a/yazi-shared/src/term/term.rs b/yazi-shared/src/term/term.rs index 22e1a1bb..83bfe929 100644 --- a/yazi-shared/src/term/term.rs +++ b/yazi-shared/src/term/term.rs @@ -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 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); pub struct Term { - inner: Terminal>, + inner: Terminal>>, last_area: Rect, last_buffer: Buffer, } @@ -15,7 +15,7 @@ pub struct Term { impl Term { pub fn start() -> Result { let mut term = Self { - inner: Terminal::new(CrosstermBackend::new(stderr()))?, + inner: Terminal::new(CrosstermBackend::new(BufWriter::new(stderr())))?, last_area: Default::default(), last_buffer: Default::default(), }; @@ -144,7 +144,7 @@ impl Drop for Term { } impl Deref for Term { - type Target = Terminal>; + type Target = Terminal>>; fn deref(&self) -> &Self::Target { &self.inner } }