Implemented cmd runtime expansion for the prompt
This commit is contained in:
@@ -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(¶ms),
|
PromptTk::AnsiSeq(params) => result.push_str(¶ms),
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
107
src/parse/lex.rs
107
src/parse/lex.rs
@@ -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,9 +866,13 @@ 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;
|
||||||
|
if let Some(ch) = chars.next() {
|
||||||
|
let chlen = ch.len_utf8();
|
||||||
|
len += chlen;
|
||||||
chars.next();
|
chars.next();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
')' => {
|
')' => {
|
||||||
len += 1;
|
len += 1;
|
||||||
return Some(len)
|
return Some(len)
|
||||||
@@ -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
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user