Add CLI flag to disable history (#11550)

# Description
Adds a CLI flag for nushell that disables reading and writing to the
history file. This will be useful for future testing and possibly our
users as well. To borrow `fish` shell's terminology, this allows users
to start nushell in "private" mode.

# User-Facing Changes
Breaking API change for `nu-protocol` (changed `Config`).
This commit is contained in:
Ian Manske
2024-01-17 15:40:59 +00:00
committed by GitHub
parent a4199ea312
commit 55bf4d847f
8 changed files with 163 additions and 106 deletions

View File

@@ -25,6 +25,25 @@ mod output;
mod reedline;
mod table;
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct HistoryConfig {
pub max_size: i64,
pub sync_on_enter: bool,
pub file_format: HistoryFileFormat,
pub isolation: bool,
}
impl Default for HistoryConfig {
fn default() -> Self {
Self {
max_size: 100_000,
sync_on_enter: true,
file_format: HistoryFileFormat::PlainText,
isolation: false,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Config {
pub external_completer: Option<usize>,
@@ -46,10 +65,7 @@ pub struct Config {
pub partial_completions: bool,
pub completion_algorithm: CompletionAlgorithm,
pub edit_mode: EditBindings,
pub max_history_size: i64,
pub sync_history_on_enter: bool,
pub history_file_format: HistoryFileFormat,
pub history_isolation: bool,
pub history: HistoryConfig,
pub keybindings: Vec<ParsedKeybinding>,
pub menus: Vec<ParsedMenu>,
pub hooks: Hooks,
@@ -104,10 +120,7 @@ impl Default for Config {
explore: HashMap::new(),
max_history_size: 100_000,
sync_history_on_enter: true,
history_file_format: HistoryFileFormat::PlainText,
history_isolation: false,
history: HistoryConfig::default(),
case_sensitive_completions: false,
quick_completions: true,
@@ -172,7 +185,7 @@ impl Value {
// the `2`.
if let Value::Record { val, .. } = self {
val.retain_mut( |key, value| {
val.retain_mut(|key, value| {
let span = value.span();
match key {
// Grouped options
@@ -232,22 +245,23 @@ impl Value {
}
}
"history" => {
let history = &mut config.history;
if let Value::Record { val, .. } = value {
val.retain_mut(|key2, value| {
let span = value.span();
match key2 {
"isolation" => {
process_bool_config(value, &mut errors, &mut config.history_isolation);
process_bool_config(value, &mut errors, &mut history.isolation);
}
"sync_on_enter" => {
process_bool_config(value, &mut errors, &mut config.sync_history_on_enter);
process_bool_config(value, &mut errors, &mut history.sync_on_enter);
}
"max_size" => {
process_int_config(value, &mut errors, &mut config.max_history_size);
process_int_config(value, &mut errors, &mut history.max_size);
}
"file_format" => {
process_string_enum(
&mut config.history_file_format,
&mut history.file_format,
&[key, key2],
value,
&mut errors);
@@ -264,10 +278,10 @@ impl Value {
// Reconstruct
*value = Value::record(
record! {
"sync_on_enter" => Value::bool(config.sync_history_on_enter, span),
"max_size" => Value::int(config.max_history_size, span),
"file_format" => config.history_file_format.reconstruct_value(span),
"isolation" => Value::bool(config.history_isolation, span),
"sync_on_enter" => Value::bool(history.sync_on_enter, span),
"max_size" => Value::int(history.max_size, span),
"file_format" => history.file_format.reconstruct_value(span),
"isolation" => Value::bool(history.isolation, span),
},
span,
);
@@ -364,7 +378,7 @@ impl Value {
let config_point = match key2 {
"vi_insert" => &mut config.cursor_shape_vi_insert,
"vi_normal" => &mut config.cursor_shape_vi_normal,
"emacs" => &mut config.cursor_shape_emacs,
"emacs" => &mut config.cursor_shape_emacs,
_ => {
report_invalid_key(&[key, key2], span, &mut errors);
return false;
@@ -720,12 +734,12 @@ impl Value {
}
// Catch all
_ => {
report_invalid_key(&[key], span, &mut errors);
report_invalid_key(&[key], span, &mut errors);
return false;
}
};
true
});
};
true
});
} else {
return (
config,

View File

@@ -5,8 +5,8 @@ use super::{usage::build_usage, usage::Usage, StateDelta};
use super::{Command, EnvVars, OverlayFrame, ScopeFrame, Stack, Visibility, DEFAULT_OVERLAY_NAME};
use crate::ast::Block;
use crate::{
BlockId, Config, DeclId, Example, FileId, Module, ModuleId, OverlayId, ShellError, Signature,
Span, Type, VarId, Variable, VirtualPathId,
BlockId, Config, DeclId, Example, FileId, HistoryConfig, Module, ModuleId, OverlayId,
ShellError, Signature, Span, Type, VarId, Variable, VirtualPathId,
};
use crate::{Category, Value};
use std::borrow::Borrow;
@@ -96,6 +96,7 @@ pub struct EngineState {
#[cfg(feature = "plugin")]
pub plugin_signatures: Option<PathBuf>,
config_path: HashMap<String, PathBuf>,
pub history_enabled: bool,
pub history_session_id: i64,
// If Nushell was started, e.g., with `nu spam.nu`, the file's parent is stored here
pub(super) currently_parsed_cwd: Option<PathBuf>,
@@ -151,6 +152,7 @@ impl EngineState {
#[cfg(feature = "plugin")]
plugin_signatures: None,
config_path: HashMap::new(),
history_enabled: true,
history_session_id: 0,
currently_parsed_cwd: None,
regex_cache: Arc::new(Mutex::new(LruCache::new(
@@ -720,6 +722,15 @@ impl EngineState {
self.config.plugins.get(plugin)
}
/// Returns the configuration settings for command history or `None` if history is disabled
pub fn history_config(&self) -> Option<HistoryConfig> {
if self.history_enabled {
Some(self.config.history)
} else {
None
}
}
pub fn get_var(&self, var_id: VarId) -> &Variable {
self.vars
.get(var_id)

View File

@@ -80,7 +80,7 @@ pub fn create_nu_constant(engine_state: &EngineState, span: Span) -> Result<Valu
"history-path",
if let Some(mut path) = nu_path::config_dir() {
path.push("nushell");
match engine_state.config.history_file_format {
match engine_state.config.history.file_format {
HistoryFileFormat::Sqlite => {
path.push("history.sqlite3");
}
@@ -187,6 +187,11 @@ pub fn create_nu_constant(engine_state: &EngineState, span: Span) -> Result<Valu
record.push("is-login", Value::bool(engine_state.is_login, span));
record.push(
"history-enabled",
Value::bool(engine_state.history_enabled, span),
);
record.push(
"current-exe",
if let Ok(current_exe) = std::env::current_exe() {