mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 02:13:38 +08:00
Use ScopeGuard
to replace manually saved-and-restored variables
This commit is contained in:
parent
11766cf56f
commit
4f30993dbb
|
@ -8,6 +8,14 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::os::fd::AsRawFd;
|
||||
use std::{ffi::c_uint, mem};
|
||||
|
||||
/// Like [`std::mem::replace()`] but provides a reference to the old value in a callback to obtain
|
||||
/// the replacement value. Useful to avoid errors about multiple references (`&mut T` for `old` then
|
||||
/// `&T` again in the `new` expression).
|
||||
pub fn replace_with<T, F: FnOnce(&T) -> T>(old: &mut T, with: F) -> T {
|
||||
let new = with(&*old);
|
||||
std::mem::replace(old, new)
|
||||
}
|
||||
|
||||
/// A RAII cleanup object. Unlike in C++ where there is no borrow checker, we can't just provide a
|
||||
/// callback that modifies live objects willy-nilly because then there would be two &mut references
|
||||
/// to the same object - the original variables we keep around to use and their captured references
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::sync::{Arc, Mutex};
|
|||
use widestring_suffix::widestrs;
|
||||
|
||||
use crate::builtins::shared::io_streams_t;
|
||||
use crate::common::{escape_string, EscapeFlags, EscapeStringStyle};
|
||||
use crate::common::{escape_string, replace_with, EscapeFlags, EscapeStringStyle, ScopeGuard};
|
||||
use crate::ffi::{
|
||||
self, block_t, parser_t, signal_check_cancel, signal_handle, termsize_container_t, Repin,
|
||||
};
|
||||
|
@ -680,11 +680,14 @@ fn fire_internal(parser: &mut parser_t, event: &Event) {
|
|||
"is_event should not be negative"
|
||||
);
|
||||
|
||||
let saved_is_event = parser.libdata_pod().is_event;
|
||||
parser.libdata_pod().is_event += 1;
|
||||
// Suppress fish_trace during events.
|
||||
let saved_suppress_fish_trace = parser.libdata_pod().suppress_fish_trace;
|
||||
parser.libdata_pod().suppress_fish_trace = true;
|
||||
let saved_is_event = replace_with(&mut parser.libdata_pod().is_event, |old| old + 1);
|
||||
let saved_suppress_fish_trace =
|
||||
std::mem::replace(&mut parser.libdata_pod().suppress_fish_trace, true);
|
||||
let mut parser = ScopeGuard::new(parser, |parser| {
|
||||
parser.libdata_pod().is_event = saved_is_event;
|
||||
parser.libdata_pod().suppress_fish_trace = saved_suppress_fish_trace;
|
||||
});
|
||||
|
||||
// Capture the event handlers that match this event.
|
||||
let fire: Vec<_> = EVENT_HANDLERS
|
||||
|
@ -716,9 +719,13 @@ fn fire_internal(parser: &mut parser_t, event: &Event) {
|
|||
|
||||
// Event handlers are not part of the main flow of code, so they are marked as
|
||||
// non-interactive.
|
||||
let saved_is_interactive = parser.libdata_pod().is_interactive;
|
||||
parser.libdata_pod().is_interactive = false;
|
||||
let prev_statuses = parser.get_last_statuses().within_unique_ptr();
|
||||
let saved_is_interactive =
|
||||
std::mem::replace(&mut parser.libdata_pod().is_interactive, false);
|
||||
let saved_statuses = parser.get_last_statuses().within_unique_ptr();
|
||||
let mut parser = ScopeGuard::new(&mut parser, |parser| {
|
||||
parser.pin().set_last_statuses(saved_statuses);
|
||||
parser.libdata_pod().is_interactive = saved_is_interactive;
|
||||
});
|
||||
|
||||
FLOG!(
|
||||
event,
|
||||
|
@ -737,19 +744,14 @@ fn fire_internal(parser: &mut parser_t, event: &Event) {
|
|||
.eval_string_ffi1(&buffer.to_ffi())
|
||||
.within_unique_ptr();
|
||||
parser.pin().pop_block(b);
|
||||
parser.pin().set_last_statuses(prev_statuses);
|
||||
|
||||
handler.fired.store(true, Ordering::Relaxed);
|
||||
fired_one_shot |= handler.is_one_shot();
|
||||
parser.libdata_pod().is_interactive = saved_is_interactive;
|
||||
}
|
||||
|
||||
if fired_one_shot {
|
||||
remove_handlers_if(|h| h.fired.load(Ordering::Relaxed) && h.is_one_shot());
|
||||
}
|
||||
|
||||
parser.libdata_pod().suppress_fish_trace = saved_suppress_fish_trace;
|
||||
parser.libdata_pod().is_event = saved_is_event;
|
||||
}
|
||||
|
||||
/// Fire all delayed events attached to the given parser.
|
||||
|
|
Loading…
Reference in New Issue
Block a user