Prompt now only redraws on completed jobs and new commands
Tab completion now finds env var names as well as internally set names
This commit is contained in:
13
src/main.rs
13
src/main.rs
@@ -34,7 +34,7 @@ use crate::prelude::*;
|
|||||||
use crate::prompt::get_prompt;
|
use crate::prompt::get_prompt;
|
||||||
use crate::prompt::readline::term::{LineWriter, RawModeGuard, raw_mode};
|
use crate::prompt::readline::term::{LineWriter, RawModeGuard, raw_mode};
|
||||||
use crate::prompt::readline::{Prompt, ReadlineEvent, ShedVi};
|
use crate::prompt::readline::{Prompt, ReadlineEvent, ShedVi};
|
||||||
use crate::signal::{GOT_SIGWINCH, QUIT_CODE, check_signals, sig_setup, signals_pending};
|
use crate::signal::{GOT_SIGWINCH, JOB_DONE, QUIT_CODE, check_signals, sig_setup, signals_pending};
|
||||||
use crate::state::{read_logic, source_rc, write_jobs, write_meta};
|
use crate::state::{read_logic, source_rc, write_jobs, write_meta};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use state::{read_vars, write_vars};
|
use state::{read_vars, write_vars};
|
||||||
@@ -186,7 +186,7 @@ fn shed_interactive() -> ShResult<()> {
|
|||||||
match e.kind() {
|
match e.kind() {
|
||||||
ShErrKind::ClearReadline => {
|
ShErrKind::ClearReadline => {
|
||||||
// Ctrl+C - clear current input and show new prompt
|
// Ctrl+C - clear current input and show new prompt
|
||||||
readline.reset(Prompt::new());
|
readline.reset();
|
||||||
}
|
}
|
||||||
ShErrKind::CleanExit(code) => {
|
ShErrKind::CleanExit(code) => {
|
||||||
QUIT_CODE.store(*code, Ordering::SeqCst);
|
QUIT_CODE.store(*code, Ordering::SeqCst);
|
||||||
@@ -200,9 +200,14 @@ fn shed_interactive() -> ShResult<()> {
|
|||||||
if GOT_SIGWINCH.swap(false, Ordering::SeqCst) {
|
if GOT_SIGWINCH.swap(false, Ordering::SeqCst) {
|
||||||
log::info!("Window size change detected, updating readline dimensions");
|
log::info!("Window size change detected, updating readline dimensions");
|
||||||
readline.writer.update_t_cols();
|
readline.writer.update_t_cols();
|
||||||
|
readline.prompt_mut().refresh()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if JOB_DONE.swap(false, Ordering::SeqCst) {
|
||||||
|
// update the prompt so any job count escape sequences update dynamically
|
||||||
|
readline.prompt_mut().refresh()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
readline.prompt_mut().refresh();
|
|
||||||
readline.print_line(false)?;
|
readline.print_line(false)?;
|
||||||
|
|
||||||
// Poll for stdin input
|
// Poll for stdin input
|
||||||
@@ -265,7 +270,7 @@ fn shed_interactive() -> ShResult<()> {
|
|||||||
readline.writer.flush_write("\n")?;
|
readline.writer.flush_write("\n")?;
|
||||||
|
|
||||||
// Reset for next command with fresh prompt
|
// Reset for next command with fresh prompt
|
||||||
readline.reset(Prompt::new());
|
readline.reset();
|
||||||
let real_end = start.elapsed();
|
let real_end = start.elapsed();
|
||||||
log::info!("Total round trip time: {:.2?}", real_end);
|
log::info!("Total round trip time: {:.2?}", real_end);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ impl ShedVi {
|
|||||||
|
|
||||||
|
|
||||||
/// Reset readline state for a new prompt
|
/// Reset readline state for a new prompt
|
||||||
pub fn reset(&mut self, prompt: Prompt) {
|
pub fn reset(&mut self) {
|
||||||
self.prompt = prompt;
|
self.prompt = Prompt::new();
|
||||||
self.editor = Default::default();
|
self.editor = Default::default();
|
||||||
self.mode = Box::new(ViInsert::new());
|
self.mode = Box::new(ViInsert::new());
|
||||||
self.old_layout = None;
|
self.old_layout = None;
|
||||||
@@ -516,9 +516,7 @@ impl ShedVi {
|
|||||||
let line = self.line_text();
|
let line = self.line_text();
|
||||||
let new_layout = self.get_layout(&line);
|
let new_layout = self.get_layout(&line);
|
||||||
let pending_seq = self.mode.pending_seq();
|
let pending_seq = self.mode.pending_seq();
|
||||||
let mut prompt_string_right = env::var("PSR")
|
let mut prompt_string_right = self.prompt.psr_expanded.clone();
|
||||||
.map(|psr| expand_prompt(&psr).unwrap())
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
if prompt_string_right.as_ref().is_some_and(|psr| psr.lines().count() > 1) {
|
if prompt_string_right.as_ref().is_some_and(|psr| psr.lines().count() > 1) {
|
||||||
log::warn!("PSR has multiple lines, truncating to one line");
|
log::warn!("PSR has multiple lines, truncating to one line");
|
||||||
|
|||||||
@@ -346,7 +346,6 @@ impl ViNormal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// End the parse and clear the pending sequence
|
/// End the parse and clear the pending sequence
|
||||||
#[track_caller]
|
|
||||||
pub fn quit_parse(&mut self) -> Option<ViCmd> {
|
pub fn quit_parse(&mut self) -> Option<ViCmd> {
|
||||||
self.clear_cmd();
|
self.clear_cmd();
|
||||||
None
|
None
|
||||||
@@ -1137,7 +1136,6 @@ impl ViVisual {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// End the parse and clear the pending sequence
|
/// End the parse and clear the pending sequence
|
||||||
#[track_caller]
|
|
||||||
pub fn quit_parse(&mut self) -> Option<ViCmd> {
|
pub fn quit_parse(&mut self) -> Option<ViCmd> {
|
||||||
self.clear_cmd();
|
self.clear_cmd();
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ static SIGNALS: AtomicU64 = AtomicU64::new(0);
|
|||||||
pub static REAPING_ENABLED: AtomicBool = AtomicBool::new(true);
|
pub static REAPING_ENABLED: AtomicBool = AtomicBool::new(true);
|
||||||
pub static SHOULD_QUIT: AtomicBool = AtomicBool::new(false);
|
pub static SHOULD_QUIT: AtomicBool = AtomicBool::new(false);
|
||||||
pub static GOT_SIGWINCH: AtomicBool = AtomicBool::new(false);
|
pub static GOT_SIGWINCH: AtomicBool = AtomicBool::new(false);
|
||||||
|
pub static JOB_DONE: AtomicBool = AtomicBool::new(false);
|
||||||
pub static QUIT_CODE: AtomicI32 = AtomicI32::new(0);
|
pub static QUIT_CODE: AtomicI32 = AtomicI32::new(0);
|
||||||
|
|
||||||
const MISC_SIGNALS: [Signal; 22] = [
|
const MISC_SIGNALS: [Signal; 22] = [
|
||||||
@@ -285,6 +286,7 @@ pub fn child_exited(pid: Pid, status: WtStat) -> ShResult<()> {
|
|||||||
if is_fg {
|
if is_fg {
|
||||||
take_term()?;
|
take_term()?;
|
||||||
} else {
|
} else {
|
||||||
|
JOB_DONE.store(true, Ordering::SeqCst);
|
||||||
let job_order = read_jobs(|j| j.order().to_vec());
|
let job_order = read_jobs(|j| j.order().to_vec());
|
||||||
let result = read_jobs(|j| j.query(JobID::Pgid(pgid)).cloned());
|
let result = read_jobs(|j| j.query(JobID::Pgid(pgid)).cloned());
|
||||||
if let Some(job) = result {
|
if let Some(job) = result {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cell::RefCell, collections::{HashMap, HashSet, VecDeque}, fmt::Display, ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Deref}, os::unix::fs::PermissionsExt, str::FromStr, time::Duration
|
cell::RefCell, collections::{HashMap, HashSet, VecDeque, hash_map::Entry}, fmt::Display, ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Deref}, os::unix::fs::PermissionsExt, str::FromStr, time::Duration
|
||||||
};
|
};
|
||||||
|
|
||||||
use nix::unistd::{User, gethostname, getppid};
|
use nix::unistd::{User, gethostname, getppid};
|
||||||
@@ -183,6 +183,12 @@ impl ScopeStack {
|
|||||||
flat_vars.insert(var_name.clone(), var.clone());
|
flat_vars.insert(var_name.clone(), var.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for var in env::vars() {
|
||||||
|
if let Entry::Vacant(e) = flat_vars.entry(var.0) {
|
||||||
|
e.insert(Var::new(VarKind::Str(var.1), VarFlags::EXPORT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flat_vars
|
flat_vars
|
||||||
}
|
}
|
||||||
pub fn set_var(&mut self, var_name: &str, val: &str, flags: VarFlags) -> ShResult<()> {
|
pub fn set_var(&mut self, var_name: &str, val: &str, flags: VarFlags) -> ShResult<()> {
|
||||||
@@ -953,7 +959,6 @@ pub fn get_status() -> i32 {
|
|||||||
.parse::<i32>()
|
.parse::<i32>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
#[track_caller]
|
|
||||||
pub fn set_status(code: i32) {
|
pub fn set_status(code: i32) {
|
||||||
write_vars(|v| v.set_param(ShellParam::Status, &code.to_string()))
|
write_vars(|v| v.set_param(ShellParam::Status, &code.to_string()))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user