Fixed 'C' and 'D' verbs deleting the newline character

This commit is contained in:
2026-03-01 02:39:22 -05:00
parent 4a0cefee32
commit ffe78620a9
12 changed files with 36 additions and 32 deletions

View File

@@ -1,6 +1,8 @@
use ariadne::Fmt;
use crate::{
jobs::JobBldr,
libsh::error::{ShErr, ShErrKind, ShResult},
libsh::error::{ShErr, ShErrKind, ShResult, next_color},
parse::{NdRule, Node},
prelude::*,
procio::{IoStack, borrow_fd},
@@ -80,7 +82,7 @@ pub fn unalias(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResul
} else {
for (arg, span) in argv {
if read_logic(|l| l.get_alias(&arg)).is_none() {
return Err(ShErr::at(ShErrKind::SyntaxErr, span, format!("unalias: alias '{arg}' not found")));
return Err(ShErr::at(ShErrKind::SyntaxErr, span, format!("unalias: alias '{}' not found",arg.fg(next_color()))));
};
write_logic(|l| l.remove_alias(&arg))
}

View File

@@ -1,4 +1,3 @@
use std::iter::Peekable;
use crate::{
getopt::{Opt, OptSpec, get_opts_from_tokens}, jobs::JobBldr, libsh::error::{ShErr, ShErrKind, ShResult}, parse::{NdRule, Node}, prelude::*, procio::{IoStack, borrow_fd}, state::{self, VarFlags, VarKind, write_vars}

View File

@@ -1,11 +1,13 @@
use std::{env, path::PathBuf};
use ariadne::Fmt;
use nix::{libc::STDOUT_FILENO, unistd::write};
use yansi::Color;
use crate::{
builtin::setup_builtin,
jobs::JobBldr,
libsh::error::{ShErr, ShErrKind, ShResult},
libsh::error::{ShErr, ShErrKind, ShResult, next_color},
parse::{NdRule, Node, lex::Span},
procio::{IoStack, borrow_fd},
state::{self, read_meta, write_meta},
@@ -48,17 +50,17 @@ fn print_dirs() -> ShResult<()> {
fn change_directory(target: &PathBuf, blame: Span) -> ShResult<()> {
if !target.is_dir() {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("not a directory: {}", target.display()))
ShErr::at(ShErrKind::ExecFail, blame, format!("not a directory: '{}'", target.display().fg(next_color())))
);
}
if let Err(e) = env::set_current_dir(target) {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("Failed to change directory: {}", e))
ShErr::at(ShErrKind::ExecFail, blame, format!("Failed to change directory: '{}'", e.fg(Color::Red)))
);
}
let new_dir = env::current_dir().map_err(|e| {
ShErr::at(ShErrKind::ExecFail, blame, format!("Failed to get current directory: {}", e))
ShErr::at(ShErrKind::ExecFail, blame, format!("Failed to get current directory: '{}'", e.fg(Color::Red)))
})?;
unsafe { env::set_var("PWD", new_dir) };
Ok(())
@@ -85,13 +87,13 @@ fn parse_stack_idx(arg: &str, blame: Span, cmd: &str) -> ShResult<StackIdx> {
for ch in digits.chars() {
if !ch.is_ascii_digit() {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("{cmd}: invalid argument: {arg}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("{cmd}: invalid argument: '{}'",arg.fg(next_color())))
);
}
}
let n = digits.parse::<usize>().map_err(|e| {
ShErr::at(ShErrKind::ExecFail, blame, format!("{cmd}: invalid index: {e}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("{cmd}: invalid index: '{}'",e.fg(next_color())))
})?;
if from_top {
@@ -127,7 +129,7 @@ pub fn pushd(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<
no_cd = true;
} else if arg.starts_with('-') {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("pushd: invalid option: {arg}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("pushd: invalid option: '{}'", arg.fg(next_color())))
);
} else {
if dir.is_some() {
@@ -138,7 +140,7 @@ pub fn pushd(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<
let target = PathBuf::from(&arg);
if !target.is_dir() {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("pushd: not a directory: {arg}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("pushd: not a directory: '{}'", target.display().fg(next_color())))
);
}
dir = Some(target);
@@ -207,7 +209,7 @@ pub fn popd(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<(
no_cd = true;
} else if arg.starts_with('-') {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("popd: invalid option: {arg}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("popd: invalid option: '{}'", arg.fg(next_color())))
);
}
}
@@ -307,12 +309,12 @@ pub fn dirs(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<(
}
_ if arg.starts_with('-') => {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("dirs: invalid option: {arg}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("dirs: invalid option: '{}'", arg.fg(next_color())))
);
}
_ => {
return Err(
ShErr::at(ShErrKind::ExecFail, blame, format!("dirs: unexpected argument: {arg}"))
ShErr::at(ShErrKind::ExecFail, blame, format!("dirs: unexpected argument: '{}'", arg.fg(next_color())))
);
}
}

View File

@@ -1,6 +1,8 @@
use ariadne::Fmt;
use crate::{
jobs::{JobBldr, JobCmdFlags, JobID},
libsh::error::{ShErr, ShErrKind, ShResult},
libsh::error::{ShErr, ShErrKind, ShResult, next_color},
parse::{NdRule, Node, lex::Span},
prelude::*,
procio::{IoStack, borrow_fd},
@@ -16,6 +18,8 @@ pub enum JobBehavior {
pub fn continue_job(node: Node, job: &mut JobBldr, behavior: JobBehavior) -> ShResult<()> {
let blame = node.get_span().clone();
let cmd_tk = node.get_command();
let cmd_span = cmd_tk.unwrap().span.clone();
let cmd = match behavior {
JobBehavior::Foregound => "fg",
JobBehavior::Background => "bg",
@@ -33,13 +37,13 @@ pub fn continue_job(node: Node, job: &mut JobBldr, behavior: JobBehavior) -> ShR
let mut argv = argv.into_iter();
if read_jobs(|j| j.get_fg().is_some()) {
return Err(ShErr::at(ShErrKind::InternalErr, blame, format!("Somehow called '{}' with an existing foreground job", cmd)));
return Err(ShErr::at(ShErrKind::InternalErr, cmd_span, format!("Somehow called '{}' with an existing foreground job", cmd)));
}
let curr_job_id = if let Some(id) = read_jobs(|j| j.curr_job()) {
id
} else {
return Err(ShErr::at(ShErrKind::ExecFail, blame, "No jobs found"));
return Err(ShErr::at(ShErrKind::ExecFail, cmd_span, "No jobs found"));
};
let tabid = match argv.next() {
@@ -111,7 +115,7 @@ fn parse_job_id(arg: &str, blame: Span) -> ShResult<usize> {
None => Err(ShErr::at(ShErrKind::InternalErr, blame, "Found a job but no table id in parse_job_id()")),
}
} else {
Err(ShErr::at(ShErrKind::SyntaxErr, blame, format!("Invalid arg: {}", arg)))
Err(ShErr::at(ShErrKind::SyntaxErr, blame, format!("Invalid arg: {}", arg.fg(next_color()))))
}
}

View File

@@ -3,7 +3,7 @@ use std::os::unix::fs::OpenOptionsExt;
use crate::{
getopt::{Opt, OptSpec, get_opts_from_tokens},
jobs::JobBldr,
libsh::error::{Note, ShErr, ShErrKind, ShResult, ShResultExt},
libsh::error::{ShErr, ShErrKind, ShResult, ShResultExt},
parse::{NdRule, Node},
prelude::*,
procio::{IoStack, borrow_fd},