1use std::ops::Range;
2use tree_sitter::{Query, QueryMatch};
3
4use crate::MigrationPatterns;
5use crate::patterns::SETTINGS_NESTED_KEY_VALUE_PATTERN;
6
7pub const SETTINGS_PATTERNS: MigrationPatterns = &[
8 (
9 SETTINGS_NESTED_KEY_VALUE_PATTERN,
10 rename_open_file_on_paste_setting,
11 ),
12 (
13 SETTINGS_NESTED_KEY_VALUE_PATTERN,
14 replace_open_file_on_paste_setting_value,
15 ),
16];
17
18fn rename_open_file_on_paste_setting(
19 contents: &str,
20 mat: &QueryMatch,
21 query: &Query,
22) -> Option<(Range<usize>, String)> {
23 if !is_project_panel_open_file_on_paste(contents, mat, query) {
24 return None;
25 }
26
27 let setting_name_ix = query.capture_index_for_name("setting_name")?;
28 let setting_name_range = mat
29 .nodes_for_capture_index(setting_name_ix)
30 .next()?
31 .byte_range();
32
33 Some((setting_name_range, "auto_open".to_string()))
34}
35
36fn replace_open_file_on_paste_setting_value(
37 contents: &str,
38 mat: &QueryMatch,
39 query: &Query,
40) -> Option<(Range<usize>, String)> {
41 if !is_project_panel_open_file_on_paste(contents, mat, query) {
42 return None;
43 }
44
45 let value_ix = query.capture_index_for_name("setting_value")?;
46 let value_node = mat.nodes_for_capture_index(value_ix).next()?;
47 let value_range = value_node.byte_range();
48 let value_text = contents.get(value_range.clone())?.trim();
49
50 let normalized_value = match value_text {
51 "true" => "true",
52 "false" => "false",
53 _ => return None,
54 };
55
56 Some((
57 value_range,
58 format!("{{ \"on_paste\": {normalized_value} }}"),
59 ))
60}
61
62fn is_project_panel_open_file_on_paste(contents: &str, mat: &QueryMatch, query: &Query) -> bool {
63 let parent_key_ix = match query.capture_index_for_name("parent_key") {
64 Some(ix) => ix,
65 None => return false,
66 };
67 let parent_range = match mat.nodes_for_capture_index(parent_key_ix).next() {
68 Some(node) => node.byte_range(),
69 None => return false,
70 };
71 if contents.get(parent_range) != Some("project_panel") {
72 return false;
73 }
74
75 let setting_name_ix = match query.capture_index_for_name("setting_name") {
76 Some(ix) => ix,
77 None => return false,
78 };
79 let setting_name_range = match mat.nodes_for_capture_index(setting_name_ix).next() {
80 Some(node) => node.byte_range(),
81 None => return false,
82 };
83 contents.get(setting_name_range) == Some("open_file_on_paste")
84}