line editor now sends bell on no-op edits

This commit is contained in:
2026-02-20 14:15:25 -05:00
parent 5721cdb7ca
commit 6f334395f7
2 changed files with 25 additions and 6 deletions

View File

@@ -8,6 +8,7 @@ use vimode::{CmdReplay, ModeReport, ViInsert, ViMode, ViNormal, ViReplace, ViVis
use crate::libsh::sys::TTY_FILENO; use crate::libsh::sys::TTY_FILENO;
use crate::prelude::*; use crate::prelude::*;
use crate::state::read_shopts;
use crate::{ use crate::{
libsh::{ libsh::{
error::ShResult, error::ShResult,
@@ -222,9 +223,9 @@ impl FernVi {
let hint = self.history.get_hint(); let hint = self.history.get_hint();
self.editor.set_hint(hint); self.editor.set_hint(hint);
} }
None => match crate::state::read_shopts(|s| s.core.bell_style) { None => match read_shopts(|s| s.core.bell_style) {
crate::shopt::FernBellStyle::Audible => { crate::shopt::FernBellStyle::Audible => {
self.writer.flush_write("\x07")?; self.writer.send_bell().ok();
} }
crate::shopt::FernBellStyle::Visible | crate::shopt::FernBellStyle::Disable => {} crate::shopt::FernBellStyle::Visible | crate::shopt::FernBellStyle::Disable => {}
}, },
@@ -255,7 +256,7 @@ impl FernVi {
self.writer.flush_write("\n")?; self.writer.flush_write("\n")?;
let buf = self.editor.take_buf(); let buf = self.editor.take_buf();
// Save command to history if auto_hist is enabled // Save command to history if auto_hist is enabled
if crate::state::read_shopts(|s| s.core.auto_hist) && !buf.is_empty() { if read_shopts(|s| s.core.auto_hist) && !buf.is_empty() {
self.history.push(buf.clone()); self.history.push(buf.clone());
if let Err(e) = self.history.save() { if let Err(e) = self.history.save() {
eprintln!("Failed to save history: {e}"); eprintln!("Failed to save history: {e}");
@@ -276,6 +277,8 @@ impl FernVi {
} }
} }
let has_edit_verb = cmd.verb().is_some_and(|v| v.1.is_edit());
let before = self.editor.buffer.clone(); let before = self.editor.buffer.clone();
self.exec_cmd(cmd)?; self.exec_cmd(cmd)?;
let after = self.editor.as_str(); let after = self.editor.as_str();
@@ -284,7 +287,9 @@ impl FernVi {
self self
.history .history
.update_pending_cmd((self.editor.as_str(), self.editor.cursor.get())); .update_pending_cmd((self.editor.as_str(), self.editor.cursor.get()));
} } else if before == after && has_edit_verb {
self.writer.send_bell().ok(); // bell on no-op commands with a verb (e.g., 'x' on empty line)
}
let hint = self.history.get_hint(); let hint = self.history.get_hint();
self.editor.set_hint(hint); self.editor.set_hint(hint);

View File

@@ -18,8 +18,7 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
use vte::{Parser, Perform}; use vte::{Parser, Perform};
use crate::{ use crate::{
libsh::{error::{ShErr, ShErrKind, ShResult}, sys::TTY_FILENO}, libsh::{error::{ShErr, ShErrKind, ShResult}, sys::TTY_FILENO}, prompt::readline::keys::{KeyCode, ModKeys}, shopt::FernBellStyle, state::read_shopts
prompt::readline::keys::{KeyCode, ModKeys},
}; };
use crate::{ use crate::{
prelude::*, prelude::*,
@@ -185,6 +184,7 @@ pub trait LineWriter {
fn clear_rows(&mut self, layout: &Layout) -> ShResult<()>; fn clear_rows(&mut self, layout: &Layout) -> ShResult<()>;
fn redraw(&mut self, prompt: &str, line: &str, new_layout: &Layout) -> ShResult<()>; fn redraw(&mut self, prompt: &str, line: &str, new_layout: &Layout) -> ShResult<()>;
fn flush_write(&mut self, buf: &str) -> ShResult<()>; fn flush_write(&mut self, buf: &str) -> ShResult<()>;
fn send_bell(&mut self) -> ShResult<()>;
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@@ -975,4 +975,18 @@ impl LineWriter for TermWriter {
write_all(self.out, buf)?; write_all(self.out, buf)?;
Ok(()) Ok(())
} }
fn send_bell(&mut self) -> ShResult<()> {
match read_shopts(|o| o.core.bell_style) {
FernBellStyle::Audible => {
self.flush_write("\x07")?;
}
FernBellStyle::Visible => {
log::warn!("Visual bell is not supported in fern shell yet");
}
FernBellStyle::Disable => { /* Do nothing */ }
}
Ok(())
}
} }