Detailed changes
@@ -61,5 +61,5 @@
"**/.classpath",
"**/.settings",
],
- "read_only_files": ["**/.rustup/**", "**/.cargo/registry/**", "**/.cargo/git/**", "target/**"],
+ "read_only_files": ["**/.rustup/**", "**/.cargo/registry/**", "**/.cargo/git/**", "target/**", "**/*.lock"],
}
@@ -3351,7 +3351,12 @@ impl Editor {
{
let start_offset = selection_start.to_offset(buffer);
let position_matches = start_offset == completion_position.to_offset(buffer);
- let continue_showing = if position_matches {
+ let continue_showing = if let Some((snap, ..)) =
+ buffer.point_to_buffer_offset(completion_position)
+ && snap.capability == Capability::ReadOnly
+ {
+ false
+ } else if position_matches {
if self.snippet_stack.is_empty() {
buffer.char_kind_before(start_offset, Some(CharScopeContext::Completion))
== Some(CharKind::Word)
@@ -4310,10 +4315,26 @@ impl Editor {
let mut new_autoclose_regions = Vec::new();
let snapshot = self.buffer.read(cx).read(cx);
let mut clear_linked_edit_ranges = false;
+ let mut all_selections_read_only = true;
for (selection, autoclose_region) in
self.selections_with_autoclose_regions(selections, &snapshot)
{
+ if snapshot
+ .point_to_buffer_point(selection.head())
+ .is_none_or(|(snapshot, ..)| snapshot.capability == Capability::ReadOnly)
+ {
+ continue;
+ }
+ if snapshot
+ .point_to_buffer_point(selection.tail())
+ .is_none_or(|(snapshot, ..)| snapshot.capability == Capability::ReadOnly)
+ {
+ // note, ideally we'd clip the tail to the closest writeable region towards the head
+ continue;
+ }
+ all_selections_read_only = false;
+
if let Some(scope) = snapshot.language_scope_at(selection.head()) {
// Determine if the inserted text matches the opening or closing
// bracket of any of this language's bracket pairs.
@@ -4593,6 +4614,10 @@ impl Editor {
edits.push((selection.start..selection.end, text.clone()));
}
+ if all_selections_read_only {
+ return;
+ }
+
drop(snapshot);
self.transact(window, cx, |this, window, cx| {
@@ -51,7 +51,7 @@ use gpui::{
quad, relative, size, solid_background, transparent_black,
};
use itertools::Itertools;
-use language::{IndentGuideSettings, language_settings::ShowWhitespaceSetting};
+use language::{Capability, IndentGuideSettings, language_settings::ShowWhitespaceSetting};
use markdown::Markdown;
use multi_buffer::{
Anchor, ExcerptId, ExcerptInfo, ExpandExcerptDirection, ExpandInfo, MultiBufferPoint,
@@ -4146,6 +4146,14 @@ impl EditorElement {
}
})),
)
+ .when(
+ for_excerpt.buffer.capability == Capability::ReadOnly,
+ |el| {
+ el.child(
+ Icon::new(IconName::FileLock).color(Color::Muted),
+ )
+ },
+ )
.when_some(parent_path, |then, path| {
then.child(Label::new(path).truncate().color(
if file_status.is_some_and(FileStatus::is_deleted) {
@@ -188,6 +188,7 @@ pub struct BufferSnapshot {
language: Option<Arc<Language>>,
non_text_state_update_count: usize,
tree_sitter_data: Arc<TreeSitterData>,
+ pub capability: Capability,
}
/// The kind and amount of indentation in a particular line. For now,
@@ -1135,6 +1136,7 @@ impl Buffer {
tree_sitter_data: Arc::new(tree_sitter_data),
language,
non_text_state_update_count: 0,
+ capability: Capability::ReadOnly,
}
}
}
@@ -1160,6 +1162,7 @@ impl Buffer {
remote_selections: Default::default(),
language: None,
non_text_state_update_count: 0,
+ capability: Capability::ReadOnly,
}
}
@@ -1189,6 +1192,7 @@ impl Buffer {
remote_selections: Default::default(),
language,
non_text_state_update_count: 0,
+ capability: Capability::ReadOnly,
}
}
@@ -1215,6 +1219,7 @@ impl Buffer {
diagnostics: self.diagnostics.clone(),
language: self.language.clone(),
non_text_state_update_count: self.non_text_state_update_count,
+ capability: self.capability,
}
}
@@ -5138,6 +5143,7 @@ impl Clone for BufferSnapshot {
language: self.language.clone(),
tree_sitter_data: self.tree_sitter_data.clone(),
non_text_state_update_count: self.non_text_state_update_count,
+ capability: self.capability,
}
}
}
@@ -1431,7 +1431,9 @@ impl MultiBuffer {
(end_region.buffer_range.start + end_overshoot).min(end_region.buffer_range.end);
if start_region.excerpt.id == end_region.excerpt.id {
- if start_region.is_main_buffer {
+ if start_region.buffer.capability == Capability::ReadWrite
+ && start_region.is_main_buffer
+ {
edited_excerpt_ids.push(start_region.excerpt.id);
buffer_edits
.entry(start_region.buffer.remote_id())
@@ -1447,7 +1449,9 @@ impl MultiBuffer {
} else {
let start_excerpt_range = buffer_start..start_region.buffer_range.end;
let end_excerpt_range = end_region.buffer_range.start..buffer_end;
- if start_region.is_main_buffer {
+ if start_region.buffer.capability == Capability::ReadWrite
+ && start_region.is_main_buffer
+ {
edited_excerpt_ids.push(start_region.excerpt.id);
buffer_edits
.entry(start_region.buffer.remote_id())
@@ -1460,7 +1464,9 @@ impl MultiBuffer {
excerpt_id: start_region.excerpt.id,
});
}
- if end_region.is_main_buffer {
+ if end_region.buffer.capability == Capability::ReadWrite
+ && end_region.is_main_buffer
+ {
edited_excerpt_ids.push(end_region.excerpt.id);
buffer_edits
.entry(end_region.buffer.remote_id())
@@ -1480,7 +1486,7 @@ impl MultiBuffer {
if region.excerpt.id == end_region.excerpt.id {
break;
}
- if region.is_main_buffer {
+ if region.buffer.capability == Capability::ReadWrite && region.is_main_buffer {
edited_excerpt_ids.push(region.excerpt.id);
buffer_edits
.entry(region.buffer.remote_id())
@@ -1560,26 +1566,6 @@ impl MultiBuffer {
}
}
- /// Inserts newlines at the given position to create an empty line, returning the start of the new line.
- /// You can also request the insertion of empty lines above and below the line starting at the returned point.
- /// Panics if the given position is invalid.
- pub fn insert_empty_line(
- &mut self,
- position: impl ToPoint,
- space_above: bool,
- space_below: bool,
- cx: &mut Context<Self>,
- ) -> Point {
- let multibuffer_point = position.to_point(&self.read(cx));
- let (buffer, buffer_point, _) = self.point_to_buffer_point(multibuffer_point, cx).unwrap();
- self.start_transaction(cx);
- let empty_line_start = buffer.update(cx, |buffer, cx| {
- buffer.insert_empty_line(buffer_point, space_above, space_below, cx)
- });
- self.end_transaction(cx);
- multibuffer_point + (empty_line_start - buffer_point)
- }
-
pub fn set_active_selections(
&self,
selections: &[Selection<Anchor>],