aboutsummaryrefslogtreecommitdiff
path: root/helix-view
diff options
context:
space:
mode:
authorConnortsui202023-08-08 12:51:34 +0000
committerGitHub2023-08-08 12:51:34 +0000
commitfcbac485f885d90f6341d7acaf75157a01d81892 (patch)
tree21184e39c95cd2b3d4e4a706608bf6584c6b9045 /helix-view
parenta7a145ad3d78dc0b9f7c2ea289e07d60d9b51d30 (diff)
Show whether file readonly in statusline (#7740)
Diffstat (limited to 'helix-view')
-rw-r--r--helix-view/Cargo.toml1
-rw-r--r--helix-view/src/document.rs35
-rw-r--r--helix-view/src/editor.rs4
3 files changed, 40 insertions, 0 deletions
diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml
index 203b5dad..b66739a4 100644
--- a/helix-view/Cargo.toml
+++ b/helix-view/Cargo.toml
@@ -51,6 +51,7 @@ clipboard-win = { version = "4.5", features = ["std"] }
[target.'cfg(unix)'.dependencies]
libc = "0.2"
+rustix = { version = "0.38", features = ["fs"] }
[dev-dependencies]
helix-tui = { path = "../helix-tui" }
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(())
}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 2152ff9b..113102b6 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -421,6 +421,7 @@ impl Default for StatusLineConfig {
E::Mode,
E::Spinner,
E::FileName,
+ E::ReadOnlyIndicator,
E::FileModificationIndicator,
],
center: vec![],
@@ -473,6 +474,9 @@ pub enum StatusLineElement {
// The file modification indicator
FileModificationIndicator,
+ /// An indicator that shows `"[readonly]"` when a file cannot be written
+ ReadOnlyIndicator,
+
/// The file encoding
FileEncoding,