Allow file paths ending in a language-specific-extension to be used as the language name for injections (#12368)

This allows us to detect the language from the extension if we use paths
in fenced code blocks.

Release Notes:

- You can now use file paths ending in a language-specific file
extension at the start of markdown code blocks.
This commit is contained in:
Nathan Sobo 2024-08-22 19:02:49 -06:00 committed by GitHub
parent db4ff7da6b
commit 88b03bc074
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 16 deletions

View File

@ -1252,20 +1252,28 @@ fn get_injections(
prev_match = Some((mat.pattern_index, content_range.clone()));
let combined = config.patterns[mat.pattern_index].combined;
let mut language_name = None;
let mut step_range = content_range.clone();
if let Some(name) = config.patterns[mat.pattern_index].language.as_ref() {
language_name = Some(Cow::Borrowed(name.as_ref()))
} else if let Some(language_node) = config
.language_capture_ix
.and_then(|ix| mat.nodes_for_capture_index(ix).next())
{
step_range.start = cmp::min(content_range.start, language_node.start_byte());
step_range.end = cmp::max(content_range.end, language_node.end_byte());
language_name = Some(Cow::Owned(
text.text_for_range(language_node.byte_range()).collect(),
))
};
let language_name =
if let Some(name) = config.patterns[mat.pattern_index].language.as_ref() {
Some(Cow::Borrowed(name.as_ref()))
} else if let Some(language_node) = config
.language_capture_ix
.and_then(|ix| mat.nodes_for_capture_index(ix).next())
{
step_range.start = cmp::min(content_range.start, language_node.start_byte());
step_range.end = cmp::max(content_range.end, language_node.end_byte());
let language_name: String =
text.text_for_range(language_node.byte_range()).collect();
// Enable paths ending in a language extension to represent a language name: e.g. "foo/bar/baz.rs"
if let Some(last_dot_pos) = language_name.rfind('.') {
Some(Cow::Owned(language_name[last_dot_pos + 1..].to_string()))
} else {
Some(Cow::Owned(language_name))
}
} else {
None
};
if let Some(language_name) = language_name {
let language = language_registry

View File

@ -214,9 +214,9 @@ fn test_dynamic_language_injection(cx: &mut AppContext) {
],
);
// Replace Rust with Ruby in code block.
// Replace `rs` with a path to ending in `.rb` in code block.
let macro_name_range = range_for_text(&buffer, "rs");
buffer.edit([(macro_name_range, "ruby")]);
buffer.edit([(macro_name_range, "foo/bar/baz.rb")]);
syntax_map.interpolate(&buffer);
syntax_map.reparse(markdown.clone(), &buffer);
syntax_map.reparse(markdown_inline.clone(), &buffer);
@ -232,7 +232,7 @@ fn test_dynamic_language_injection(cx: &mut AppContext) {
);
// Replace Ruby with a language that hasn't been loaded yet.
let macro_name_range = range_for_text(&buffer, "ruby");
let macro_name_range = range_for_text(&buffer, "foo/bar/baz.rb");
buffer.edit([(macro_name_range, "html")]);
syntax_map.interpolate(&buffer);
syntax_map.reparse(markdown.clone(), &buffer);