diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 61c62251..8dc69544 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -830,7 +830,7 @@ pub fn command_mode(cx: &mut Context) { ["w"] | ["write"] => { // TODO: non-blocking via save() command let id = editor.view().doc; - let doc = &mut editor.document(id).unwrap(); + let doc = &mut editor.documents[id]; smol::block_on(doc.save()); } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 1103d6f5..1f4bf6bd 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -415,14 +415,15 @@ impl EditorView { if let Some(path) = doc.relative_path() { let path = path.to_string_lossy(); + + let title = format!("{}{}", path, if doc.modified() { "[+]" } else { "" }); surface.set_stringn( viewport.x + 6, viewport.y, - path, + title, viewport.width.saturating_sub(6) as usize, text_color, ); - // TODO: append [+] if modified } surface.set_string( diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 6e73104a..94684362 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -31,6 +31,7 @@ pub struct Document { // /// Corresponding language scope name. Usually `source.`. pub(crate) language: Option>, + modified: bool, /// Pending changes since last history commit. changes: ChangeSet, /// State at last commit. Used for calculating reverts. @@ -75,6 +76,7 @@ impl Document { restore_cursor: false, syntax: None, language: None, + modified: false, changes, old_state, diagnostics: Vec::new(), @@ -111,7 +113,7 @@ impl Document { // TODO: do we need some way of ensuring two save operations on the same doc can't run at once? // or is that handled by the OS/async layer - pub fn save(&self) -> impl Future> { + pub fn save(&mut self) -> impl Future> { // we clone and move text + path into the future so that we asynchronously save the current // state without blocking any further edits. @@ -120,10 +122,12 @@ impl Document { let identifier = self.identifier(); // TODO: mark changes up to now as saved - // TODO: mark dirty false let language_server = self.language_server.clone(); + // reset the modified flag + self.modified = false; + async move { use smol::{fs::File, prelude::*}; let mut file = File::create(path).await?; @@ -224,6 +228,10 @@ impl Document { let success = self._apply(&transaction); + self.modified = true; + // TODO: be smarter about modified by keeping track of saved version instead. That way if + // current version == version then it's not modified. + if !transaction.changes().is_empty() { // Compose this transaction with the previous one take_with(&mut self.changes, |changes| { @@ -279,6 +287,11 @@ impl Document { self.id } + #[inline] + pub fn modified(&self) -> bool { + self.modified + } + #[inline] pub fn mode(&self) -> Mode { self.mode