Detailed changes
@@ -2029,6 +2029,9 @@
"remove_trailing_whitespace_on_save": false,
"ensure_final_newline_on_save": false,
},
+ "EEx": {
+ "language_servers": ["elixir-ls", "!expert", "!next-ls", "!lexical", "..."],
+ },
"Elixir": {
"language_servers": ["elixir-ls", "!expert", "!next-ls", "!lexical", "..."],
},
@@ -2055,7 +2058,7 @@
"allowed": true,
},
},
- "HEEX": {
+ "HEEx": {
"language_servers": ["elixir-ls", "!expert", "!next-ls", "!lexical", "..."],
},
"HTML": {
@@ -22,7 +22,7 @@ const SUGGESTIONS_BY_EXTENSION_ID: &[(&str, &[&str])] = &[
("dart", &["dart"]),
("dockerfile", &["Dockerfile"]),
("elisp", &["el"]),
- ("elixir", &["ex", "exs", "heex"]),
+ ("elixir", &["eex", "ex", "exs", "heex", "leex", "neex"]),
("elm", &["elm"]),
("erlang", &["erl", "hrl"]),
("fish", &["fish"]),
@@ -299,7 +299,7 @@ pub fn init(languages: Arc<LanguageRegistry>, fs: Arc<dyn Fs>, node: NodeRuntime
"CSS",
"ERB",
"HTML+ERB",
- "HEEX",
+ "HEEx",
"HTML",
"JavaScript",
"TypeScript",
@@ -197,11 +197,8 @@ impl LspAdapter for TailwindLspAdapter {
"typescriptreact".to_string(),
),
(LanguageName::new_static("Svelte"), "svelte".to_string()),
- (
- LanguageName::new_static("Elixir"),
- "phoenix-heex".to_string(),
- ),
- (LanguageName::new_static("HEEX"), "phoenix-heex".to_string()),
+ (LanguageName::new_static("Elixir"), "elixir".to_string()),
+ (LanguageName::new_static("HEEx"), "heex".to_string()),
(LanguageName::new_static("ERB"), "erb".to_string()),
(LanguageName::new_static("HTML+ERB"), "erb".to_string()),
(LanguageName::new_static("PHP"), "php".to_string()),
@@ -305,6 +305,12 @@ pub(crate) mod m_2026_02_25 {
pub(crate) use settings::migrate_builtin_agent_servers_to_registry;
}
+pub(crate) mod m_2026_03_16 {
+ mod settings;
+
+ pub(crate) use settings::SETTINGS_PATTERNS;
+}
+
pub(crate) mod m_2026_03_23 {
mod keymap;
@@ -0,0 +1,50 @@
+use std::ops::Range;
+use tree_sitter::{Query, QueryMatch};
+
+use crate::MigrationPatterns;
+use crate::patterns::SETTINGS_NESTED_KEY_VALUE_PATTERN;
+
+pub const SETTINGS_PATTERNS: MigrationPatterns =
+ &[(SETTINGS_NESTED_KEY_VALUE_PATTERN, rename_heex_settings)];
+
+fn rename_heex_settings(
+ contents: &str,
+ mat: &QueryMatch,
+ query: &Query,
+) -> Option<(Range<usize>, String)> {
+ if !is_heex_settings(contents, mat, query) {
+ return None;
+ }
+
+ let setting_name_ix = query.capture_index_for_name("setting_name")?;
+ let setting_name_range = mat
+ .nodes_for_capture_index(setting_name_ix)
+ .next()?
+ .byte_range();
+
+ Some((setting_name_range, "HEEx".to_string()))
+}
+
+fn is_heex_settings(contents: &str, mat: &QueryMatch, query: &Query) -> bool {
+ let parent_key_ix = match query.capture_index_for_name("parent_key") {
+ Some(ix) => ix,
+ None => return false,
+ };
+ let parent_range = match mat.nodes_for_capture_index(parent_key_ix).next() {
+ Some(node) => node.byte_range(),
+ None => return false,
+ };
+ if contents.get(parent_range) != Some("languages") {
+ return false;
+ }
+
+ let setting_name_ix = match query.capture_index_for_name("setting_name") {
+ Some(ix) => ix,
+ None => return false,
+ };
+ let setting_name_range = match mat.nodes_for_capture_index(setting_name_ix).next() {
+ Some(node) => node.byte_range(),
+ None => return false,
+ };
+ contents.get(setting_name_range) == Some("HEEX")
+}
@@ -243,6 +243,10 @@ pub fn migrate_settings(text: &str) -> Result<Option<String>> {
MigrationType::Json(migrations::m_2026_02_03::migrate_experimental_sweep_mercury),
MigrationType::Json(migrations::m_2026_02_04::migrate_tool_permission_defaults),
MigrationType::Json(migrations::m_2026_02_25::migrate_builtin_agent_servers_to_registry),
+ MigrationType::TreeSitter(
+ migrations::m_2026_03_16::SETTINGS_PATTERNS,
+ &SETTINGS_QUERY_2026_03_16,
+ ),
];
run_migrations(text, migrations)
}
@@ -377,6 +381,10 @@ define_query!(
SETTINGS_QUERY_2025_12_15,
migrations::m_2025_12_15::SETTINGS_PATTERNS
);
+define_query!(
+ SETTINGS_QUERY_2026_03_16,
+ migrations::m_2026_03_16::SETTINGS_PATTERNS
+);
define_query!(
KEYMAP_QUERY_2026_03_23,
migrations::m_2026_03_23::KEYMAP_PATTERNS
@@ -115,7 +115,7 @@ const FILE_SUFFIXES_BY_ICON_KEY: &[(&str, &[&str])] = &[
"xlsx",
],
),
- ("elixir", &["eex", "ex", "exs", "heex"]),
+ ("elixir", &["eex", "ex", "exs", "heex", "leex", "neex"]),
("elm", &["elm"]),
(
"erlang",