From 08f16fd4ca8dbe62134fe8ced8536be0a41729ac Mon Sep 17 00:00:00 2001 From: Ingrid Date: Thu, 28 Dec 2023 21:13:04 +0100 Subject: [PATCH] switch to multi-file approach, implement persisting command history --- helix-loader/src/lib.rs | 21 +++++---- helix-term/src/application.rs | 4 -- helix-term/src/args.rs | 5 --- helix-term/src/main.rs | 3 +- helix-term/src/session.rs | 81 +++++++---------------------------- helix-term/src/ui/prompt.rs | 4 +- 6 files changed, 32 insertions(+), 86 deletions(-) diff --git a/helix-loader/src/lib.rs b/helix-loader/src/lib.rs index cc26b7c01..fccfcce17 100644 --- a/helix-loader/src/lib.rs +++ b/helix-loader/src/lib.rs @@ -15,7 +15,7 @@ static CONFIG_FILE: once_cell::sync::OnceCell = once_cell::sync::OnceCe static LOG_FILE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); -static SESSION_FILE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); +static COMMAND_HISTFILE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); pub fn initialize_config_file(specified_file: Option) { let config_file = specified_file.unwrap_or_else(default_config_file); @@ -29,10 +29,10 @@ pub fn initialize_log_file(specified_file: Option) { LOG_FILE.set(log_file).ok(); } -pub fn initialize_session_file(specified_file: Option) { - let session_file = specified_file.unwrap_or_else(default_session_file); - ensure_parent_dir(&session_file); - SESSION_FILE.set(session_file).ok(); +pub fn initialize_command_histfile(specified_file: Option) { + let command_histfile = specified_file.unwrap_or_else(default_command_histfile); + ensure_parent_dir(&command_histfile); + COMMAND_HISTFILE.set(command_histfile).ok(); } /// A list of runtime directories from highest to lowest priority @@ -156,8 +156,11 @@ pub fn log_file() -> PathBuf { LOG_FILE.get().map(|path| path.to_path_buf()).unwrap() } -pub fn session_file() -> PathBuf { - SESSION_FILE.get().map(|path| path.to_path_buf()).unwrap() +pub fn command_histfile() -> PathBuf { + COMMAND_HISTFILE + .get() + .map(|path| path.to_path_buf()) + .unwrap() } pub fn workspace_config_file() -> PathBuf { @@ -172,8 +175,8 @@ pub fn default_log_file() -> PathBuf { cache_dir().join("helix.log") } -pub fn default_session_file() -> PathBuf { - state_dir().join("helix.session") +pub fn default_command_histfile() -> PathBuf { + state_dir().join("command_history") } /// Merge two TOML documents, merging values from `right` onto `left` diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index e31584ef5..bd6b5a870 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -27,7 +27,6 @@ use crate::{ handlers, job::Jobs, keymap::Keymaps, - session, ui::{self, overlay::overlaid}, }; @@ -1255,9 +1254,6 @@ impl Application { )); } - #[cfg(not(feature = "integration"))] - session::write_session_file(); - errs } } diff --git a/helix-term/src/args.rs b/helix-term/src/args.rs index ddb43c034..0b1c9cde0 100644 --- a/helix-term/src/args.rs +++ b/helix-term/src/args.rs @@ -16,7 +16,6 @@ pub struct Args { pub verbosity: u64, pub log_file: Option, pub config_file: Option, - pub session_file: Option, pub files: Vec<(PathBuf, Position)>, pub working_directory: Option, } @@ -62,10 +61,6 @@ impl Args { Some(path) => args.log_file = Some(path.into()), None => anyhow::bail!("--log must specify a path to write"), }, - "--session-file" => match argv.next().as_deref() { - Some(path) => args.session_file = Some(path.into()), - None => anyhow::bail!("--session-file must specify a path to write"), - }, "-w" | "--working-dir" => match argv.next().as_deref() { Some(path) => { args.working_directory = if Path::new(path).is_dir() { diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index 4a5650301..b904d3999 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -63,7 +63,6 @@ FLAGS: -v Increases logging verbosity each use for up to 3 times --log Specifies a file to use for logging (default file: {}) - --session-file Specifies a file to use for shared data -V, --version Prints version information --vsplit Splits all given files vertically into different windows --hsplit Splits all given files horizontally into different windows @@ -81,7 +80,7 @@ FLAGS: helix_loader::initialize_config_file(args.config_file.clone()); helix_loader::initialize_log_file(args.log_file.clone()); - helix_loader::initialize_session_file(args.session_file.clone()); + helix_loader::initialize_command_histfile(None); // Help has a higher priority and should be handled separately. if args.display_help { diff --git a/helix-term/src/session.rs b/helix-term/src/session.rs index fc36a9a56..0b06c6266 100644 --- a/helix-term/src/session.rs +++ b/helix-term/src/session.rs @@ -1,68 +1,19 @@ -use bincode::{encode_into_std_write, Decode, Encode}; -use helix_loader::{session_file, VERSION_AND_GIT_HASH}; -// use helix_view::view::ViewPosition; -use std::{ - fs::File, - time::{SystemTime, UNIX_EPOCH}, -}; - -// TODO: should this be non-exhaustive? -#[derive(Debug, Encode, Decode)] -struct Header { - generator: String, - version: String, - max_kbyte: u32, - pid: u32, -} - -// TODO: should this be non-exhaustive? -#[derive(Debug, Encode, Decode)] -struct FilePosition { - path: String, - // position: ViewPosition, -} - -// TODO: should this be non-exhaustive? -#[derive(Debug, Encode, Decode)] -enum EntryData { - Header(Header), - FilePosition(FilePosition), -} - -// TODO: should this be non-exhaustive? -#[derive(Debug, Encode, Decode)] -struct Entry { - timestamp: u64, - data: EntryData, -} - -fn timestamp_now() -> u64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_secs() -} - -fn generate_header() -> Entry { - Entry { - timestamp: timestamp_now(), - data: EntryData::Header(Header { - generator: "helix".to_string(), - version: VERSION_AND_GIT_HASH.to_string(), - max_kbyte: 100, - pid: std::process::id(), - }), - } -} - -pub fn write_session_file() { - // TODO: merge existing file if exists - - // TODO: do something about this unwrap - let mut session_file = File::create(session_file()).unwrap(); - - let header = generate_header(); +use helix_loader::command_histfile; +use std::{fs::OpenOptions, io::Write}; + +pub fn push_history(register: char, line: &str) { + let filepath = match register { + ':' => command_histfile(), + _ => return, + }; + + let mut file = OpenOptions::new() + .append(true) + .create(true) + .open(filepath) + // TODO: do something about this unwrap + .unwrap(); // TODO: do something about this unwrap - encode_into_std_write(&header, &mut session_file, bincode::config::standard()).unwrap(); + writeln!(file, "{}", line).unwrap(); } diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 6ba2fcb9e..c7f4b5e82 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -1,5 +1,5 @@ use crate::compositor::{Component, Compositor, Context, Event, EventResult}; -use crate::{alt, ctrl, key, shift, ui}; +use crate::{alt, ctrl, key, session, shift, ui}; use arc_swap::ArcSwap; use helix_core::syntax; use helix_view::document::Mode; @@ -614,6 +614,8 @@ impl Component for Prompt { { cx.editor.set_error(err.to_string()); } + #[cfg(not(feature = "integration"))] + session::push_history(register, &self.line); }; }