mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Show whether file readonly in statusline (#7740)
This commit is contained in:
parent
a7a145ad3d
commit
fcbac485f8
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1392,6 +1392,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
"rustix 0.38.4",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
|
@ -89,7 +89,7 @@ ### `[editor.statusline]` Section
|
|||||||
|
|
||||||
| Key | Description | Default |
|
| Key | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name", "file-modification-indicator"]` |
|
| `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name", "read-only-indicator", "file-modification-indicator"]` |
|
||||||
| `center` | A list of elements aligned to the middle of the statusline | `[]` |
|
| `center` | A list of elements aligned to the middle of the statusline | `[]` |
|
||||||
| `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "register", "position", "file-encoding"]` |
|
| `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "register", "position", "file-encoding"]` |
|
||||||
| `separator` | The character used to separate elements in the statusline | `"│"` |
|
| `separator` | The character used to separate elements in the statusline | `"│"` |
|
||||||
@ -108,6 +108,7 @@ ### `[editor.statusline]` Section
|
|||||||
| `file-modification-indicator` | The indicator to show whether the file is modified (a `[+]` appears when there are unsaved changes) |
|
| `file-modification-indicator` | The indicator to show whether the file is modified (a `[+]` appears when there are unsaved changes) |
|
||||||
| `file-encoding` | The encoding of the opened file if it differs from UTF-8 |
|
| `file-encoding` | The encoding of the opened file if it differs from UTF-8 |
|
||||||
| `file-line-ending` | The file line endings (CRLF or LF) |
|
| `file-line-ending` | The file line endings (CRLF or LF) |
|
||||||
|
| `read-only-indicator` | An indicator that shows `[readonly]` when a file cannot be written |
|
||||||
| `total-line-numbers` | The total line numbers of the opened file |
|
| `total-line-numbers` | The total line numbers of the opened file |
|
||||||
| `file-type` | The type of the opened file |
|
| `file-type` | The type of the opened file |
|
||||||
| `diagnostics` | The number of warnings and/or errors |
|
| `diagnostics` | The number of warnings and/or errors |
|
||||||
|
@ -672,7 +672,7 @@ pub fn write_all_impl(
|
|||||||
}
|
}
|
||||||
if doc.path().is_none() {
|
if doc.path().is_none() {
|
||||||
if write_scratch {
|
if write_scratch {
|
||||||
errors.push("cannot write a buffer without a filename\n");
|
errors.push("cannot write a buffer without a filename");
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,7 @@ fn get_render_function<F>(element_id: StatusLineElementID) -> impl Fn(&mut Rende
|
|||||||
helix_view::editor::StatusLineElement::FileModificationIndicator => {
|
helix_view::editor::StatusLineElement::FileModificationIndicator => {
|
||||||
render_file_modification_indicator
|
render_file_modification_indicator
|
||||||
}
|
}
|
||||||
|
helix_view::editor::StatusLineElement::ReadOnlyIndicator => render_read_only_indicator,
|
||||||
helix_view::editor::StatusLineElement::FileEncoding => render_file_encoding,
|
helix_view::editor::StatusLineElement::FileEncoding => render_file_encoding,
|
||||||
helix_view::editor::StatusLineElement::FileLineEnding => render_file_line_ending,
|
helix_view::editor::StatusLineElement::FileLineEnding => render_file_line_ending,
|
||||||
helix_view::editor::StatusLineElement::FileType => render_file_type,
|
helix_view::editor::StatusLineElement::FileType => render_file_type,
|
||||||
@ -442,6 +443,19 @@ fn render_file_modification_indicator<F>(context: &mut RenderContext, write: F)
|
|||||||
write(context, title, None);
|
write(context, title, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_read_only_indicator<F>(context: &mut RenderContext, write: F)
|
||||||
|
where
|
||||||
|
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||||
|
{
|
||||||
|
let title = if context.doc.readonly {
|
||||||
|
" [readonly] "
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
write(context, title, None);
|
||||||
|
}
|
||||||
|
|
||||||
fn render_file_base_name<F>(context: &mut RenderContext, write: F)
|
fn render_file_base_name<F>(context: &mut RenderContext, write: F)
|
||||||
where
|
where
|
||||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||||
|
@ -51,6 +51,7 @@ clipboard-win = { version = "4.5", features = ["std"] }
|
|||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
rustix = { version = "0.38", features = ["fs"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
helix-tui = { path = "../helix-tui" }
|
helix-tui = { path = "../helix-tui" }
|
||||||
|
@ -185,6 +185,8 @@ pub struct Document {
|
|||||||
|
|
||||||
// when document was used for most-recent-used buffer picker
|
// when document was used for most-recent-used buffer picker
|
||||||
pub focused_at: std::time::Instant,
|
pub focused_at: std::time::Instant,
|
||||||
|
|
||||||
|
pub readonly: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inlay hints for a single `(Document, View)` combo.
|
/// Inlay hints for a single `(Document, View)` combo.
|
||||||
@ -673,6 +675,7 @@ pub fn from(
|
|||||||
config,
|
config,
|
||||||
version_control_head: None,
|
version_control_head: None,
|
||||||
focused_at: std::time::Instant::now(),
|
focused_at: std::time::Instant::now(),
|
||||||
|
readonly: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,6 +958,33 @@ pub fn detect_indent_and_line_ending(&mut self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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.
|
/// Reload the document from its path.
|
||||||
pub fn reload(
|
pub fn reload(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -969,6 +999,9 @@ pub fn reload(
|
|||||||
.ok_or_else(|| anyhow!("can't find file to reload from {:?}", self.display_name()))?
|
.ok_or_else(|| anyhow!("can't find file to reload from {:?}", self.display_name()))?
|
||||||
.to_owned();
|
.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 mut file = std::fs::File::open(&path)?;
|
||||||
let (rope, ..) = from_reader(&mut file, Some(encoding))?;
|
let (rope, ..) = from_reader(&mut file, Some(encoding))?;
|
||||||
|
|
||||||
@ -1018,6 +1051,8 @@ pub fn set_path(&mut self, path: Option<&Path>) -> Result<(), std::io::Error> {
|
|||||||
// and error out when document is saved
|
// and error out when document is saved
|
||||||
self.path = path;
|
self.path = path;
|
||||||
|
|
||||||
|
self.detect_readonly();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +421,7 @@ fn default() -> Self {
|
|||||||
E::Mode,
|
E::Mode,
|
||||||
E::Spinner,
|
E::Spinner,
|
||||||
E::FileName,
|
E::FileName,
|
||||||
|
E::ReadOnlyIndicator,
|
||||||
E::FileModificationIndicator,
|
E::FileModificationIndicator,
|
||||||
],
|
],
|
||||||
center: vec![],
|
center: vec![],
|
||||||
@ -473,6 +474,9 @@ pub enum StatusLineElement {
|
|||||||
// The file modification indicator
|
// The file modification indicator
|
||||||
FileModificationIndicator,
|
FileModificationIndicator,
|
||||||
|
|
||||||
|
/// An indicator that shows `"[readonly]"` when a file cannot be written
|
||||||
|
ReadOnlyIndicator,
|
||||||
|
|
||||||
/// The file encoding
|
/// The file encoding
|
||||||
FileEncoding,
|
FileEncoding,
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user