mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
feat(repl): add DENO_REPL_HISTORY
to change history file path (#18047)
This commit is contained in:
parent
b258763558
commit
1a3c2e2f1d
4 changed files with 83 additions and 18 deletions
|
@ -593,6 +593,9 @@ static ENV_VARIABLES_HELP: &str = r#"ENVIRONMENT VARIABLES:
|
||||||
DENO_DIR Set the cache directory
|
DENO_DIR Set the cache directory
|
||||||
DENO_INSTALL_ROOT Set deno install's output directory
|
DENO_INSTALL_ROOT Set deno install's output directory
|
||||||
(defaults to $HOME/.deno/bin)
|
(defaults to $HOME/.deno/bin)
|
||||||
|
DENO_REPL_HISTORY Set REPL history file path
|
||||||
|
History file is disabled when the value is empty
|
||||||
|
(defaults to $DENO_DIR/deno_history.txt)
|
||||||
DENO_NO_PACKAGE_JSON Disables auto-resolution of package.json
|
DENO_NO_PACKAGE_JSON Disables auto-resolution of package.json
|
||||||
DENO_NO_PROMPT Set to disable permission prompts on access
|
DENO_NO_PROMPT Set to disable permission prompts on access
|
||||||
(alternative to passing --no-prompt on invocation)
|
(alternative to passing --no-prompt on invocation)
|
||||||
|
|
14
cli/cache/deno_dir.rs
vendored
14
cli/cache/deno_dir.rs
vendored
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use super::DiskCache;
|
use super::DiskCache;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// `DenoDir` serves as coordinator for multiple `DiskCache`s containing them
|
/// `DenoDir` serves as coordinator for multiple `DiskCache`s containing them
|
||||||
|
@ -109,8 +110,17 @@ impl DenoDir {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Path used for the REPL history file.
|
/// Path used for the REPL history file.
|
||||||
pub fn repl_history_file_path(&self) -> PathBuf {
|
/// Can be overridden or disabled by setting `DENO_REPL_HISTORY` environment variable.
|
||||||
self.root.join("deno_history.txt")
|
pub fn repl_history_file_path(&self) -> Option<PathBuf> {
|
||||||
|
if let Some(deno_repl_history) = env::var_os("DENO_REPL_HISTORY") {
|
||||||
|
if deno_repl_history.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(PathBuf::from(deno_repl_history))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(self.root.join("deno_history.txt"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Folder path used for downloading new versions of deno.
|
/// Folder path used for downloading new versions of deno.
|
||||||
|
|
|
@ -654,6 +654,52 @@ fn missing_deno_dir() {
|
||||||
assert!(err.is_empty());
|
assert!(err.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn custom_history_path() {
|
||||||
|
use std::fs::read;
|
||||||
|
let temp_dir = TempDir::new();
|
||||||
|
let history_path = temp_dir.path().join("history.txt");
|
||||||
|
let (out, err) = util::run_and_collect_output(
|
||||||
|
true,
|
||||||
|
"repl",
|
||||||
|
Some(vec!["1"]),
|
||||||
|
Some(vec![
|
||||||
|
(
|
||||||
|
"DENO_REPL_HISTORY".to_owned(),
|
||||||
|
history_path.to_str().unwrap().to_owned(),
|
||||||
|
),
|
||||||
|
("NO_COLOR".to_owned(), "1".to_owned()),
|
||||||
|
]),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(read(&history_path).is_ok());
|
||||||
|
assert_ends_with!(out, "1\n");
|
||||||
|
assert!(err.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn disable_history_file() {
|
||||||
|
let deno_dir = util::new_deno_dir();
|
||||||
|
let default_history_path = deno_dir.path().join("deno_history.txt");
|
||||||
|
let (out, err) = util::run_and_collect_output(
|
||||||
|
true,
|
||||||
|
"repl",
|
||||||
|
Some(vec!["1"]),
|
||||||
|
Some(vec![
|
||||||
|
(
|
||||||
|
"DENO_DIR".to_owned(),
|
||||||
|
deno_dir.path().to_str().unwrap().to_owned(),
|
||||||
|
),
|
||||||
|
("DENO_REPL_HISTORY".to_owned(), "".to_owned()),
|
||||||
|
("NO_COLOR".to_owned(), "1".to_owned()),
|
||||||
|
]),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(!default_history_path.try_exists().unwrap());
|
||||||
|
assert_ends_with!(out, "1\n");
|
||||||
|
assert!(err.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn save_last_eval() {
|
fn save_last_eval() {
|
||||||
let (out, err) = util::run_and_collect_output(
|
let (out, err) = util::run_and_collect_output(
|
||||||
|
|
|
@ -401,7 +401,7 @@ impl Highlighter for EditorHelper {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ReplEditor {
|
pub struct ReplEditor {
|
||||||
inner: Arc<Mutex<Editor<EditorHelper>>>,
|
inner: Arc<Mutex<Editor<EditorHelper>>>,
|
||||||
history_file_path: PathBuf,
|
history_file_path: Option<PathBuf>,
|
||||||
errored_on_history_save: Arc<AtomicBool>,
|
errored_on_history_save: Arc<AtomicBool>,
|
||||||
should_exit_on_interrupt: Arc<AtomicBool>,
|
should_exit_on_interrupt: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ pub struct ReplEditor {
|
||||||
impl ReplEditor {
|
impl ReplEditor {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
helper: EditorHelper,
|
helper: EditorHelper,
|
||||||
history_file_path: PathBuf,
|
history_file_path: Option<PathBuf>,
|
||||||
) -> Result<Self, AnyError> {
|
) -> Result<Self, AnyError> {
|
||||||
let editor_config = Config::builder()
|
let editor_config = Config::builder()
|
||||||
.completion_type(CompletionType::List)
|
.completion_type(CompletionType::List)
|
||||||
|
@ -418,7 +418,9 @@ impl ReplEditor {
|
||||||
let mut editor =
|
let mut editor =
|
||||||
Editor::with_config(editor_config).expect("Failed to create editor.");
|
Editor::with_config(editor_config).expect("Failed to create editor.");
|
||||||
editor.set_helper(Some(helper));
|
editor.set_helper(Some(helper));
|
||||||
editor.load_history(&history_file_path).unwrap_or(());
|
if let Some(history_file_path) = &history_file_path {
|
||||||
|
editor.load_history(history_file_path).unwrap_or(());
|
||||||
|
}
|
||||||
editor.bind_sequence(
|
editor.bind_sequence(
|
||||||
KeyEvent(KeyCode::Char('s'), Modifiers::CTRL),
|
KeyEvent(KeyCode::Char('s'), Modifiers::CTRL),
|
||||||
EventHandler::Simple(Cmd::Newline),
|
EventHandler::Simple(Cmd::Newline),
|
||||||
|
@ -435,13 +437,15 @@ impl ReplEditor {
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
let history_file_dir = history_file_path.parent().unwrap();
|
if let Some(history_file_path) = &history_file_path {
|
||||||
std::fs::create_dir_all(history_file_dir).with_context(|| {
|
let history_file_dir = history_file_path.parent().unwrap();
|
||||||
format!(
|
std::fs::create_dir_all(history_file_dir).with_context(|| {
|
||||||
"Unable to create directory for the history file: {}",
|
format!(
|
||||||
history_file_dir.display()
|
"Unable to create directory for the history file: {}",
|
||||||
)
|
history_file_dir.display()
|
||||||
})?;
|
)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(ReplEditor {
|
Ok(ReplEditor {
|
||||||
inner: Arc::new(Mutex::new(editor)),
|
inner: Arc::new(Mutex::new(editor)),
|
||||||
|
@ -457,13 +461,15 @@ impl ReplEditor {
|
||||||
|
|
||||||
pub fn update_history(&self, entry: String) {
|
pub fn update_history(&self, entry: String) {
|
||||||
self.inner.lock().add_history_entry(entry);
|
self.inner.lock().add_history_entry(entry);
|
||||||
if let Err(e) = self.inner.lock().append_history(&self.history_file_path) {
|
if let Some(history_file_path) = &self.history_file_path {
|
||||||
if self.errored_on_history_save.load(Relaxed) {
|
if let Err(e) = self.inner.lock().append_history(history_file_path) {
|
||||||
return;
|
if self.errored_on_history_save.load(Relaxed) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.errored_on_history_save.store(true, Relaxed);
|
self.errored_on_history_save.store(true, Relaxed);
|
||||||
eprintln!("Unable to save history file: {e}");
|
eprintln!("Unable to save history file: {e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue