Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fish_trace filters to avoid suppressing traces from binds etc #10424

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions share/completions/set.fish
Expand Up @@ -54,15 +54,14 @@ function __fish_complete_special_vars
FISH_DEBUG_OUTPUT "debug output path" \
umask "current file creation mask" \
fish_handle_reflow "if fish should repaint prompt when the term resizes" \
fish_trace "print cmds as they execute, like set -x" \
fish_emoji_width "cols wide fish assumes emoji render as" \
fish_key_bindings "name of function that sets binds" \
fish_autosuggestion_enabled "turns autosuggestions on or off" \
fish_ambiguous_width "affects computed width of east asian chars" \
fish_escape_delay_ms "How long fish waits to distinguish escape and alt" \
fish_greeting "The message to display at start (also a function)" \
fish_history "The session id to store history under" \
fish_trace "Enables execution tracing (if set to non-empty value)" \
fish_trace "Enables execution tracing, usually '1', or bind/event/prompt/title/all" \
fish_user_paths "A list of dirs to prepend to PATH"
end

Expand Down
2 changes: 1 addition & 1 deletion src/env_dispatch.rs
Expand Up @@ -352,7 +352,7 @@ fn handle_read_limit_change(vars: &EnvStack) {
}

fn handle_fish_trace(vars: &EnvStack) {
let enabled = vars.get_unless_empty(L!("fish_trace")).is_some();
let enabled = vars.get_unless_empty(L!("fish_trace"));
crate::trace::trace_set_enabled(enabled);
}

Expand Down
21 changes: 12 additions & 9 deletions src/event.rs
Expand Up @@ -15,6 +15,7 @@ use crate::job_group::MaybeJobId;
use crate::parser::{Block, Parser};
use crate::signal::{signal_check_cancel, signal_handle, Signal};
use crate::termsize;
use crate::trace::{should_suppress_trace, TraceCategory};
use crate::wchar::prelude::*;

pub enum event_type_t {
Expand Down Expand Up @@ -466,15 +467,17 @@ fn fire_internal(parser: &Parser, event: &Event) {
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_event, new_value),
is_event + 1,
);
let _suppress_trace = scoped_push_replacer(
|new_value| {
std::mem::replace(
&mut parser.libdata_mut().pods.suppress_fish_trace,
new_value,
)
},
true,
);
let _suppress_trace = should_suppress_trace(TraceCategory::Event).then(|| {
scoped_push_replacer(
|new_value| {
std::mem::replace(
&mut parser.libdata_mut().pods.suppress_fish_trace,
new_value,
)
},
true,
)
});

// Capture the event handlers that match this event.
let fire: Vec<_> = EVENT_HANDLERS
Expand Down
4 changes: 2 additions & 2 deletions src/parser.rs
Expand Up @@ -1286,8 +1286,8 @@ pub struct library_data_pod_t {
/// Whether we are currently interactive.
pub is_interactive: bool,

/// Whether to suppress fish_trace output. This occurs in the prompt, event handlers, and key
/// bindings.
/// Whether to suppress fish_trace output. This may occur in prompt, title, event handlers,
/// and key bindings.
pub suppress_fish_trace: bool,

/// Whether we should break or continue the current loop.
Expand Down
45 changes: 28 additions & 17 deletions src/reader.rs
Expand Up @@ -110,6 +110,7 @@ use crate::tokenizer::{
tok_command, MoveWordStateMachine, MoveWordStyle, TokenType, Tokenizer, TOK_ACCEPT_UNFINISHED,
TOK_SHOW_COMMENTS,
};
use crate::trace::{should_suppress_trace, TraceCategory};
use crate::wchar::prelude::*;
use crate::wcstringutil::{
count_preceding_backslashes, join_strings, string_prefixes_string,
Expand Down Expand Up @@ -1751,10 +1752,14 @@ impl ReaderData {
let mut zelf = scoped_push_replacer_ctx(
self,
|zelf, new_value| {
std::mem::replace(
&mut zelf.parser().libdata_mut().pods.suppress_fish_trace,
new_value,
)
if should_suppress_trace(TraceCategory::Bind) {
std::mem::replace(
&mut zelf.parser().libdata_mut().pods.suppress_fish_trace,
new_value,
)
} else {
false // Don't care
}
},
true,
);
Expand Down Expand Up @@ -3644,15 +3649,17 @@ pub fn reader_write_title(
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
false,
);
let _in_title = scoped_push_replacer(
|new_value| {
std::mem::replace(
&mut parser.libdata_mut().pods.suppress_fish_trace,
new_value,
)
},
true,
);
let _in_title = should_suppress_trace(TraceCategory::Title).then(|| {
scoped_push_replacer(
|new_value| {
std::mem::replace(
&mut parser.libdata_mut().pods.suppress_fish_trace,
new_value,
)
},
true,
)
});

let mut fish_title_command = DEFAULT_TITLE.to_owned();
if function::exists(L!("fish_title"), parser) {
Expand Down Expand Up @@ -3721,10 +3728,14 @@ impl ReaderData {
let mut zelf = scoped_push_replacer_ctx(
self,
|zelf, new_value| {
std::mem::replace(
&mut zelf.parser().libdata_mut().pods.suppress_fish_trace,
new_value,
)
if should_suppress_trace(TraceCategory::Prompt) {
std::mem::replace(
&mut zelf.parser().libdata_mut().pods.suppress_fish_trace,
new_value,
)
} else {
false // Don't care
}
},
true,
);
Expand Down
43 changes: 37 additions & 6 deletions src/trace.rs
@@ -1,20 +1,51 @@
use std::sync::Mutex;

use crate::env::EnvVar;
use crate::flog::log_extra_to_flog_file;
#[allow(unused_imports)]
use crate::future::IsSomeAnd;
use crate::parser::Parser;
use crate::{common::escape, global_safety::RelaxedAtomicBool, wchar::prelude::*};
use crate::{common::escape, wchar::prelude::*};

static TRACE_VAR: Mutex<Option<EnvVar>> = Mutex::new(None);

pub fn trace_set_enabled(trace_var: Option<EnvVar>) {
*TRACE_VAR.lock().unwrap() = trace_var;
}

pub(crate) enum TraceCategory {
Bind,
Event,
Prompt,
Title,
}

pub(crate) fn should_suppress_trace(category: TraceCategory) -> bool {
let trace_var = TRACE_VAR.lock().unwrap();
let Some(enabled_categories) = trace_var.as_ref() else {
return false; // not tracing, no need to suppress anything
};
let enabled_categories = enabled_categories.as_list();

static DO_TRACE: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
let category = match category {
TraceCategory::Bind => "bind",
TraceCategory::Event => "event",
TraceCategory::Prompt => "prompt",
TraceCategory::Title => "title",
};

pub fn trace_set_enabled(do_enable: bool) {
DO_TRACE.store(do_enable);
!enabled_categories
.iter()
.any(|s| s == "all" || s == category)
}

/// return whether tracing is enabled.
pub fn trace_enabled(parser: &Parser) -> bool {
fn trace_enabled(parser: &Parser) -> bool {
let ld = &parser.libdata().pods;
if ld.suppress_fish_trace {
return false;
}
DO_TRACE.load()
TRACE_VAR.lock().unwrap().is_some()
}

/// Trace an "argv": a list of arguments where the first is the command.
Expand Down