Add vim/emacs modeline support (#49267)
Many editors such as vim and emacs support "modelines", a comment at the beginning of the file that allows the file type to be explicitly specified along with per-file specific settings - The amount of configurations, style and settings mapping cannot be handled in one go, so this opens up a lot of potential improvements. - I left out the possiblity to have "zed" specific modelines for now, but this could be potentially interesting. - Mapping the mode or filetype to zed language names isn't obvious either. We may want to make it configurable. This is my first contribution to zed, be kind. I struggled a bit to find the right place to add those settings. I use a similar approach as done with editorconfig (merge_with_editorconfig). There might be better ways. Closes #4762 Release Notes: - Add basic emacs/vim modeline support. Supersedes #41899, changes: - limit reading to the first and last 1kb - add documentation - more variables handled - add Arc around ModelineSettings to avoid extra cloning - changed the way mode -> language mapping is done, thanks to `modeline_aliases` language config - drop vim ex: support - made "Local Variables:" handling a separate commit, so we can drop it easily - various code style improvements --------- Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
1 parent
e2ecd3e85a
commit
ef282cca24
62 files changed
+1549
-597
No files matched your search
@@ -23,13 +23,14 @@ use language::{
|
||||
IndentGuideSettings, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16, Outline,
|
||||
OutlineItem, Point, PointUtf16, Selection, TextDimension, TextObject, ToOffset as _,
|
||||
ToPoint as _, TransactionId, TreeSitterOptions, Unclipped,
|
||||
language_settings::{LanguageSettings, language_settings},
|
||||
language_settings::{AllLanguageSettings, LanguageSettings},
|
||||
};
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
use gpui::AppContext as _;
|
||||
|
||||
use rope::DimensionPair;
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use smol::future::yield_now;
|
||||
use std::{
|
||||
@@ -2576,10 +2577,7 @@ impl MultiBuffer {
|
||||
.map(|excerpt| excerpt.buffer.remote_id());
|
||||
buffer_id
|
||||
.and_then(|buffer_id| self.buffer(buffer_id))
|
||||
.map(|buffer| {
|
||||
let buffer = buffer.read(cx);
|
||||
language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
|
||||
})
|
||||
.map(|buffer| LanguageSettings::for_buffer(&buffer.read(cx), cx))
|
||||
.unwrap_or_else(move || self.language_settings_at(MultiBufferOffset::default(), cx))
|
||||
}
|
||||
|
||||
@@ -2588,14 +2586,11 @@ impl MultiBuffer {
|
||||
point: T,
|
||||
cx: &'a App,
|
||||
) -> Cow<'a, LanguageSettings> {
|
||||
let mut language = None;
|
||||
let mut file = None;
|
||||
if let Some((buffer, offset)) = self.point_to_buffer_offset(point, cx) {
|
||||
let buffer = buffer.read(cx);
|
||||
language = buffer.language_at(offset);
|
||||
file = buffer.file();
|
||||
LanguageSettings::for_buffer_at(buffer.read(cx), offset, cx)
|
||||
} else {
|
||||
Cow::Borrowed(&AllLanguageSettings::get_global(cx).defaults)
|
||||
}
|
||||
language_settings(language.map(|l| l.name()), file, cx)
|
||||
}
|
||||
|
||||
pub fn for_each_buffer(&self, f: &mut dyn FnMut(&Entity<Buffer>)) {
|
||||
@@ -6603,8 +6598,7 @@ impl MultiBufferSnapshot {
|
||||
let end_row = MultiBufferRow(range.end.row);
|
||||
|
||||
let mut row_indents = self.line_indents(start_row, |buffer| {
|
||||
let settings =
|
||||
language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx);
|
||||
let settings = LanguageSettings::for_buffer_snapshot(buffer, None, cx);
|
||||
settings.indent_guides.enabled || ignore_disabled_for_language
|
||||
});
|
||||
|
||||
@@ -6628,7 +6622,7 @@ impl MultiBufferSnapshot {
|
||||
.get_or_insert_with(|| {
|
||||
(
|
||||
buffer.remote_id(),
|
||||
language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx),
|
||||
LanguageSettings::for_buffer_snapshot(buffer, None, cx),
|
||||
)
|
||||
})
|
||||
.1;
|
||||
@@ -6724,13 +6718,7 @@ impl MultiBufferSnapshot {
|
||||
self.excerpts
|
||||
.first()
|
||||
.map(|excerpt| &excerpt.buffer)
|
||||
.map(|buffer| {
|
||||
language_settings(
|
||||
buffer.language().map(|language| language.name()),
|
||||
buffer.file(),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.map(|buffer| LanguageSettings::for_buffer_snapshot(buffer, None, cx))
|
||||
.unwrap_or_else(move || self.language_settings_at(MultiBufferOffset::ZERO, cx))
|
||||
}
|
||||
|
||||
@@ -6739,13 +6727,11 @@ impl MultiBufferSnapshot {
|
||||
point: T,
|
||||
cx: &'a App,
|
||||
) -> Cow<'a, LanguageSettings> {
|
||||
let mut language = None;
|
||||
let mut file = None;
|
||||
if let Some((buffer, offset)) = self.point_to_buffer_offset(point) {
|
||||
language = buffer.language_at(offset);
|
||||
file = buffer.file();
|
||||
buffer.settings_at(offset, cx)
|
||||
} else {
|
||||
Cow::Borrowed(&AllLanguageSettings::get_global(cx).defaults)
|
||||
}
|
||||
language_settings(language.map(|l| l.name()), file, cx)
|
||||
}
|
||||
|
||||
pub fn language_scope_at<T: ToOffset>(&self, point: T) -> Option<LanguageScope> {
|
||||
|
||||
Reference in new issue
Block a user