diff options
author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2025-07-30 19:36:15 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2025-07-30 19:36:15 +0200 |
commit | 8a82d098e357ef29875fb5b37960cab46e72745f (patch) | |
tree | bb1821ab8bbb1b9584f002e3af30888cf2c244dd | |
parent | 3e5972991ae1b608e3907a7d2d10b24b6124176b (diff) |
Add trivial prompt handling.
-rw-r--r-- | src/main.rs | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs index 0547412..77ad9a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ +use std::collections::{LinkedList, VecDeque}; use crossterm::{cursor, execute, terminal}; use eyre::{bail, Result}; use regex::Regex; use rustyline::DefaultEditor; use std::io; use std::io::Write; -use std::path::PathBuf; +use std::path::{Component, Path, PathBuf}; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::thread::spawn; use rustyline::error::ReadlineError; @@ -16,9 +17,14 @@ fn main() -> Result<()> { color_eyre::install()?; let mut line_editor = DefaultEditor::new()?; + let mut prompt_spec = "$p$g"; loop { - let line = match line_editor.readline(">>> ") { + let cwd = std::env::current_dir()?; + let full_cwd = format_path(&cwd); + let interpolated_prompt = prompt_spec.replace("$p", &full_cwd).replace("$g", ">"); + + let line = match line_editor.readline(&interpolated_prompt) { Ok(line) => line, Err(ReadlineError::Eof) => break, Err(err) => return Err(err.into()) @@ -67,6 +73,71 @@ fn main() -> Result<()> { Ok(()) } +/// Turns "/home/mulk/foo/longfilenames/excellent.text" into "C:\\HOME\\MULK\\FOO\\LONGFILE~1\\EXCELL~1.TEX" +fn format_path(p: &Path) -> String { + use std::path::Component::*; + + let mut prefix: Option<String> = None; + let mut components = Vec::new(); + + for component in p.components() { + match component { + Normal(c) => { + let s = c.to_string_lossy().to_uppercase(); + let s_parts: Vec<&str> = s.splitn(2, '.').collect(); + + let mut name: String; + let mut ext: Option<String>; + if s_parts.len() == 1 { + name = s.clone(); + ext = None; + } else { + name = s_parts[0].into(); + ext = Some(s_parts[1].into()); + } + + let mut result = String::new(); + + if name.len() > 8 || ext.as_ref().map_or(false, |e| e.len() > 3) { + name = name.chars().take(6).collect::<String>(); + name.push_str("~1"); + } + result.push_str(&name.to_uppercase()); + + if let Some(mut e) = ext { + if e.len() > 3 { + e = e.chars().take(3).collect::<String>(); + } + result.push_str("."); + result.push_str(&e.to_uppercase()); + } + + components.push(result); + } + + Prefix(c) => prefix = Some(component.as_os_str().to_string_lossy().to_uppercase()), + + RootDir => { + if prefix.is_none() { + prefix = Some("C:".into()) + } + components.push("".into()); + } + + CurDir => components.push(".".into()), + + ParentDir => components.push("..".into()), + } + } + + let mut result = String::new(); + if let Some(p) = prefix { + result.push_str(&p) + }; + result.push_str(&components.join("\\")); + result +} + #[derive(Debug)] enum FileSpec { Con, |