Skip to content

Commit

Permalink
inline workspace commands
Browse files Browse the repository at this point in the history
  • Loading branch information
kirawi committed Jan 30, 2023
1 parent 683800b commit 9ce94fc
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 118 deletions.
104 changes: 100 additions & 4 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1865,20 +1865,116 @@ fn save_workspace(
saved_files.append(&mut new_files);
UndoIndex(saved_files)
};

cx.editor.save_workspace()
log::debug!("Saving undo index: {:?}", index);

index
.serialize(&mut index_file)
.context("failed to save index")?;

// Save the histories of open buffers.
for doc in cx.editor.documents_mut().filter(|doc| doc.path().is_some()) {
let path = doc.path().unwrap().clone();
let last_saved_revision = doc.get_last_saved_revision();
let history = doc.history.get_mut();
let mtime = std::fs::metadata(path.clone())?
.modified()?
.duration_since(std::time::UNIX_EPOCH)?
.as_secs();

let mut file = workspace.get_mut(&index.find_id(&path).unwrap().to_string())?;
history
.serialize(
&mut file,
&mut std::fs::File::open(&path)?,
last_saved_revision,
mtime,
)
.context(format!(
"failed to save history for {}",
path.to_string_lossy()
))?;
log::debug!("Saved history for: {}", path.to_string_lossy());
}
Ok(())
}

fn open_workspace(
cx: &mut compositor::Context,
_args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
use helix_view::workspace::undo::UndoIndex;
use helix_view::workspace::Workspace;

if event != PromptEvent::Validate {
return Ok(());
}

cx.editor.open_workspace()
let mut workspace = Workspace::new()?;
let index = UndoIndex::deserialize(&mut workspace.get(".index")?)
.context("failed to load index")?
.0;
let scrolloff = cx.editor.config().scrolloff;
log::debug!("Loaded undo index: {:?}", index);

// Open the documents in the index and load their histories.
for (id, path) in index {
if !path.exists() {
continue;
}

// Close open buffers for the doc.
let doc_id = cx
.editor
.documents()
.find_map(|doc| (doc.path() == Some(&path)).then_some(doc.id()));
if let Some(id) = doc_id {
buffer_close_by_ids_impl(cx, &[id], false)?;
}

let mut file = workspace.get(&id.to_string())?;
let last_mtime = std::fs::metadata(path.clone())?
.modified()?
.duration_since(std::time::UNIX_EPOCH)?
.as_secs();
let id = cx.editor.open(path.as_path(), Action::Load)?;
let doc = doc_mut!(cx.editor, &id);
let (last_saved_revision, history) = match helix_core::history::History::deserialize(
&mut file,
&mut std::fs::File::open(&path)?,
last_mtime,
) {
Ok(res) => res,
Err(e) => {
cx.editor.set_error(format!(
"failed to load undo file for {} because {e}",
path.to_string_lossy()
));
continue;
}
};

// Jump to saved revision if the doc wasn't saved.
if history.current_revision() != last_saved_revision {
let view_id = doc
.selections()
.keys()
.next()
.copied()
.expect("No view_id available");
let view = view_mut!(cx.editor, view_id);
apply_transaction(
&history.changes_since(last_saved_revision).unwrap(),
doc,
&view,
);
view.ensure_cursor_in_view(&doc, scrolloff);
}
doc.history.set(history);
doc.set_last_saved_revision(last_saved_revision);
log::debug!("Loaded history for: {}", path.to_string_lossy());
}
Ok(())
}

pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
Expand Down Expand Up @@ -2406,7 +2502,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand {
name: "open-workspace",
aliases: &["ow"],
doc: "Open document undo history",
doc: "Open document undo history, overriding open buffers.",
fun: open_workspace,
completer: None,
},
Expand Down
2 changes: 1 addition & 1 deletion helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ impl Document {
}

/// Get the document's latest saved revision.
pub fn get_last_saved_revision(&mut self) -> usize {
pub fn get_last_saved_revision(&self) -> usize {
self.last_saved_revision
}

Expand Down
113 changes: 0 additions & 113 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,119 +831,6 @@ impl Editor {
}
}

// TODO: Async?
pub fn save_workspace(&mut self) -> anyhow::Result<()> {
let mut workspace = Workspace::new()?;
let mut index_file = workspace.get_mut("index.undo")?;
let index = {
let mut current_index =
UndoIndex::deserialize(&mut index_file).unwrap_or(UndoIndex::default());
let new_files = self.documents().filter_map(|doc| {
doc.path().filter(|path| {
!current_index
.0
.iter()
.any(|(_, indexed_path)| indexed_path == *path)
})
});
let mut last_id = current_index.0.last().map(|(id, _)| *id).unwrap_or(0);
current_index.0.append(
&mut new_files
.map(|path| {
let current_id = last_id;
last_id += 1;
(current_id, path.clone())
})
.collect(),
);
current_index
};
log::debug!("Saving undo index: {:?}", index);

index
.serialize(&mut index_file)
.context("failed to serialize index")?;
for doc in self.documents_mut().filter(|doc| doc.path().is_some()) {
let history = doc.history.take();
let last_saved_revision = doc.get_last_saved_revision();
let path = doc.path().unwrap();
let mtime = std::fs::metadata(path.clone())?
.modified()?
.duration_since(std::time::UNIX_EPOCH)?
.as_secs();
let id = index.find_id(path).unwrap();
let mut undo_file = workspace.get_mut(&id.to_string())?;

history
.serialize(
&mut undo_file,
&mut File::open(path)?,
last_saved_revision,
mtime,
)
.context(format!(
"failed to save history for {}",
path.to_string_lossy()
))?;
doc.history.set(history);
}
Ok(())
}

pub fn open_workspace(&mut self) -> anyhow::Result<()> {
let mut workspace = Workspace::new()?;
let index = UndoIndex::deserialize(&mut workspace.get("index.undo")?)
.context("failed to load index")?;

let scrolloff = self.config().scrolloff;
for (id, path) in index.0 {
if !path.exists() {
continue;
}
let current_view_id = view!(&self).id;

let mut undo_file = workspace.get(&id.to_string())?;
let last_mtime = std::fs::metadata(path.clone())?
.modified()?
.duration_since(std::time::UNIX_EPOCH)?
.as_secs();
let id = self.open(path.as_path(), Action::Load)?;
let doc = doc_mut!(self, &id);
let (last_saved_revision, history) = helix_core::history::History::deserialize(
&mut undo_file,
&mut File::open(path)?,
last_mtime,
)
.context("failed to load history")?;

if history.current_revision() != last_saved_revision {
let selections = doc.selections();
let view_id = if selections.contains_key(&current_view_id) {
// use current if possible
current_view_id
} else {
// Hack: we take the first available view_id
selections
.keys()
.next()
.copied()
.expect("No view_id available")
};
let view = view_mut!(self, view_id);
apply_transaction(
&history.changes_since(last_saved_revision).unwrap(),
doc,
&view,
);
view.ensure_cursor_in_view(&doc, scrolloff);
}
doc.history.set(history);
doc.set_last_saved_revision(last_saved_revision);
}

Ok(())
}

/// Current editing mode for the [`Editor`].
pub fn mode(&self) -> Mode {
self.mode
Expand Down

0 comments on commit 9ce94fc

Please sign in to comment.