persist file history

pull/9143/head
Ingrid 11 months ago
parent b5c5e5d715
commit ed7fb431aa

10
Cargo.lock generated

@ -93,6 +93,15 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -1346,6 +1355,7 @@ name = "helix-loader"
version = "24.7.0" version = "24.7.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode",
"cc", "cc",
"dunce", "dunce",
"etcetera", "etcetera",

@ -24,6 +24,7 @@ etcetera = "0.8"
tree-sitter.workspace = true tree-sitter.workspace = true
once_cell = "1.19" once_cell = "1.19"
log = "0.4" log = "0.4"
bincode = "1.3.3"
# TODO: these two should be on !wasm32 only # TODO: these two should be on !wasm32 only

@ -20,6 +20,8 @@ static COMMAND_HISTFILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::O
static SEARCH_HISTFILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new(); static SEARCH_HISTFILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new();
static FILE_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);
ensure_parent_dir(&config_file); ensure_parent_dir(&config_file);
@ -44,6 +46,12 @@ pub fn initialize_search_histfile(specified_file: Option<PathBuf>) {
SEARCH_HISTFILE.set(search_histfile).ok(); SEARCH_HISTFILE.set(search_histfile).ok();
} }
pub fn initialize_file_histfile(specified_file: Option<PathBuf>) {
let file_histfile = specified_file.unwrap_or_else(default_file_histfile);
ensure_parent_dir(&file_histfile);
FILE_HISTFILE.set(file_histfile).ok();
}
/// A list of runtime directories from highest to lowest priority /// A list of runtime directories from highest to lowest priority
/// ///
/// The priority is: /// The priority is:
@ -179,6 +187,10 @@ pub fn search_histfile() -> PathBuf {
.unwrap() .unwrap()
} }
pub fn file_histfile() -> PathBuf {
FILE_HISTFILE.get().map(|path| path.to_path_buf()).unwrap()
}
pub fn workspace_config_file() -> PathBuf { pub fn workspace_config_file() -> PathBuf {
find_workspace().0.join(".helix").join("config.toml") find_workspace().0.join(".helix").join("config.toml")
} }
@ -199,6 +211,10 @@ pub fn default_search_histfile() -> PathBuf {
state_dir().join("search_history") state_dir().join("search_history")
} }
pub fn default_file_histfile() -> PathBuf {
state_dir().join("file_history")
}
/// Merge two TOML documents, merging values from `right` onto `left` /// Merge two TOML documents, merging values from `right` onto `left`
/// ///
/// When an array exists in both `left` and `right`, `right`'s array is /// When an array exists in both `left` and `right`, `right`'s array is

@ -1,10 +1,51 @@
use crate::{command_histfile, search_histfile}; use crate::{command_histfile, file_histfile, search_histfile};
use bincode::serialize_into;
use serde::{Deserialize, Serialize};
use std::{ use std::{
fs::{File, OpenOptions}, fs::{File, OpenOptions},
io::{self, BufRead, BufReader, Write}, io::{self, BufRead, BufReader, Write},
path::PathBuf, path::PathBuf,
}; };
// TODO: should this contain a ViewPosition?
// it would require exposing that type in a new crate, re-exporting in helix-view,
// since this crate is a dependency of helix-view
#[derive(Debug, Serialize, Deserialize)]
pub struct FileHistoryEntry {
path: PathBuf,
anchor: usize,
vertical_offset: usize,
horizontal_offset: usize,
}
impl FileHistoryEntry {
pub fn new(
path: PathBuf,
anchor: usize,
vertical_offset: usize,
horizontal_offset: usize,
) -> Self {
Self {
path,
anchor,
vertical_offset,
horizontal_offset,
}
}
}
pub fn push_file_history(entry: FileHistoryEntry) {
let file = OpenOptions::new()
.append(true)
.create(true)
.open(file_histfile())
// TODO: do something about this unwrap
.unwrap();
// TODO: do something about this unwrap
serialize_into(file, &entry).unwrap();
}
pub fn push_history(register: char, line: &str) { pub fn push_history(register: char, line: &str) {
let filepath = match register { let filepath = match register {
':' => command_histfile(), ':' => command_histfile(),

@ -82,6 +82,7 @@ FLAGS:
helix_loader::initialize_log_file(args.log_file.clone()); helix_loader::initialize_log_file(args.log_file.clone());
helix_loader::initialize_command_histfile(None); helix_loader::initialize_command_histfile(None);
helix_loader::initialize_search_histfile(None); helix_loader::initialize_search_histfile(None);
helix_loader::initialize_file_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 {

@ -13,6 +13,7 @@ use crate::{
Document, DocumentId, View, ViewId, Document, DocumentId, View, ViewId,
}; };
use dap::StackFrame; use dap::StackFrame;
use helix_loader::session::{push_file_history, FileHistoryEntry};
use helix_vcs::DiffProviderRegistry; use helix_vcs::DiffProviderRegistry;
use futures_util::stream::select_all::SelectAll; use futures_util::stream::select_all::SelectAll;
@ -1725,6 +1726,18 @@ impl Editor {
} }
pub fn close(&mut self, id: ViewId) { pub fn close(&mut self, id: ViewId) {
let view = self.tree.get(id);
// TODO: do something about this unwrap
let doc = self.document(view.doc).unwrap();
if let Some(path) = doc.path() {
push_file_history(FileHistoryEntry::new(
path.to_owned(),
view.offset.anchor,
view.offset.vertical_offset,
view.offset.horizontal_offset,
));
};
// Remove selections for the closed view on all documents. // Remove selections for the closed view on all documents.
for doc in self.documents_mut() { for doc in self.documents_mut() {
doc.remove_view(id); doc.remove_view(id);

Loading…
Cancel
Save