diff --git a/nix/hm-module.nix b/nix/hm-module.nix index 8558993..d988b81 100644 --- a/nix/hm-module.nix +++ b/nix/hm-module.nix @@ -80,6 +80,7 @@ in "post-prompt" "pre-mode-change" "post-mode-change" + "on-exit" ])) (list: list != []); description = "The events that trigger this autocmd"; }; diff --git a/src/expand.rs b/src/expand.rs index b36f0a2..6f55a50 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -1070,6 +1070,14 @@ pub fn unescape_str(raw: &str) -> String { result.push(markers::SNG_QUOTE); while let Some(q_ch) = chars.next() { match q_ch { + '\\' => { + if chars.peek() == Some(&'\'') { + result.push('\''); + chars.next(); + } else { + result.push('\\'); + } + } '\'' => { result.push(markers::SNG_QUOTE); break; diff --git a/src/main.rs b/src/main.rs index 3853e02..b04f2ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,14 +118,17 @@ fn main() -> ExitCode { } else { shed_interactive(args) } { - eprintln!("shed: {e}"); + e.print_error(); }; if let Some(trap) = read_logic(|l| l.get_trap(TrapTarget::Exit)) && let Err(e) = exec_input(trap, None, false, Some("trap".into())) { - eprintln!("shed: error running EXIT trap: {e}"); + e.print_error(); } + let on_exit_autocmds = read_logic(|l| l.get_autocmds(AutoCmdKind::OnExit)); + on_exit_autocmds.exec(); + write_jobs(|j| j.hang_up()); ExitCode::from(QUIT_CODE.load(Ordering::SeqCst) as u8) } diff --git a/src/readline/mod.rs b/src/readline/mod.rs index 3887264..cb0f197 100644 --- a/src/readline/mod.rs +++ b/src/readline/mod.rs @@ -800,10 +800,16 @@ impl ShedVi { } pub fn swap_mode(&mut self, mode: &mut Box) { + let pre_mode_change = read_logic(|l| l.get_autocmds(AutoCmdKind::PreModeChange)); + pre_mode_change.exec(); + std::mem::swap(&mut self.mode, mode); self.editor.set_cursor_clamp(self.mode.clamp_cursor()); write_vars(|v| v.set_var("SHED_VI_MODE", VarKind::Str(self.mode.report_mode().to_string()), VarFlags::NONE)).ok(); self.prompt.refresh().ok(); + + let post_mode_change = read_logic(|l| l.get_autocmds(AutoCmdKind::PostModeChange)); + post_mode_change.exec(); } pub fn exec_cmd(&mut self, mut cmd: ViCmd) -> ShResult<()> { @@ -811,8 +817,6 @@ impl ShedVi { let mut is_insert_mode = false; if cmd.is_mode_transition() { let count = cmd.verb_count(); - let pre_mode_change = read_logic(|l| l.get_autocmds(AutoCmdKind::PreModeChange)); - pre_mode_change.exec(); let mut mode: Box = if let ModeReport::Ex = self.mode.report_mode() && cmd.flags.contains(CmdFlags::EXIT_CUR_MODE) { if let Some(saved) = self.saved_mode.take() { @@ -892,8 +896,6 @@ impl ShedVi { write_vars(|v| v.set_var("SHED_VI_MODE", VarKind::Str(self.mode.report_mode().to_string()), VarFlags::NONE))?; self.prompt.refresh()?; - let post_mode_change = read_logic(|l| l.get_autocmds(AutoCmdKind::PostModeChange)); - post_mode_change.exec(); return Ok(()); } else if cmd.is_cmd_repeat() { @@ -1377,6 +1379,12 @@ pub fn annotate_token(token: Tk) -> Vec<(usize, Marker)> { token_chars.next(); // consume the escaped char } } + '\\' if qt_state.in_single() => { + token_chars.next(); + if let Some(&(_,'\'')) = token_chars.peek() { + token_chars.next(); // consume the escaped single quote + } + } '<' | '>' if !qt_state.in_quote() && cmd_sub_depth == 0 && proc_sub_depth == 0 => { token_chars.next(); if let Some((_, proc_sub_ch)) = token_chars.peek() diff --git a/src/state.rs b/src/state.rs index 298e2af..0b5b79a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -532,7 +532,8 @@ pub enum AutoCmdKind { PrePrompt, PostPrompt, PreModeChange, - PostModeChange + PostModeChange, + OnExit } impl Display for AutoCmdKind { @@ -547,6 +548,7 @@ impl Display for AutoCmdKind { Self::PostPrompt => write!(f, "post-prompt"), Self::PreModeChange => write!(f, "pre-mode-change"), Self::PostModeChange => write!(f, "post-mode-change"), + Self::OnExit => write!(f, "on-exit"), } } } @@ -564,6 +566,7 @@ impl FromStr for AutoCmdKind { "post-prompt" => Ok(Self::PostPrompt), "pre-mode-change" => Ok(Self::PreModeChange), "post-mode-change" => Ok(Self::PostModeChange), + "on-exit" => Ok(Self::OnExit), _ => Err(ShErr::simple( ShErrKind::ParseErr, format!("Invalid autocmd kind: {}", s),