Skip to content

language: Respect combined injection sub-ranges for language queries#48522

Merged
Veykril merged 1 commit intozed-industries:mainfrom
vitallium:vs/lang-at-injected-layers
Feb 13, 2026
Merged

language: Respect combined injection sub-ranges for language queries#48522
Veykril merged 1 commit intozed-industries:mainfrom
vitallium:vs/lang-at-injected-layers

Conversation

@vitallium
Copy link
Contributor

@vitallium vitallium commented Feb 5, 2026

Follow-up to #41111.

PR #41111 introduced combined injection handling, but cursor language queries still relied on layer range selection alone. For combined injections this can surface a language from the outer combined layer even when the cursor is outside that language's actual included sub-range. So, we just need to add sub-range filtering based on anchor-aware boundary checks in the same way we did in the previous PR. That means: apply it in Buffer::language_at,
Buffer::languages_at, and BufferSnapshot::language_scope_at. All places that rely on the described behavior.

I also added some additional test cases for the HTML+ERB lang to verify language resolution for HTML and Ruby positions.
Thank you!

Closes #48358

Release Notes:

  • Respect combined injection sub-ranges for language queries

Follow-up to zed-industries#41111.

PR zed-industries#41111 introduced combined injection handling, but cursor language
queries still relied on layer range selection alone. For combined
injections this can surface a language from the outer combined layer
even when the cursor is outside that language's actual included
sub-range. So, we just need to add sub-range filtering
based on anchor-aware boundary checks.
And apply it in `Buffer::language_at`,
`Buffer::languages_at`, and `BufferSnapshot::language_scope_at`
(all places that rely on the described behavior).

I also added some additional test cases for the `HTML+ERB` lang to
verify language resolution for HTML and Ruby positions.
@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Feb 5, 2026
@github-actions github-actions bot added the community champion Issues filed by our amazing community champions! 🫶 label Feb 5, 2026
Comment on lines -1725 to -1732
is_first = false;
return true;
}

layer
.included_sub_ranges
.map(|sub_ranges| {
sub_ranges.iter().any(|sub_range| {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted that as offset_in_sub_ranges since I need it in multiple places.

.layers_for_range(offset..offset, &self.text, false)
.layers_for_range(offset..offset, text, false)
.filter(|layer| {
// For combined injections, check if offset is within the actual sub-ranges.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTML+ERB is quite tricky language since it:

  • Defines itself as HTML+ERB language
  • Injects HTML
  • Injects Ruby

Let's take the following example:

<div>Hello</div>
<%= yield %>
<p>World</p>
  • HTML+ERB lang is active in <%|
  • HTML lang is active in <div>Hello</div> and <p>World</p>.
  • Ruby lang is active only inside <%= yield %>.

So, when a file mixes languages, HTML+ERB for example, the injected language (Ruby or HTML) is only valid in specific spans, so we check those real sub-ranges at the cursor
position to avoid reporting the wrong lang and breaking language-specific actions.

}

#[gpui::test]
fn test_languages_at_for_combined_injections(cx: &mut App) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy&pasted both tests, I hope that's OK? :D

@vitallium vitallium marked this pull request as ready for review February 6, 2026 05:58
@JosephTLyons JosephTLyons requested a review from Veykril February 6, 2026 18:35
Copy link
Member

@Veykril Veykril left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@Veykril Veykril merged commit a6653f0 into zed-industries:main Feb 13, 2026
30 checks passed
@vitallium vitallium deleted the vs/lang-at-injected-layers branch February 13, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement community champion Issues filed by our amazing community champions! 🫶

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTML+ERB auto-completion does not work according to language

3 participants