settings.rs

 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}