Allow tracing bindings, event handlers etc. with fish_trace=all

Might have helped with cases like #12209 where an event handler stomps
user preferences.
This commit is contained in:
Johannes Altmanninger
2025-12-26 07:34:43 +01:00
parent 1c1baddf4f
commit b88a5eaad5
5 changed files with 14 additions and 13 deletions

View File

@@ -33,6 +33,7 @@ Scripting improvements
----------------------
- New :ref:`status language <status-language>` commands allow showing and modifying language settings for fish messages without having to modify environment variables.
- When using a noninteractive fish instance to compute completions, ``commandline --cursor`` no works as expected instead of throwing an error (:issue:`11993`).
- :envvar:`fish_trace` can now be set to ``all`` to also trace execution of key bindings, event handlers as well as prompt and title functions.
Interactive improvements
------------------------

View File

@@ -1628,6 +1628,7 @@ You can change the settings of fish by changing the values of certain variables.
if set and not empty, will cause fish to print commands before they execute, similar to ``set -x`` in bash.
The trace is printed to the path given by the `--debug-output` option to fish or the :envvar:`FISH_DEBUG_OUTPUT` variable.
It goes to stderr by default.
Set it to ``all`` to also trace execution of key bindings, event handlers as well as prompt and title functions.
.. envvar:: FISH_DEBUG

9
src/env/var.rs vendored
View File

@@ -164,15 +164,6 @@ pub fn as_string(&self) -> WString {
join_strings(&self.values, self.get_delimiter())
}
/// Copies the variable's values into an existing list, avoiding reallocation if possible.
pub fn to_list(&self, out: &mut Vec<WString>) {
// Try to avoid reallocation as much as possible.
out.resize(self.values.len(), WString::new());
for (i, val) in self.values.iter().enumerate() {
out[i].clone_from(val);
}
}
/// Returns the variable's values.
pub fn as_list(&self) -> &[WString] {
&self.values

View File

@@ -355,8 +355,11 @@ fn handle_read_limit_change(vars: &EnvStack) {
}
fn handle_fish_trace(vars: &EnvStack) {
let enabled = vars.get_unless_empty(L!("fish_trace")).is_some();
crate::trace::trace_set_enabled(enabled);
crate::trace::trace_set_enabled(
vars.get_unless_empty(L!("fish_trace"))
.map(|var| var.as_list().to_vec())
.unwrap_or_default(),
);
}
pub fn env_dispatch_init(vars: &EnvStack) {

View File

@@ -3,13 +3,18 @@
use crate::{common::escape, global_safety::RelaxedAtomicBool, prelude::*};
static DO_TRACE: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
static DO_TRACE_ALL: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
pub fn trace_set_enabled(do_enable: bool) {
DO_TRACE.store(do_enable);
pub fn trace_set_enabled(enable: Vec<WString>) {
DO_TRACE.store(!enable.is_empty());
DO_TRACE_ALL.store(enable.iter().any(|s| s == "all"));
}
/// return whether tracing is enabled.
pub fn trace_enabled(parser: &Parser) -> bool {
if DO_TRACE_ALL.load() {
return true;
}
if parser.scope().suppress_fish_trace {
return false;
}