diff options
Diffstat (limited to 'helix-view/src/document.rs')
-rw-r--r-- | helix-view/src/document.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index af7e3a7e..7602c9c7 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -185,6 +185,8 @@ pub struct Document { // when document was used for most-recent-used buffer picker pub focused_at: std::time::Instant, + + pub readonly: bool, } /// Inlay hints for a single `(Document, View)` combo. @@ -673,6 +675,7 @@ impl Document { config, version_control_head: None, focused_at: std::time::Instant::now(), + readonly: false, } } @@ -955,6 +958,33 @@ impl Document { } } + #[cfg(unix)] + // Detect if the file is readonly and change the readonly field if necessary (unix only) + pub fn detect_readonly(&mut self) { + use rustix::fs::{access, Access}; + // Allows setting the flag for files the user cannot modify, like root files + self.readonly = match &self.path { + None => false, + Some(p) => access(p, Access::WRITE_OK).is_err(), + }; + } + + #[cfg(not(unix))] + // Detect if the file is readonly and change the readonly field if necessary (non-unix os) + pub fn detect_readonly(&mut self) { + // TODO Use the Windows' function `CreateFileW` to check if a file is readonly + // Discussion: https://github.com/helix-editor/helix/pull/7740#issuecomment-1656806459 + // Vim implementation: https://github.com/vim/vim/blob/4c0089d696b8d1d5dc40568f25ea5738fa5bbffb/src/os_win32.c#L7665 + // Windows binding: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Storage/FileSystem/fn.CreateFileW.html + self.readonly = match &self.path { + None => false, + Some(p) => match std::fs::metadata(p) { + Err(_) => false, + Ok(metadata) => metadata.permissions().readonly(), + }, + }; + } + /// Reload the document from its path. pub fn reload( &mut self, @@ -969,6 +999,9 @@ impl Document { .ok_or_else(|| anyhow!("can't find file to reload from {:?}", self.display_name()))? .to_owned(); + // Once we have a valid path we check if its readonly status has changed + self.detect_readonly(); + let mut file = std::fs::File::open(&path)?; let (rope, ..) = from_reader(&mut file, Some(encoding))?; @@ -1018,6 +1051,8 @@ impl Document { // and error out when document is saved self.path = path; + self.detect_readonly(); + Ok(()) } |