Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Readonly status #7740

Merged
merged 29 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7fa7896
ignore runtime symlink
connortsui20 Jul 25, 2023
4e01088
added is_read_only and "[readonly]" to statusline
connortsui20 Jul 26, 2023
141a162
change to check if readonly on set_path()
connortsui20 Jul 26, 2023
d17992c
undo first commit gitignore mess up
connortsui20 Jul 27, 2023
407959d
change Document readonly field to bool
connortsui20 Jul 27, 2023
4696692
readonly check on write_impl and write_all_impl
connortsui20 Jul 29, 2023
6ad36ba
add readonly indicator element on statusline
connortsui20 Jul 29, 2023
9b4010d
use access syscall for unix readonly
connortsui20 Jul 29, 2023
0059cce
spacing corrected for statusline text
connortsui20 Jul 29, 2023
d23252e
delete runtime
connortsui20 Jul 29, 2023
e01f1e7
Add todo message for windows readonly
connortsui20 Jul 29, 2023
7ecaf74
added error list of readonly files on write-all
connortsui20 Jul 29, 2023
dfa11dc
shorthand change back
connortsui20 Jul 30, 2023
0700254
clearer readonly message
connortsui20 Jul 30, 2023
7f18081
change rustix dep for unix only
connortsui20 Jul 30, 2023
d593548
add read-only-indicator to docs
connortsui20 Jul 30, 2023
d9faba8
added back newline to .gitignore
connortsui20 Jul 30, 2023
c2361a4
change spacing on no file modification
connortsui20 Jul 30, 2023
5cd5baa
change detect_readonly() for windows compilation
connortsui20 Jul 30, 2023
c048345
reorder default statusline
connortsui20 Jul 30, 2023
48600f5
remove extra spaces
connortsui20 Jul 30, 2023
bbcbdfe
simplicity and comment fixes
connortsui20 Aug 4, 2023
f54f2f3
remove force checks
connortsui20 Aug 4, 2023
9bcde99
removed dead code
connortsui20 Aug 4, 2023
bbe6ccd
removed more dead code
connortsui20 Aug 4, 2023
6088449
better description
connortsui20 Aug 4, 2023
1b55179
fix lint
connortsui20 Aug 5, 2023
3c9ba32
revert to static str
connortsui20 Aug 8, 2023
04f9a57
revert whole function
connortsui20 Aug 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The `[editor.statusline]` key takes the following sub-keys:

| 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 | `[]` |
| `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 | `"│"` |
Expand All @@ -108,6 +108,7 @@ The following statusline elements can be configured:
| `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-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 |
| `file-type` | The type of the opened file |
| `diagnostics` | The number of warnings and/or errors |
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ pub fn write_all_impl(
}
if doc.path().is_none() {
if write_scratch {
errors.push("cannot write a buffer without a filename\n");
errors.push("cannot write a buffer without a filename");
connortsui20 marked this conversation as resolved.
Show resolved Hide resolved
}
return None;
}
Expand Down
14 changes: 14 additions & 0 deletions helix-term/src/ui/statusline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ where
helix_view::editor::StatusLineElement::FileModificationIndicator => {
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::FileLineEnding => render_file_line_ending,
helix_view::editor::StatusLineElement::FileType => render_file_type,
Expand Down Expand Up @@ -442,6 +443,19 @@ where
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)
where
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
Expand Down
1 change: 1 addition & 0 deletions helix-view/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
35 changes: 35 additions & 0 deletions helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -673,6 +675,7 @@ impl Document {
config,
version_control_head: None,
focused_at: std::time::Instant::now(),
readonly: false,
}
}

Expand Down Expand Up @@ -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,
Expand All @@ -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))?;

Expand Down Expand Up @@ -1018,6 +1051,8 @@ impl Document {
// and error out when document is saved
self.path = path;

self.detect_readonly();

Ok(())
}

Expand Down
4 changes: 4 additions & 0 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ impl Default for StatusLineConfig {
E::Mode,
E::Spinner,
E::FileName,
E::ReadOnlyIndicator,
E::FileModificationIndicator,
],
center: vec![],
Expand Down Expand Up @@ -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,

Expand Down