use qem::{EditorTab, LoadPhase, TextPosition};
use std::env;
use std::path::PathBuf;
use std::thread;
use std::time::{Duration, Instant};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = env::args_os().skip(1);
let input = args
.next()
.map(PathBuf::from)
.ok_or("usage: cargo run --example editor_session --features editor -- <input> <output>")?;
let output = args
.next()
.map(PathBuf::from)
.ok_or("usage: cargo run --example editor_session --features editor -- <input> <output>")?;
let mut tab = EditorTab::new(1);
tab.open_file_async(input.clone())?;
wait_for_open(&mut tab, Duration::from_secs(5))?;
let _ = tab.try_insert(TextPosition::new(0, 0), "// generated by qem example\n")?;
tab.save_as_async(output.clone())?;
wait_for_save(&mut tab, Duration::from_secs(5))?;
let status = tab.status();
println!("opened: {}", input.display());
println!("saved copy: {}", output.display());
println!("bytes: {}", status.file_len());
println!("backing: {}", status.backing().as_str());
println!(
"cursor: line {}, column {}",
status.cursor().line(),
status.cursor().column()
);
println!("dirty: {}", status.is_dirty());
println!(
"edit capability at line 1: {:?}",
tab.edit_capability_at(TextPosition::new(0, 0))
);
Ok(())
}
fn wait_for_open(tab: &mut EditorTab, timeout: Duration) -> Result<(), Box<dyn std::error::Error>> {
let deadline = Instant::now() + timeout;
let mut last_snapshot = None;
loop {
if let Some(progress) = tab.loading_state() {
let snapshot = (
progress.completed_bytes(),
progress.total_bytes(),
progress.load_phase(),
);
if last_snapshot != Some(snapshot) {
println!(
"opening: {}/{} bytes, phase: {:?}",
progress.completed_bytes(),
progress.total_bytes(),
progress.load_phase().unwrap_or(LoadPhase::Opening)
);
last_snapshot = Some(snapshot);
}
}
if let Some(result) = tab.poll_load_job() {
result?;
return Ok(());
}
if !tab.is_loading() {
return Ok(());
}
if Instant::now() >= deadline {
return Err("background open timed out".into());
}
thread::sleep(Duration::from_millis(10));
}
}
fn wait_for_save(tab: &mut EditorTab, timeout: Duration) -> Result<(), Box<dyn std::error::Error>> {
let deadline = Instant::now() + timeout;
let mut last_snapshot = None;
loop {
if let Some(progress) = tab.save_state() {
let snapshot = (progress.completed_bytes(), progress.total_bytes());
if last_snapshot != Some(snapshot) {
println!(
"saving: {}/{} bytes to {}",
progress.completed_bytes(),
progress.total_bytes(),
progress.path().display()
);
last_snapshot = Some(snapshot);
}
}
if let Some(result) = tab.poll_save_job() {
result?;
return Ok(());
}
if !tab.is_saving() {
return Ok(());
}
if Instant::now() >= deadline {
return Err("background save timed out".into());
}
thread::sleep(Duration::from_millis(10));
}
}