Fixed 'C' and 'D' verbs deleting the newline character
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
|
use ariadne::Fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
jobs::JobBldr,
|
jobs::JobBldr,
|
||||||
libsh::error::{ShErr, ShErrKind, ShResult},
|
libsh::error::{ShErr, ShErrKind, ShResult, next_color},
|
||||||
parse::{NdRule, Node},
|
parse::{NdRule, Node},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
procio::{IoStack, borrow_fd},
|
procio::{IoStack, borrow_fd},
|
||||||
@@ -80,7 +82,7 @@ pub fn unalias(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResul
|
|||||||
} else {
|
} else {
|
||||||
for (arg, span) in argv {
|
for (arg, span) in argv {
|
||||||
if read_logic(|l| l.get_alias(&arg)).is_none() {
|
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))
|
write_logic(|l| l.remove_alias(&arg))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use std::iter::Peekable;
|
|
||||||
|
|
||||||
use crate::{
|
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}
|
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}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
use ariadne::Fmt;
|
||||||
use nix::{libc::STDOUT_FILENO, unistd::write};
|
use nix::{libc::STDOUT_FILENO, unistd::write};
|
||||||
|
use yansi::Color;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builtin::setup_builtin,
|
builtin::setup_builtin,
|
||||||
jobs::JobBldr,
|
jobs::JobBldr,
|
||||||
libsh::error::{ShErr, ShErrKind, ShResult},
|
libsh::error::{ShErr, ShErrKind, ShResult, next_color},
|
||||||
parse::{NdRule, Node, lex::Span},
|
parse::{NdRule, Node, lex::Span},
|
||||||
procio::{IoStack, borrow_fd},
|
procio::{IoStack, borrow_fd},
|
||||||
state::{self, read_meta, write_meta},
|
state::{self, read_meta, write_meta},
|
||||||
@@ -48,17 +50,17 @@ fn print_dirs() -> ShResult<()> {
|
|||||||
fn change_directory(target: &PathBuf, blame: Span) -> ShResult<()> {
|
fn change_directory(target: &PathBuf, blame: Span) -> ShResult<()> {
|
||||||
if !target.is_dir() {
|
if !target.is_dir() {
|
||||||
return Err(
|
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) {
|
if let Err(e) = env::set_current_dir(target) {
|
||||||
return Err(
|
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| {
|
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) };
|
unsafe { env::set_var("PWD", new_dir) };
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -85,13 +87,13 @@ fn parse_stack_idx(arg: &str, blame: Span, cmd: &str) -> ShResult<StackIdx> {
|
|||||||
for ch in digits.chars() {
|
for ch in digits.chars() {
|
||||||
if !ch.is_ascii_digit() {
|
if !ch.is_ascii_digit() {
|
||||||
return Err(
|
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| {
|
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 {
|
if from_top {
|
||||||
@@ -127,7 +129,7 @@ pub fn pushd(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<
|
|||||||
no_cd = true;
|
no_cd = true;
|
||||||
} else if arg.starts_with('-') {
|
} else if arg.starts_with('-') {
|
||||||
return Err(
|
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 {
|
} else {
|
||||||
if dir.is_some() {
|
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);
|
let target = PathBuf::from(&arg);
|
||||||
if !target.is_dir() {
|
if !target.is_dir() {
|
||||||
return Err(
|
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);
|
dir = Some(target);
|
||||||
@@ -207,7 +209,7 @@ pub fn popd(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<(
|
|||||||
no_cd = true;
|
no_cd = true;
|
||||||
} else if arg.starts_with('-') {
|
} else if arg.starts_with('-') {
|
||||||
return Err(
|
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('-') => {
|
_ if arg.starts_with('-') => {
|
||||||
return Err(
|
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(
|
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())))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
use ariadne::Fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
jobs::{JobBldr, JobCmdFlags, JobID},
|
jobs::{JobBldr, JobCmdFlags, JobID},
|
||||||
libsh::error::{ShErr, ShErrKind, ShResult},
|
libsh::error::{ShErr, ShErrKind, ShResult, next_color},
|
||||||
parse::{NdRule, Node, lex::Span},
|
parse::{NdRule, Node, lex::Span},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
procio::{IoStack, borrow_fd},
|
procio::{IoStack, borrow_fd},
|
||||||
@@ -16,6 +18,8 @@ pub enum JobBehavior {
|
|||||||
|
|
||||||
pub fn continue_job(node: Node, job: &mut JobBldr, behavior: JobBehavior) -> ShResult<()> {
|
pub fn continue_job(node: Node, job: &mut JobBldr, behavior: JobBehavior) -> ShResult<()> {
|
||||||
let blame = node.get_span().clone();
|
let blame = node.get_span().clone();
|
||||||
|
let cmd_tk = node.get_command();
|
||||||
|
let cmd_span = cmd_tk.unwrap().span.clone();
|
||||||
let cmd = match behavior {
|
let cmd = match behavior {
|
||||||
JobBehavior::Foregound => "fg",
|
JobBehavior::Foregound => "fg",
|
||||||
JobBehavior::Background => "bg",
|
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();
|
let mut argv = argv.into_iter();
|
||||||
|
|
||||||
if read_jobs(|j| j.get_fg().is_some()) {
|
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()) {
|
let curr_job_id = if let Some(id) = read_jobs(|j| j.curr_job()) {
|
||||||
id
|
id
|
||||||
} else {
|
} 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() {
|
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()")),
|
None => Err(ShErr::at(ShErrKind::InternalErr, blame, "Found a job but no table id in parse_job_id()")),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ShErr::at(ShErrKind::SyntaxErr, blame, format!("Invalid arg: {}", arg)))
|
Err(ShErr::at(ShErrKind::SyntaxErr, blame, format!("Invalid arg: {}", arg.fg(next_color()))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::os::unix::fs::OpenOptionsExt;
|
|||||||
use crate::{
|
use crate::{
|
||||||
getopt::{Opt, OptSpec, get_opts_from_tokens},
|
getopt::{Opt, OptSpec, get_opts_from_tokens},
|
||||||
jobs::JobBldr,
|
jobs::JobBldr,
|
||||||
libsh::error::{Note, ShErr, ShErrKind, ShResult, ShResultExt},
|
libsh::error::{ShErr, ShErrKind, ShResult, ShResultExt},
|
||||||
parse::{NdRule, Node},
|
parse::{NdRule, Node},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
procio::{IoStack, borrow_fd},
|
procio::{IoStack, borrow_fd},
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::collections::{HashMap, VecDeque};
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use ariadne::Color;
|
use ariadne::Color;
|
||||||
use ariadne::{Report, ReportKind};
|
use ariadne::{Report, ReportKind};
|
||||||
use rand::{RngExt, TryRng};
|
use rand::TryRng;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
libsh::term::{Style, Styled},
|
libsh::term::{Style, Styled},
|
||||||
@@ -13,9 +13,7 @@ use crate::{
|
|||||||
|
|
||||||
pub type ShResult<T> = Result<T, ShErr>;
|
pub type ShResult<T> = Result<T, ShErr>;
|
||||||
|
|
||||||
pub struct ColorRng {
|
pub struct ColorRng;
|
||||||
last_color: Option<Color>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorRng {
|
impl ColorRng {
|
||||||
fn get_colors() -> &'static [Color] {
|
fn get_colors() -> &'static [Color] {
|
||||||
@@ -53,7 +51,7 @@ impl Iterator for ColorRng {
|
|||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static COLOR_RNG: RefCell<ColorRng> = const { RefCell::new(ColorRng { last_color: None }) };
|
static COLOR_RNG: RefCell<ColorRng> = const { RefCell::new(ColorRng) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_color() -> Color {
|
pub fn next_color() -> Color {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::{cell::RefCell, fmt::Display, ops::BitOr};
|
use std::{fmt::Display, ops::BitOr};
|
||||||
|
|
||||||
pub trait Styled: Sized + Display {
|
pub trait Styled: Sized + Display {
|
||||||
fn styled<S: Into<StyleSet>>(self, style: S) -> String {
|
fn styled<S: Into<StyleSet>>(self, style: S) -> String {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
use ariadne::{Fmt, Label, Span as AriadneSpan};
|
use ariadne::Fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builtin::{
|
builtin::{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::{
|
|||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
iter::Peekable,
|
iter::Peekable,
|
||||||
ops::{Bound, Deref, Range, RangeBounds},
|
ops::{Bound, Range, RangeBounds},
|
||||||
str::Chars,
|
str::Chars,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ use ariadne::{Fmt, Label, Span as AriadneSpan};
|
|||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use fmt::Display;
|
use fmt::Display;
|
||||||
use lex::{LexFlags, LexStream, Span, SpanSource, Tk, TkFlags, TkRule};
|
use lex::{LexFlags, LexStream, Span, SpanSource, Tk, TkFlags, TkRule};
|
||||||
use yansi::Color;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
libsh::{
|
libsh::{
|
||||||
error::{Note, ShErr, ShErrKind, ShResult, next_color},
|
error::{ShErr, ShErrKind, ShResult, next_color},
|
||||||
utils::{NodeVecUtils, TkVecUtils},
|
utils::{NodeVecUtils, TkVecUtils},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
|||||||
@@ -2173,11 +2173,11 @@ impl LineBuf {
|
|||||||
MotionCmd(_, Motion::BeginningOfLine) => MotionKind::On(self.start_of_line()),
|
MotionCmd(_, Motion::BeginningOfLine) => MotionKind::On(self.start_of_line()),
|
||||||
MotionCmd(count, Motion::EndOfLine) => {
|
MotionCmd(count, Motion::EndOfLine) => {
|
||||||
let pos = if count == 1 {
|
let pos = if count == 1 {
|
||||||
self.end_of_line()
|
self.end_of_line_exclusive()
|
||||||
} else if let Some((_, end)) = self.select_lines_down(count) {
|
} else if let Some((_, end)) = self.select_lines_down(count) {
|
||||||
end
|
end
|
||||||
} else {
|
} else {
|
||||||
self.end_of_line()
|
self.end_of_line_exclusive()
|
||||||
};
|
};
|
||||||
|
|
||||||
MotionKind::On(pos)
|
MotionKind::On(pos)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::{fmt::Display, str::FromStr};
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
use crate::libsh::error::{Note, ShErr, ShErrKind, ShResult};
|
use crate::libsh::error::{ShErr, ShErrKind, ShResult};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum ShedBellStyle {
|
pub enum ShedBellStyle {
|
||||||
|
|||||||
Reference in New Issue
Block a user