project_panel: Add auto_open settings (#40435)

- Based on #40234, and improvement of #40331

Release Notes:

- Added granular settings to control when files auto-open in the project
panel (project_panel.auto_open.on_create, on_paste, on_drop)

<img width="662" height="367" alt="Screenshot_2025-10-16_17-28-31"
src="https://github.com/user-attachments/assets/930a0a50-fc89-4c5d-8d05-b1fa2279de8b"
/>

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This commit is contained in:
Miguel Cárdenas
2025-11-12 03:23:40 +05:30
committed by GitHub
co-authored by Smit Barmase
parent 854c6873c7
commit 2ad7ecbcf0
13 changed files with 542 additions and 34 deletions
+6
View File
@@ -135,3 +135,9 @@ pub(crate) mod m_2025_10_21 {
pub(crate) use settings::make_relative_line_numbers_an_enum;
}
pub(crate) mod m_2025_11_12 {
mod settings;
pub(crate) use settings::SETTINGS_PATTERNS;
}
@@ -0,0 +1,84 @@
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_open_file_on_paste_setting,
),
(
SETTINGS_NESTED_KEY_VALUE_PATTERN,
replace_open_file_on_paste_setting_value,
),
];
fn rename_open_file_on_paste_setting(
contents: &str,
mat: &QueryMatch,
query: &Query,
) -> Option<(Range<usize>, String)> {
if !is_project_panel_open_file_on_paste(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, "auto_open".to_string()))
}
fn replace_open_file_on_paste_setting_value(
contents: &str,
mat: &QueryMatch,
query: &Query,
) -> Option<(Range<usize>, String)> {
if !is_project_panel_open_file_on_paste(contents, mat, query) {
return None;
}
let value_ix = query.capture_index_for_name("setting_value")?;
let value_node = mat.nodes_for_capture_index(value_ix).next()?;
let value_range = value_node.byte_range();
let value_text = contents.get(value_range.clone())?.trim();
let normalized_value = match value_text {
"true" => "true",
"false" => "false",
_ => return None,
};
Some((
value_range,
format!("{{ \"on_paste\": {normalized_value} }}"),
))
}
fn is_project_panel_open_file_on_paste(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("project_panel") {
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("open_file_on_paste")
}
+53
View File
@@ -215,6 +215,10 @@ pub fn migrate_settings(text: &str) -> Result<Option<String>> {
MigrationType::Json(migrations::m_2025_10_16::restore_code_actions_on_format),
MigrationType::Json(migrations::m_2025_10_17::make_file_finder_include_ignored_an_enum),
MigrationType::Json(migrations::m_2025_10_21::make_relative_line_numbers_an_enum),
MigrationType::TreeSitter(
migrations::m_2025_11_12::SETTINGS_PATTERNS,
&SETTINGS_QUERY_2025_11_12,
),
];
run_migrations(text, migrations)
}
@@ -333,6 +337,10 @@ define_query!(
SETTINGS_QUERY_2025_10_03,
migrations::m_2025_10_03::SETTINGS_PATTERNS
);
define_query!(
SETTINGS_QUERY_2025_11_12,
migrations::m_2025_11_12::SETTINGS_PATTERNS
);
// custom query
static EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY: LazyLock<Query> = LazyLock::new(|| {
@@ -2193,4 +2201,49 @@ mod tests {
),
);
}
#[test]
fn test_project_panel_open_file_on_paste_migration() {
assert_migrate_settings(
&r#"
{
"project_panel": {
"open_file_on_paste": true
}
}
"#
.unindent(),
Some(
&r#"
{
"project_panel": {
"auto_open": { "on_paste": true }
}
}
"#
.unindent(),
),
);
assert_migrate_settings(
&r#"
{
"project_panel": {
"open_file_on_paste": false
}
}
"#
.unindent(),
Some(
&r#"
{
"project_panel": {
"auto_open": { "on_paste": false }
}
}
"#
.unindent(),
),
);
}
}