From 465b14d71b2fed2e992e212ec08560c0994e8e10 Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Fri, 23 Aug 2024 11:15:42 +0300 Subject: [PATCH] Implement ExternalPrinterWriter To enable duplex output of log messages Fixes #797 --- examples/external_print.rs | 25 ++++++++++++++++++++++--- src/lib.rs | 25 ++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/examples/external_print.rs b/examples/external_print.rs index f93769e95..0bbd2c520 100644 --- a/examples/external_print.rs +++ b/examples/external_print.rs @@ -1,5 +1,11 @@ +extern crate env_logger; +extern crate log; + +use std::io::Write; use std::thread; use std::time::Duration; +use env_logger::Target; +use log::LevelFilter; use rand::{thread_rng, Rng}; @@ -8,10 +14,24 @@ use rustyline::{DefaultEditor, ExternalPrinter, Result}; fn main() -> Result<()> { let mut rl = DefaultEditor::new()?; let mut printer = rl.create_external_printer()?; + + env_logger::builder() + .filter_level(LevelFilter::Info) + .target(Target::Pipe(rl.create_external_writer()?)) + .init(); + thread::spawn(move || { + loop { + log::info!("Log Message"); + thread::sleep(Duration::from_secs(3)); + } + }); + + let mut writer = rl.create_external_writer().unwrap(); thread::spawn(move || { let mut rng = thread_rng(); let mut i = 0usize; loop { + writer.write("writing without newline".as_bytes()); printer .print(format!("External message #{i}")) .expect("External print failure"); @@ -23,7 +43,6 @@ fn main() -> Result<()> { loop { let line = rl.readline("> ")?; - rl.add_history_entry(line.as_str())?; - println!("Line: {line}"); + println!("Read Line: {line}"); } -} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 10fd4b68a..1a7785ec9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,7 @@ mod undo; pub mod validate; use std::fmt; -use std::io::{self, BufRead, Write}; +use std::io::{self, BufRead, Read, Write}; use std::path::Path; use std::result; @@ -923,6 +923,12 @@ impl Editor { self.term.create_external_printer() } + /// Create a wrapper for the external printer implementing std::io::Write + pub fn create_external_writer(&mut self) -> Result> { + self.create_external_printer().map(|printer| + Box::new(ExternalPrinterWriter(Box::new(printer))) as Box) + } + /// Change cursor visibility pub fn set_cursor_visibility( &mut self, @@ -932,6 +938,23 @@ impl Editor { } } +struct ExternalPrinterWriter

(Box

); + +impl

Write for ExternalPrinterWriter

+where P: ExternalPrinter + Send { + fn write(&mut self, mut buf: &[u8]) -> io::Result { + let mut string = String::with_capacity(buf.len()); + buf.read_to_string(&mut string).inspect(|_| { + self.0.print(string); //.strip_suffix('\n').map(|s| s.to_string()).unwrap_or(string)); + }) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + + impl config::Configurer for Editor { fn config_mut(&mut self) -> &mut Config { &mut self.config