1use anyhow::Result;
2use serde_json::Value;
3use settings_content::{PlatformOverrides, ReleaseChannelOverrides};
4
5/// Applies a migration callback to the root settings object as well as all
6/// nested platform, release-channel, and profile override objects.
7pub(crate) fn migrate_settings(
8 value: &mut Value,
9 migrate_one: &mut dyn FnMut(&mut serde_json::Map<String, Value>) -> Result<()>,
10) -> Result<()> {
11 let Some(root_object) = value.as_object_mut() else {
12 return Ok(());
13 };
14
15 migrate_one(root_object)?;
16
17 let override_keys = ReleaseChannelOverrides::OVERRIDE_KEYS
18 .iter()
19 .copied()
20 .chain(PlatformOverrides::OVERRIDE_KEYS.iter().copied());
21
22 for key in override_keys {
23 if let Some(sub_object) = root_object.get_mut(key) {
24 if let Some(sub_map) = sub_object.as_object_mut() {
25 migrate_one(sub_map)?;
26 }
27 }
28 }
29
30 if let Some(profiles) = root_object.get_mut("profiles") {
31 if let Some(profiles_object) = profiles.as_object_mut() {
32 for (_profile_name, profile_settings) in profiles_object.iter_mut() {
33 if let Some(profile_map) = profile_settings.as_object_mut() {
34 migrate_one(profile_map)?;
35 }
36 }
37 }
38 }
39
40 Ok(())
41}
42
43/// Applies a migration callback to a value and its `languages` children,
44/// at the root level as well as all nested platform, release-channel, and
45/// profile override objects.
46pub(crate) fn migrate_language_setting(
47 value: &mut Value,
48 migrate_fn: fn(&mut Value, path: &[&str]) -> Result<()>,
49) -> Result<()> {
50 fn apply_to_value_and_languages(
51 value: &mut Value,
52 prefix: &[&str],
53 migrate_fn: fn(&mut Value, path: &[&str]) -> Result<()>,
54 ) -> Result<()> {
55 migrate_fn(value, prefix)?;
56 let languages = value
57 .as_object_mut()
58 .and_then(|obj| obj.get_mut("languages"))
59 .and_then(|languages| languages.as_object_mut());
60 if let Some(languages) = languages {
61 for (language_name, language) in languages.iter_mut() {
62 let mut path: Vec<&str> = prefix.to_vec();
63 path.push("languages");
64 path.push(language_name);
65 migrate_fn(language, &path)?;
66 }
67 }
68 Ok(())
69 }
70
71 if !value.is_object() {
72 return Ok(());
73 }
74
75 apply_to_value_and_languages(value, &[], migrate_fn)?;
76
77 let Some(root_object) = value.as_object_mut() else {
78 return Ok(());
79 };
80
81 let override_keys = ReleaseChannelOverrides::OVERRIDE_KEYS
82 .iter()
83 .copied()
84 .chain(PlatformOverrides::OVERRIDE_KEYS.iter().copied());
85
86 for key in override_keys {
87 if let Some(sub_value) = root_object.get_mut(key) {
88 apply_to_value_and_languages(sub_value, &[key], migrate_fn)?;
89 }
90 }
91
92 if let Some(profiles) = root_object.get_mut("profiles") {
93 if let Some(profiles_object) = profiles.as_object_mut() {
94 let profile_names: Vec<String> = profiles_object.keys().cloned().collect();
95 for profile_name in &profile_names {
96 if let Some(profile_settings) = profiles_object.get_mut(profile_name.as_str()) {
97 apply_to_value_and_languages(
98 profile_settings,
99 &["profiles", profile_name],
100 migrate_fn,
101 )?;
102 }
103 }
104 }
105 }
106
107 Ok(())
108}
109
110pub(crate) mod m_2025_01_02 {
111 mod settings;
112
113 pub(crate) use settings::SETTINGS_PATTERNS;
114}
115
116pub(crate) mod m_2025_01_29 {
117 mod keymap;
118 mod settings;
119
120 pub(crate) use keymap::KEYMAP_PATTERNS;
121 pub(crate) use settings::{SETTINGS_PATTERNS, replace_edit_prediction_provider_setting};
122}
123
124pub(crate) mod m_2025_01_30 {
125 mod keymap;
126 mod settings;
127
128 pub(crate) use keymap::KEYMAP_PATTERNS;
129 pub(crate) use settings::SETTINGS_PATTERNS;
130}
131
132pub(crate) mod m_2025_03_03 {
133 mod keymap;
134
135 pub(crate) use keymap::KEYMAP_PATTERNS;
136}
137
138pub(crate) mod m_2025_03_06 {
139 mod keymap;
140
141 pub(crate) use keymap::KEYMAP_PATTERNS;
142}
143
144pub(crate) mod m_2025_03_29 {
145 mod settings;
146
147 pub(crate) use settings::SETTINGS_PATTERNS;
148}
149
150pub(crate) mod m_2025_04_15 {
151 mod keymap;
152 mod settings;
153
154 pub(crate) use keymap::KEYMAP_PATTERNS;
155 pub(crate) use settings::SETTINGS_PATTERNS;
156}
157
158pub(crate) mod m_2025_04_21 {
159 mod settings;
160
161 pub(crate) use settings::SETTINGS_PATTERNS;
162}
163
164pub(crate) mod m_2025_04_23 {
165 mod settings;
166
167 pub(crate) use settings::SETTINGS_PATTERNS;
168}
169
170pub(crate) mod m_2025_05_05 {
171 mod settings;
172
173 pub(crate) use settings::SETTINGS_PATTERNS;
174}
175
176pub(crate) mod m_2025_05_08 {
177 mod settings;
178
179 pub(crate) use settings::SETTINGS_PATTERNS;
180}
181
182pub(crate) mod m_2025_06_16 {
183 mod settings;
184
185 pub(crate) use settings::SETTINGS_PATTERNS;
186}
187
188pub(crate) mod m_2025_06_25 {
189 mod settings;
190
191 pub(crate) use settings::SETTINGS_PATTERNS;
192}
193
194pub(crate) mod m_2025_06_27 {
195 mod settings;
196
197 pub(crate) use settings::SETTINGS_PATTERNS;
198}
199
200pub(crate) mod m_2025_07_08 {
201 mod settings;
202
203 pub(crate) use settings::SETTINGS_PATTERNS;
204}
205
206pub(crate) mod m_2025_10_01 {
207 mod settings;
208
209 pub(crate) use settings::flatten_code_actions_formatters;
210}
211
212pub(crate) mod m_2025_10_02 {
213 mod settings;
214
215 pub(crate) use settings::remove_formatters_on_save;
216}
217
218pub(crate) mod m_2025_10_03 {
219 mod settings;
220
221 pub(crate) use settings::SETTINGS_PATTERNS;
222}
223
224pub(crate) mod m_2025_10_16 {
225 mod settings;
226
227 pub(crate) use settings::restore_code_actions_on_format;
228}
229
230pub(crate) mod m_2025_10_17 {
231 mod settings;
232
233 pub(crate) use settings::make_file_finder_include_ignored_an_enum;
234}
235
236pub(crate) mod m_2025_10_21 {
237 mod settings;
238
239 pub(crate) use settings::make_relative_line_numbers_an_enum;
240}
241
242pub(crate) mod m_2025_11_12 {
243 mod settings;
244
245 pub(crate) use settings::SETTINGS_PATTERNS;
246}
247
248pub(crate) mod m_2025_11_20 {
249 mod settings;
250
251 pub(crate) use settings::SETTINGS_PATTERNS;
252}
253
254pub(crate) mod m_2025_11_25 {
255 mod settings;
256
257 pub(crate) use settings::remove_context_server_source;
258}
259
260pub(crate) mod m_2025_12_01 {
261 mod settings;
262
263 pub(crate) use settings::SETTINGS_PATTERNS;
264}
265
266pub(crate) mod m_2025_12_08 {
267 mod keymap;
268
269 pub(crate) use keymap::KEYMAP_PATTERNS;
270}
271
272pub(crate) mod m_2025_12_15 {
273 mod settings;
274
275 pub(crate) use settings::SETTINGS_PATTERNS;
276}
277
278pub(crate) mod m_2025_01_27 {
279 mod settings;
280
281 pub(crate) use settings::make_auto_indent_an_enum;
282}
283
284pub(crate) mod m_2026_02_02 {
285 mod settings;
286
287 pub(crate) use settings::move_edit_prediction_provider_to_edit_predictions;
288}
289
290pub(crate) mod m_2026_02_03 {
291 mod settings;
292
293 pub(crate) use settings::migrate_experimental_sweep_mercury;
294}
295
296pub(crate) mod m_2026_02_04 {
297 mod settings;
298
299 pub(crate) use settings::migrate_tool_permission_defaults;
300}
301
302pub(crate) mod m_2026_02_25 {
303 mod settings;
304
305 pub(crate) use settings::migrate_builtin_agent_servers_to_registry;
306}