Implemented cmd runtime expansion for the prompt

This commit is contained in:
2025-03-09 03:51:49 -04:00
parent 58abe3bc3d
commit 9b805c542c
6 changed files with 84 additions and 48 deletions

View File

@@ -196,7 +196,7 @@ pub fn format_cmd_runtime(dur: std::time::Duration) -> String {
result.push(string); result.push(string);
} }
if result.is_empty() && micros > 0 { if result.is_empty() && micros > 0 {
let string = format!("{}ms",micros); let string = format!("{}µs",micros);
result.push(string); result.push(string);
} }
@@ -209,8 +209,6 @@ fn tokenize_prompt(raw: &str) -> Vec<PromptTk> {
let mut tokens = vec![]; let mut tokens = vec![];
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
log!(DEBUG,tokens);
log!(DEBUG,ch);
match ch { match ch {
'\\' => { '\\' => {
// Push any accumulated text as a token // Push any accumulated text as a token
@@ -321,7 +319,9 @@ pub fn expand_prompt(raw: &str, shenv: &mut ShEnv) -> ShResult<String> {
PromptTk::Text(txt) => result.push_str(&txt), PromptTk::Text(txt) => result.push_str(&txt),
PromptTk::AnsiSeq(params) => result.push_str(&params), PromptTk::AnsiSeq(params) => result.push_str(&params),
PromptTk::Runtime => { PromptTk::Runtime => {
log!(INFO, "getting runtime");
if let Some(runtime) = shenv.meta().get_runtime() { if let Some(runtime) = shenv.meta().get_runtime() {
log!(DEBUG, runtime);
let runtime_fmt = format_cmd_runtime(runtime); let runtime_fmt = format_cmd_runtime(runtime);
result.push_str(&runtime_fmt); result.push_str(&runtime_fmt);
} }

View File

@@ -58,6 +58,7 @@ pub fn main() {
log!(TRACE, "Entered loop"); log!(TRACE, "Entered loop");
match prompt::read_line(&mut shenv) { match prompt::read_line(&mut shenv) {
Ok(line) => { Ok(line) => {
shenv.meta_mut().start_timer();
let _ = exec_input(line, &mut shenv).eprint(); let _ = exec_input(line, &mut shenv).eprint();
} }
Err(e) => { Err(e) => {

View File

@@ -301,7 +301,8 @@ tkrule_def!(Comment, |input: &str| {
if let Some('#') = chars.next() { if let Some('#') = chars.next() {
len += 1; len += 1;
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
if ch == '\n' { if ch == '\n' {
break break
} }
@@ -318,10 +319,12 @@ tkrule_def!(Whitespace, |input: &str| {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
match ch { match ch {
'\\' => { '\\' => {
len += 1; let chlen = ch.len_utf8();
len += chlen;
if let Some(ch) = chars.next() { if let Some(ch) = chars.next() {
if matches!(ch, ' ' | '\t' | '\n') { if matches!(ch, ' ' | '\t' | '\n') {
len += 1; let chlen = ch.len_utf8();
len += chlen;
} else { } else {
return None return None
} }
@@ -347,17 +350,20 @@ tkrule_def!(CasePat, |input:&str| {
let mut len = 0; let mut len = 0;
let mut is_casepat = false; let mut is_casepat = false;
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
match ch { match ch {
'\\' => { '\\' => {
if chars.next().is_some() { if let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
} }
} }
')' => { ')' => {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
if ch == ')' { if ch == ')' {
len += 1; let chlen = ch.len_utf8();
len += chlen;
} else { } else {
break break
} }
@@ -377,20 +383,24 @@ tkrule_def!(ArithSub, |input: &str| {
let mut len = 0; let mut len = 0;
let mut is_arith_sub = false; let mut is_arith_sub = false;
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
match ch { match ch {
'\\' => { '\\' => {
if chars.next().is_some() { if let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
} }
} }
'`' => { '`' => {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
match ch { match ch {
'\\' => { '\\' => {
if chars.next().is_some() { if let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
} }
} }
'`' => { '`' => {
@@ -446,11 +456,13 @@ tkrule_def!(Subshell, |input: &str| {
chars.next(); chars.next();
} }
'(' => { '(' => {
len += 1; let chlen = ch.len_utf8();
len += chlen;
paren_count += 1; paren_count += 1;
} }
')' => { ')' => {
len += 1; let chlen = ch.len_utf8();
len += chlen;
paren_count -= 1; paren_count -= 1;
if paren_count == 0 { if paren_count == 0 {
return Some(len); return Some(len);
@@ -670,8 +682,11 @@ tkrule_def!(Ident, |input: &str| {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
match ch { match ch {
'\\' => { '\\' => {
chars.next(); len += 1;
len += 2; if let Some(ch) = chars.next() {
let chlen = ch.len_utf8();
len += chlen;
}
} }
'>' | '<' | '$' | ' ' | '\t' | '\n' | ';' => { '>' | '<' | '$' | ' ' | '\t' | '\n' | ';' => {
match len { match len {
@@ -679,7 +694,10 @@ tkrule_def!(Ident, |input: &str| {
_ => return Some(len), _ => return Some(len),
} }
} }
_ => len += 1 _ => {
let chlen = ch.len_utf8();
len += chlen;
}
} }
} }
match len { match len {
@@ -702,7 +720,8 @@ tkrule_def!(Sep, |input: &str| {
if len == 0 { if len == 0 {
return None return None
} else { } else {
len += 1; let chlen = ch.len_utf8();
len += chlen;
} }
} }
';' | '\n' => len += 1, ';' | '\n' => len += 1,
@@ -733,11 +752,13 @@ tkrule_def!(SQuote, |input: &str| {
len += 2; len += 2;
} }
'\'' if !quoted => { '\'' if !quoted => {
len += 1; let chlen = ch.len_utf8();
len += chlen;
quoted = true; quoted = true;
} }
'\'' if quoted => { '\'' if quoted => {
len += 1; let chlen = ch.len_utf8();
len += chlen;
return Some(len) return Some(len)
} }
_ if !quoted => { _ if !quoted => {
@@ -758,11 +779,15 @@ tkrule_def!(DQuote, |input: &str| {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
match ch { match ch {
'\\' => { '\\' => {
chars.next(); len += 1;
len += 2; if let Some(ch) = chars.next() {
let chlen = ch.len_utf8();
len += chlen;
}
} }
'"' => { '"' => {
len += 1; let chlen = ch.len_utf8();
len += chlen;
quote_count += 1; quote_count += 1;
} }
' ' | '\t' | ';' | '\n' if quote_count % 2 == 0 => { ' ' | '\t' | ';' | '\n' if quote_count % 2 == 0 => {
@@ -776,7 +801,10 @@ tkrule_def!(DQuote, |input: &str| {
return None return None
} }
} }
_ => len += 1 _ => {
let chlen = ch.len_utf8();
len += chlen;
}
} }
} }
match len { match len {
@@ -838,8 +866,12 @@ tkrule_def!(CmdSub, |input: &str| {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
match ch { match ch {
'\\' => { '\\' => {
len += 2; len += 1;
chars.next(); if let Some(ch) = chars.next() {
let chlen = ch.len_utf8();
len += chlen;
chars.next();
}
} }
')' => { ')' => {
len += 1; len += 1;
@@ -1028,13 +1060,15 @@ tkrule_def!(RedirHeredoc, |mut input: &str| {
let mut body = ""; let mut body = "";
let mut body_len = 1; let mut body_len = 1;
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
match ch { match ch {
' ' | '\t' | '\n' | ';' if delim.is_empty() => return None, ' ' | '\t' | '\n' | ';' if delim.is_empty() => return None,
_ if delim.is_empty() => { _ if delim.is_empty() => {
delim_len += 1; delim_len += 1;
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
len += 1; let chlen = ch.len_utf8();
len += chlen;
match ch { match ch {
'\n' => { '\n' => {
delim = &input[..delim_len]; delim = &input[..delim_len];
@@ -1046,7 +1080,7 @@ tkrule_def!(RedirHeredoc, |mut input: &str| {
} }
} }
_ => { _ => {
body_len += 1; body_len += chlen;
body = &input[..body_len]; body = &input[..body_len];
if body.ends_with(&delim) { break } if body.ends_with(&delim) { break }
} }
@@ -1120,7 +1154,8 @@ tkrule_def!(RedirInFd, |input: &str| {
if !ch.is_ascii_digit() { if !ch.is_ascii_digit() {
break break
} }
len += 1; let chlen = ch.len_utf8();
len += chlen;
} }
if len <= 2 { if len <= 2 {
None None
@@ -1147,7 +1182,8 @@ tkrule_def!(RedirOutFd, |input: &str| {
if !ch.is_ascii_digit() { if !ch.is_ascii_digit() {
break break
} }
len += 1; let chlen = ch.len_utf8();
len += chlen;
} }
if len <= 2 { if len <= 2 {
None None
@@ -1170,7 +1206,8 @@ tkrule_def!(RedirFdOut, |input: &str| {
return Some(len) return Some(len)
} }
} }
len += 1; let chlen = char.len_utf8();
len += chlen;
} }
None None
}); });
@@ -1194,7 +1231,8 @@ tkrule_def!(RedirFdClobber, |input: &str| {
} }
} }
} }
len += 1; let chlen = char.len_utf8();
len += chlen;
} }
None None
}); });
@@ -1218,7 +1256,8 @@ tkrule_def!(RedirFdInOut, |input: &str| {
} }
} }
} }
len += 1; let chlen = char.len_utf8();
len += chlen;
} }
None None
}); });

View File

@@ -28,6 +28,7 @@ fn init_rl<'a>(shenv: &'a mut ShEnv) -> Editor<SynHelper<'a>, DefaultHistory> {
pub fn read_line(shenv: &mut ShEnv) -> ShResult<String> { pub fn read_line(shenv: &mut ShEnv) -> ShResult<String> {
log!(TRACE, "Entering prompt"); log!(TRACE, "Entering prompt");
shenv.meta_mut().stop_timer();
let ps1 = std::env::var("PS1").unwrap_or("\\$ ".styled(Style::Green | Style::Bold)); let ps1 = std::env::var("PS1").unwrap_or("\\$ ".styled(Style::Green | Style::Bold));
let prompt = expand_prompt(&ps1,shenv)?; let prompt = expand_prompt(&ps1,shenv)?;
let mut editor = init_rl(shenv); let mut editor = init_rl(shenv);

View File

@@ -13,9 +13,6 @@ pub fn check_delims(line: &str) -> bool {
while let Some(ch) = chars.next() { while let Some(ch) = chars.next() {
case_check.push(ch); case_check.push(ch);
if case_check.len() > 4 {
case_check = case_check[1..].to_string();
}
if case_check.ends_with("case") { if case_check.ends_with("case") {
case_depth += 1; case_depth += 1;
} }

View File

@@ -1,8 +1,9 @@
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use crate::prelude::*;
#[derive(Clone,Debug)] #[derive(Clone,Debug)]
pub struct MetaTab { pub struct MetaTab {
timer_start: Option<Instant>, timer_start: Instant,
last_runtime: Option<Duration>, last_runtime: Option<Duration>,
last_status: i32 last_status: i32
} }
@@ -10,19 +11,16 @@ pub struct MetaTab {
impl MetaTab { impl MetaTab {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
timer_start: None, timer_start: Instant::now(),
last_runtime: None, last_runtime: None,
last_status: 0 last_status: 0
} }
} }
pub fn start_timer(&mut self) { pub fn start_timer(&mut self) {
self.timer_start = Some(Instant::now()) self.timer_start = Instant::now();
} }
pub fn stop_timer(&mut self) { pub fn stop_timer(&mut self) {
let timer_start = self.timer_start.take(); self.last_runtime = Some(self.timer_start.elapsed());
if let Some(instant) = timer_start {
self.last_runtime = Some(instant.elapsed())
}
} }
pub fn get_runtime(&self) -> Option<Duration> { pub fn get_runtime(&self) -> Option<Duration> {
self.last_runtime self.last_runtime