switch to multi-file approach, implement persisting command history

pull/9143/head
Ingrid 11 months ago
parent 0fcb26c877
commit 08f16fd4ca

@ -15,7 +15,7 @@ static CONFIG_FILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCe
static LOG_FILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new(); static LOG_FILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new();
static SESSION_FILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new(); static COMMAND_HISTFILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new();
pub fn initialize_config_file(specified_file: Option<PathBuf>) { pub fn initialize_config_file(specified_file: Option<PathBuf>) {
let config_file = specified_file.unwrap_or_else(default_config_file); let config_file = specified_file.unwrap_or_else(default_config_file);
@ -29,10 +29,10 @@ pub fn initialize_log_file(specified_file: Option<PathBuf>) {
LOG_FILE.set(log_file).ok(); LOG_FILE.set(log_file).ok();
} }
pub fn initialize_session_file(specified_file: Option<PathBuf>) { pub fn initialize_command_histfile(specified_file: Option<PathBuf>) {
let session_file = specified_file.unwrap_or_else(default_session_file); let command_histfile = specified_file.unwrap_or_else(default_command_histfile);
ensure_parent_dir(&session_file); ensure_parent_dir(&command_histfile);
SESSION_FILE.set(session_file).ok(); COMMAND_HISTFILE.set(command_histfile).ok();
} }
/// A list of runtime directories from highest to lowest priority /// 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() LOG_FILE.get().map(|path| path.to_path_buf()).unwrap()
} }
pub fn session_file() -> PathBuf { pub fn command_histfile() -> PathBuf {
SESSION_FILE.get().map(|path| path.to_path_buf()).unwrap() COMMAND_HISTFILE
.get()
.map(|path| path.to_path_buf())
.unwrap()
} }
pub fn workspace_config_file() -> PathBuf { pub fn workspace_config_file() -> PathBuf {
@ -172,8 +175,8 @@ pub fn default_log_file() -> PathBuf {
cache_dir().join("helix.log") cache_dir().join("helix.log")
} }
pub fn default_session_file() -> PathBuf { pub fn default_command_histfile() -> PathBuf {
state_dir().join("helix.session") state_dir().join("command_history")
} }
/// Merge two TOML documents, merging values from `right` onto `left` /// Merge two TOML documents, merging values from `right` onto `left`

@ -27,7 +27,6 @@ use crate::{
handlers, handlers,
job::Jobs, job::Jobs,
keymap::Keymaps, keymap::Keymaps,
session,
ui::{self, overlay::overlaid}, ui::{self, overlay::overlaid},
}; };
@ -1255,9 +1254,6 @@ impl Application {
)); ));
} }
#[cfg(not(feature = "integration"))]
session::write_session_file();
errs errs
} }
} }

@ -16,7 +16,6 @@ pub struct Args {
pub verbosity: u64, pub verbosity: u64,
pub log_file: Option<PathBuf>, pub log_file: Option<PathBuf>,
pub config_file: Option<PathBuf>, pub config_file: Option<PathBuf>,
pub session_file: Option<PathBuf>,
pub files: Vec<(PathBuf, Position)>, pub files: Vec<(PathBuf, Position)>,
pub working_directory: Option<PathBuf>, pub working_directory: Option<PathBuf>,
} }
@ -62,10 +61,6 @@ impl Args {
Some(path) => args.log_file = Some(path.into()), Some(path) => args.log_file = Some(path.into()),
None => anyhow::bail!("--log must specify a path to write"), 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() { "-w" | "--working-dir" => match argv.next().as_deref() {
Some(path) => { Some(path) => {
args.working_directory = if Path::new(path).is_dir() { args.working_directory = if Path::new(path).is_dir() {

@ -63,7 +63,6 @@ FLAGS:
-v Increases logging verbosity each use for up to 3 times -v Increases logging verbosity each use for up to 3 times
--log <file> Specifies a file to use for logging --log <file> Specifies a file to use for logging
(default file: {}) (default file: {})
--session-file <file> Specifies a file to use for shared data
-V, --version Prints version information -V, --version Prints version information
--vsplit Splits all given files vertically into different windows --vsplit Splits all given files vertically into different windows
--hsplit Splits all given files horizontally 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_config_file(args.config_file.clone());
helix_loader::initialize_log_file(args.log_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. // Help has a higher priority and should be handled separately.
if args.display_help { if args.display_help {

@ -1,68 +1,19 @@
use bincode::{encode_into_std_write, Decode, Encode}; use helix_loader::command_histfile;
use helix_loader::{session_file, VERSION_AND_GIT_HASH}; use std::{fs::OpenOptions, io::Write};
// use helix_view::view::ViewPosition;
use std::{ pub fn push_history(register: char, line: &str) {
fs::File, let filepath = match register {
time::{SystemTime, UNIX_EPOCH}, ':' => command_histfile(),
}; _ => return,
};
// TODO: should this be non-exhaustive?
#[derive(Debug, Encode, Decode)] let mut file = OpenOptions::new()
struct Header { .append(true)
generator: String, .create(true)
version: String, .open(filepath)
max_kbyte: u32, // TODO: do something about this unwrap
pid: u32, .unwrap();
}
// 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();
// TODO: do something about this unwrap // TODO: do something about this unwrap
encode_into_std_write(&header, &mut session_file, bincode::config::standard()).unwrap(); writeln!(file, "{}", line).unwrap();
} }

@ -1,5 +1,5 @@
use crate::compositor::{Component, Compositor, Context, Event, EventResult}; 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 arc_swap::ArcSwap;
use helix_core::syntax; use helix_core::syntax;
use helix_view::document::Mode; use helix_view::document::Mode;
@ -614,6 +614,8 @@ impl Component for Prompt {
{ {
cx.editor.set_error(err.to_string()); cx.editor.set_error(err.to_string());
} }
#[cfg(not(feature = "integration"))]
session::push_history(register, &self.line);
}; };
} }

Loading…
Cancel
Save