aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs3
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs2
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/ide_assists/src/tests.rs1
-rw-r--r--crates/ide_completion/src/item.rs11
-rw-r--r--crates/ide_completion/src/lib.rs2
-rw-r--r--crates/ide_completion/src/test_utils.rs3
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs17
-rw-r--r--crates/ide_db/src/helpers/insert_use/tests.rs38
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/bin/flags.rs15
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs6
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/rust-analyzer/src/to_proto.rs6
-rw-r--r--docs/user/generated_config.adoc2
-rw-r--r--editors/code/package.json5
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/flags.rs17
19 files changed, 102 insertions, 44 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 39f27098a..c392a8907 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1919,18 +1919,18 @@ checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
1919 1919
1920[[package]] 1920[[package]]
1921name = "xflags" 1921name = "xflags"
1922version = "0.1.4" 1922version = "0.2.1"
1923source = "registry+https://github.com/rust-lang/crates.io-index" 1923source = "registry+https://github.com/rust-lang/crates.io-index"
1924checksum = "222e914b43cec5d7305ac5116d10a14b3a52c50e9062d642c92631f3beabc729" 1924checksum = "59ad6ce6a0b7224130015b4ebac796478ac04e0079f5d222a690efea06a9208a"
1925dependencies = [ 1925dependencies = [
1926 "xflags-macros", 1926 "xflags-macros",
1927] 1927]
1928 1928
1929[[package]] 1929[[package]]
1930name = "xflags-macros" 1930name = "xflags-macros"
1931version = "0.1.4" 1931version = "0.2.1"
1932source = "registry+https://github.com/rust-lang/crates.io-index" 1932source = "registry+https://github.com/rust-lang/crates.io-index"
1933checksum = "52f18f5b4aa7f95e209d5b9274f6164c3938920b4d5c75f97f0dd16daee25ddd" 1933checksum = "c8037d3ca14996158b03c0fa905d0834906ef0fc7044df72c1f5ff690e5e62c9"
1934dependencies = [ 1934dependencies = [
1935 "proc-macro2", 1935 "proc-macro2",
1936] 1936]
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs
index dc38f90e9..1422224ac 100644
--- a/crates/ide_assists/src/handlers/auto_import.rs
+++ b/crates/ide_assists/src/handlers/auto_import.rs
@@ -99,8 +99,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
99 format!("Import `{}`", &import), 99 format!("Import `{}`", &import),
100 range, 100 range,
101 |builder| { 101 |builder| {
102 let rewriter = 102 let rewriter = insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use);
103 insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use.merge);
104 builder.rewrite(rewriter); 103 builder.rewrite(rewriter);
105 }, 104 },
106 ); 105 );
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index 5c7678b53..4f0422e96 100644
--- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -154,7 +154,7 @@ fn insert_import(
154 mod_path.pop_segment(); 154 mod_path.pop_segment();
155 mod_path.push_segment(variant_hir_name.clone()); 155 mod_path.push_segment(variant_hir_name.clone());
156 let scope = ImportScope::find_insert_use_container(scope_node, &ctx.sema)?; 156 let scope = ImportScope::find_insert_use_container(scope_node, &ctx.sema)?;
157 *rewriter += insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use.merge); 157 *rewriter += insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use);
158 } 158 }
159 Some(()) 159 Some(())
160} 160}
diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
index f3bc6cf39..55481af34 100644
--- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -44,7 +44,7 @@ pub(crate) fn replace_qualified_name_with_use(
44 let mut rewriter = SyntaxRewriter::default(); 44 let mut rewriter = SyntaxRewriter::default();
45 shorten_paths(&mut rewriter, syntax.clone(), &path); 45 shorten_paths(&mut rewriter, syntax.clone(), &path);
46 if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { 46 if let Some(ref import_scope) = ImportScope::from(syntax.clone()) {
47 rewriter += insert_use(import_scope, path, ctx.config.insert_use.merge); 47 rewriter += insert_use(import_scope, path, ctx.config.insert_use);
48 builder.rewrite(rewriter); 48 builder.rewrite(rewriter);
49 } 49 }
50 }, 50 },
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index b7f616760..a7a923beb 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -23,6 +23,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
23 insert_use: InsertUseConfig { 23 insert_use: InsertUseConfig {
24 merge: Some(MergeBehavior::Full), 24 merge: Some(MergeBehavior::Full),
25 prefix_kind: hir::PrefixKind::Plain, 25 prefix_kind: hir::PrefixKind::Plain,
26 group: true,
26 }, 27 },
27}; 28};
28 29
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 884711f11..9b2435c4b 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -5,7 +5,7 @@ use std::fmt;
5use hir::{Documentation, ModPath, Mutability}; 5use hir::{Documentation, ModPath, Mutability};
6use ide_db::{ 6use ide_db::{
7 helpers::{ 7 helpers::{
8 insert_use::{self, ImportScope, MergeBehavior}, 8 insert_use::{self, ImportScope, InsertUseConfig},
9 mod_path_to_ast, SnippetCap, 9 mod_path_to_ast, SnippetCap,
10 }, 10 },
11 SymbolKind, 11 SymbolKind,
@@ -280,14 +280,11 @@ pub struct ImportEdit {
280impl ImportEdit { 280impl ImportEdit {
281 /// Attempts to insert the import to the given scope, producing a text edit. 281 /// Attempts to insert the import to the given scope, producing a text edit.
282 /// May return no edit in edge cases, such as scope already containing the import. 282 /// May return no edit in edge cases, such as scope already containing the import.
283 pub fn to_text_edit(&self, merge_behavior: Option<MergeBehavior>) -> Option<TextEdit> { 283 pub fn to_text_edit(&self, cfg: InsertUseConfig) -> Option<TextEdit> {
284 let _p = profile::span("ImportEdit::to_text_edit"); 284 let _p = profile::span("ImportEdit::to_text_edit");
285 285
286 let rewriter = insert_use::insert_use( 286 let rewriter =
287 &self.import_scope, 287 insert_use::insert_use(&self.import_scope, mod_path_to_ast(&self.import_path), cfg);
288 mod_path_to_ast(&self.import_path),
289 merge_behavior,
290 );
291 let old_ast = rewriter.rewrite_root()?; 288 let old_ast = rewriter.rewrite_root()?;
292 let mut import_insert = TextEdit::builder(); 289 let mut import_insert = TextEdit::builder();
293 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut import_insert); 290 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut import_insert);
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 76f31de9e..b0b809791 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -156,7 +156,7 @@ pub fn resolve_completion_edits(
156 .find(|mod_path| mod_path.to_string() == full_import_path)?; 156 .find(|mod_path| mod_path.to_string() == full_import_path)?;
157 157
158 ImportEdit { import_path, import_scope, import_for_trait_assoc_item } 158 ImportEdit { import_path, import_scope, import_for_trait_assoc_item }
159 .to_text_edit(config.insert_use.merge) 159 .to_text_edit(config.insert_use)
160 .map(|edit| vec![edit]) 160 .map(|edit| vec![edit])
161} 161}
162 162
diff --git a/crates/ide_completion/src/test_utils.rs b/crates/ide_completion/src/test_utils.rs
index baff83305..9da844031 100644
--- a/crates/ide_completion/src/test_utils.rs
+++ b/crates/ide_completion/src/test_utils.rs
@@ -25,6 +25,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
25 insert_use: InsertUseConfig { 25 insert_use: InsertUseConfig {
26 merge: Some(MergeBehavior::Full), 26 merge: Some(MergeBehavior::Full),
27 prefix_kind: PrefixKind::Plain, 27 prefix_kind: PrefixKind::Plain,
28 group: true,
28 }, 29 },
29}; 30};
30 31
@@ -119,7 +120,7 @@ pub(crate) fn check_edit_with_config(
119 120
120 let mut combined_edit = completion.text_edit().to_owned(); 121 let mut combined_edit = completion.text_edit().to_owned();
121 if let Some(import_text_edit) = 122 if let Some(import_text_edit) =
122 completion.import_to_add().and_then(|edit| edit.to_text_edit(config.insert_use.merge)) 123 completion.import_to_add().and_then(|edit| edit.to_text_edit(config.insert_use))
123 { 124 {
124 combined_edit.union(import_text_edit).expect( 125 combined_edit.union(import_text_edit).expect(
125 "Failed to apply completion resolve changes: change ranges overlap, but should not", 126 "Failed to apply completion resolve changes: change ranges overlap, but should not",
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index fd4035198..f52aee344 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -19,6 +19,7 @@ use test_utils::mark;
19pub struct InsertUseConfig { 19pub struct InsertUseConfig {
20 pub merge: Option<MergeBehavior>, 20 pub merge: Option<MergeBehavior>,
21 pub prefix_kind: hir::PrefixKind, 21 pub prefix_kind: hir::PrefixKind,
22 pub group: bool,
22} 23}
23 24
24#[derive(Debug, Clone)] 25#[derive(Debug, Clone)]
@@ -99,13 +100,13 @@ fn is_inner_comment(token: SyntaxToken) -> bool {
99pub fn insert_use<'a>( 100pub fn insert_use<'a>(
100 scope: &ImportScope, 101 scope: &ImportScope,
101 path: ast::Path, 102 path: ast::Path,
102 merge: Option<MergeBehavior>, 103 cfg: InsertUseConfig,
103) -> SyntaxRewriter<'a> { 104) -> SyntaxRewriter<'a> {
104 let _p = profile::span("insert_use"); 105 let _p = profile::span("insert_use");
105 let mut rewriter = SyntaxRewriter::default(); 106 let mut rewriter = SyntaxRewriter::default();
106 let use_item = make::use_(None, make::use_tree(path.clone(), None, None, false)); 107 let use_item = make::use_(None, make::use_tree(path.clone(), None, None, false));
107 // merge into existing imports if possible 108 // merge into existing imports if possible
108 if let Some(mb) = merge { 109 if let Some(mb) = cfg.merge {
109 for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { 110 for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) {
110 if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { 111 if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) {
111 rewriter.replace(existing_use.syntax(), merged.syntax()); 112 rewriter.replace(existing_use.syntax(), merged.syntax());
@@ -116,7 +117,7 @@ pub fn insert_use<'a>(
116 117
117 // either we weren't allowed to merge or there is no import that fits the merge conditions 118 // either we weren't allowed to merge or there is no import that fits the merge conditions
118 // so look for the place we have to insert to 119 // so look for the place we have to insert to
119 let (insert_position, add_blank) = find_insert_position(scope, path); 120 let (insert_position, add_blank) = find_insert_position(scope, path, cfg.group);
120 121
121 let indent = if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize { 122 let indent = if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize {
122 Some(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into()) 123 Some(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into())
@@ -538,6 +539,7 @@ impl AddBlankLine {
538fn find_insert_position( 539fn find_insert_position(
539 scope: &ImportScope, 540 scope: &ImportScope,
540 insert_path: ast::Path, 541 insert_path: ast::Path,
542 group_imports: bool,
541) -> (InsertPosition<SyntaxElement>, AddBlankLine) { 543) -> (InsertPosition<SyntaxElement>, AddBlankLine) {
542 let group = ImportGroup::new(&insert_path); 544 let group = ImportGroup::new(&insert_path);
543 let path_node_iter = scope 545 let path_node_iter = scope
@@ -550,6 +552,14 @@ fn find_insert_position(
550 let has_tl = tree.use_tree_list().is_some(); 552 let has_tl = tree.use_tree_list().is_some();
551 Some((path, has_tl, node)) 553 Some((path, has_tl, node))
552 }); 554 });
555
556 if !group_imports {
557 if let Some((_, _, node)) = path_node_iter.last() {
558 return (InsertPosition::After(node.into()), AddBlankLine::Before);
559 }
560 return (InsertPosition::First, AddBlankLine::AfterTwice);
561 }
562
553 // Iterator that discards anything thats not in the required grouping 563 // Iterator that discards anything thats not in the required grouping
554 // This implementation allows the user to rearrange their import groups as this only takes the first group that fits 564 // This implementation allows the user to rearrange their import groups as this only takes the first group that fits
555 let group_iter = path_node_iter 565 let group_iter = path_node_iter
@@ -565,6 +575,7 @@ fn find_insert_position(
565 use_tree_path_cmp(&insert_path, false, path, has_tl) != Ordering::Greater 575 use_tree_path_cmp(&insert_path, false, path, has_tl) != Ordering::Greater
566 }, 576 },
567 ); 577 );
578
568 match post_insert { 579 match post_insert {
569 // insert our import before that element 580 // insert our import before that element
570 Some((.., node)) => (InsertPosition::Before(node.into()), AddBlankLine::After), 581 Some((.., node)) => (InsertPosition::Before(node.into()), AddBlankLine::After),
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs
index 4bbe66f1f..67d0d6fb6 100644
--- a/crates/ide_db/src/helpers/insert_use/tests.rs
+++ b/crates/ide_db/src/helpers/insert_use/tests.rs
@@ -1,8 +1,32 @@
1use super::*; 1use super::*;
2 2
3use hir::PrefixKind;
3use test_utils::assert_eq_text; 4use test_utils::assert_eq_text;
4 5
5#[test] 6#[test]
7fn insert_not_group() {
8 check(
9 "use external_crate2::bar::A",
10 r"
11use std::bar::B;
12use external_crate::bar::A;
13use crate::bar::A;
14use self::bar::A;
15use super::bar::A;",
16 r"
17use std::bar::B;
18use external_crate::bar::A;
19use crate::bar::A;
20use self::bar::A;
21use super::bar::A;
22use external_crate2::bar::A;",
23 None,
24 false,
25 false,
26 );
27}
28
29#[test]
6fn insert_existing() { 30fn insert_existing() {
7 check_full("std::fs", "use std::fs;", "use std::fs;") 31 check_full("std::fs", "use std::fs;", "use std::fs;")
8} 32}
@@ -240,6 +264,7 @@ fn insert_empty_module() {
240}", 264}",
241 None, 265 None,
242 true, 266 true,
267 true,
243 ) 268 )
244} 269}
245 270
@@ -584,6 +609,7 @@ fn check(
584 ra_fixture_after: &str, 609 ra_fixture_after: &str,
585 mb: Option<MergeBehavior>, 610 mb: Option<MergeBehavior>,
586 module: bool, 611 module: bool,
612 group: bool,
587) { 613) {
588 let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone(); 614 let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone();
589 if module { 615 if module {
@@ -597,21 +623,25 @@ fn check(
597 .find_map(ast::Path::cast) 623 .find_map(ast::Path::cast)
598 .unwrap(); 624 .unwrap();
599 625
600 let rewriter = insert_use(&file, path, mb); 626 let rewriter = insert_use(
627 &file,
628 path,
629 InsertUseConfig { merge: mb, prefix_kind: PrefixKind::Plain, group },
630 );
601 let result = rewriter.rewrite(file.as_syntax_node()).to_string(); 631 let result = rewriter.rewrite(file.as_syntax_node()).to_string();
602 assert_eq_text!(ra_fixture_after, &result); 632 assert_eq_text!(ra_fixture_after, &result);
603} 633}
604 634
605fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 635fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
606 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Full), false) 636 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Full), false, true)
607} 637}
608 638
609fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 639fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
610 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Last), false) 640 check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehavior::Last), false, true)
611} 641}
612 642
613fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { 643fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
614 check(path, ra_fixture_before, ra_fixture_after, None, false) 644 check(path, ra_fixture_before, ra_fixture_after, None, false, true)
615} 645}
616 646
617fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior) { 647fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior) {
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 8789f0852..3130785cc 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -24,7 +24,7 @@ jod-thread = "0.1.0"
24log = "0.4.8" 24log = "0.4.8"
25lsp-types = { version = "0.88.0", features = ["proposed"] } 25lsp-types = { version = "0.88.0", features = ["proposed"] }
26parking_lot = "0.11.0" 26parking_lot = "0.11.0"
27xflags = "0.1.2" 27xflags = "0.2.1"
28oorandom = "11.1.2" 28oorandom = "11.1.2"
29rustc-hash = "1.1.0" 29rustc-hash = "1.1.0"
30serde = { version = "1.0.106", features = ["derive"] } 30serde = { version = "1.0.106", features = ["derive"] }
diff --git a/crates/rust-analyzer/src/bin/flags.rs b/crates/rust-analyzer/src/bin/flags.rs
index 244912d26..3a7caaf3f 100644
--- a/crates/rust-analyzer/src/bin/flags.rs
+++ b/crates/rust-analyzer/src/bin/flags.rs
@@ -6,7 +6,9 @@ use ide_ssr::{SsrPattern, SsrRule};
6use rust_analyzer::cli::{BenchWhat, Position, Verbosity}; 6use rust_analyzer::cli::{BenchWhat, Position, Verbosity};
7use vfs::AbsPathBuf; 7use vfs::AbsPathBuf;
8 8
9xflags::args_parser! { 9xflags::xflags! {
10 src "./src/bin/flags.rs"
11
10 /// LSP server for the Rust programming language. 12 /// LSP server for the Rust programming language.
11 cmd rust-analyzer { 13 cmd rust-analyzer {
12 /// Verbosity level, can be repeated multiple times. 14 /// Verbosity level, can be repeated multiple times.
@@ -120,7 +122,7 @@ xflags::args_parser! {
120 122
121// generated start 123// generated start
122// The following code is generated by `xflags` macro. 124// The following code is generated by `xflags` macro.
123// Run `env XFLAGS_DUMP= cargo build` to regenerate. 125// Run `env UPDATE_XFLAGS=1 cargo build` to regenerate.
124#[derive(Debug)] 126#[derive(Debug)]
125pub struct RustAnalyzer { 127pub struct RustAnalyzer {
126 pub verbose: u32, 128 pub verbose: u32,
@@ -158,7 +160,7 @@ pub struct Parse {
158} 160}
159 161
160#[derive(Debug)] 162#[derive(Debug)]
161pub struct Symbols {} 163pub struct Symbols;
162 164
163#[derive(Debug)] 165#[derive(Debug)]
164pub struct Highlight { 166pub struct Highlight {
@@ -211,14 +213,13 @@ pub struct Search {
211} 213}
212 214
213#[derive(Debug)] 215#[derive(Debug)]
214pub struct ProcMacro {} 216pub struct ProcMacro;
215 217
216impl RustAnalyzer { 218impl RustAnalyzer {
217 pub const HELP: &'static str = Self::_HELP; 219 pub const HELP: &'static str = Self::HELP_;
218 220
219 pub fn from_env() -> xflags::Result<Self> { 221 pub fn from_env() -> xflags::Result<Self> {
220 let mut p = xflags::rt::Parser::new_from_env(); 222 Self::from_env_()
221 Self::_parse(&mut p)
222 } 223 }
223} 224}
224// generated end 225// generated end
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index 3bd7e678d..49994824f 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -108,7 +108,11 @@ impl BenchCmd {
108 add_call_parenthesis: true, 108 add_call_parenthesis: true,
109 add_call_argument_snippets: true, 109 add_call_argument_snippets: true,
110 snippet_cap: SnippetCap::new(true), 110 snippet_cap: SnippetCap::new(true),
111 insert_use: InsertUseConfig { merge: None, prefix_kind: PrefixKind::Plain }, 111 insert_use: InsertUseConfig {
112 merge: None,
113 prefix_kind: PrefixKind::Plain,
114 group: true,
115 },
112 }; 116 };
113 let res = do_work(&mut host, file_id, |analysis| { 117 let res = do_work(&mut host, file_id, |analysis| {
114 analysis.completions(&options, file_position) 118 analysis.completions(&options, file_position)
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 367136702..cac48e911 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -35,7 +35,8 @@ config_data! {
35 assist_importMergeBehaviour: MergeBehaviorDef = "\"full\"", 35 assist_importMergeBehaviour: MergeBehaviorDef = "\"full\"",
36 /// The path structure for newly inserted paths to use. 36 /// The path structure for newly inserted paths to use.
37 assist_importPrefix: ImportPrefixDef = "\"plain\"", 37 assist_importPrefix: ImportPrefixDef = "\"plain\"",
38 38 /// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
39 assist_importGroup: bool = "true",
39 /// Show function name and docs in parameter hints. 40 /// Show function name and docs in parameter hints.
40 callInfo_full: bool = "true", 41 callInfo_full: bool = "true",
41 42
@@ -574,6 +575,7 @@ impl Config {
574 ImportPrefixDef::ByCrate => PrefixKind::ByCrate, 575 ImportPrefixDef::ByCrate => PrefixKind::ByCrate,
575 ImportPrefixDef::BySelf => PrefixKind::BySelf, 576 ImportPrefixDef::BySelf => PrefixKind::BySelf,
576 }, 577 },
578 group: self.data.assist_importGroup,
577 } 579 }
578 } 580 }
579 pub fn completion(&self) -> CompletionConfig { 581 pub fn completion(&self) -> CompletionConfig {
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index c1ca88df6..4235eb6dd 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1087,7 +1087,11 @@ mod tests {
1087 add_call_parenthesis: true, 1087 add_call_parenthesis: true,
1088 add_call_argument_snippets: true, 1088 add_call_argument_snippets: true,
1089 snippet_cap: SnippetCap::new(true), 1089 snippet_cap: SnippetCap::new(true),
1090 insert_use: InsertUseConfig { merge: None, prefix_kind: PrefixKind::Plain }, 1090 insert_use: InsertUseConfig {
1091 merge: None,
1092 prefix_kind: PrefixKind::Plain,
1093 group: true,
1094 },
1091 }, 1095 },
1092 ide_db::base_db::FilePosition { file_id, offset }, 1096 ide_db::base_db::FilePosition { file_id, offset },
1093 ) 1097 )
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 1dbf2a611..e564c1427 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -2,6 +2,8 @@
2 The strategy to use when inserting new imports or merging imports. 2 The strategy to use when inserting new imports or merging imports.
3[[rust-analyzer.assist.importPrefix]]rust-analyzer.assist.importPrefix (default: `"plain"`):: 3[[rust-analyzer.assist.importPrefix]]rust-analyzer.assist.importPrefix (default: `"plain"`)::
4 The path structure for newly inserted paths to use. 4 The path structure for newly inserted paths to use.
5[[rust-analyzer.assist.importGroup]]rust-analyzer.assist.importGroup (default: `true`)::
6 Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
5[[rust-analyzer.callInfo.full]]rust-analyzer.callInfo.full (default: `true`):: 7[[rust-analyzer.callInfo.full]]rust-analyzer.callInfo.full (default: `true`)::
6 Show function name and docs in parameter hints. 8 Show function name and docs in parameter hints.
7[[rust-analyzer.cargo.autoreload]]rust-analyzer.cargo.autoreload (default: `true`):: 9[[rust-analyzer.cargo.autoreload]]rust-analyzer.cargo.autoreload (default: `true`)::
diff --git a/editors/code/package.json b/editors/code/package.json
index 68f58d3ca..176f47920 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -386,6 +386,11 @@
386 "Force import paths to be absolute by always starting them with `crate` or the crate name they refer to." 386 "Force import paths to be absolute by always starting them with `crate` or the crate name they refer to."
387 ] 387 ]
388 }, 388 },
389 "rust-analyzer.assist.importGroup": {
390 "markdownDescription": "Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.",
391 "default": true,
392 "type": "boolean"
393 },
389 "rust-analyzer.callInfo.full": { 394 "rust-analyzer.callInfo.full": {
390 "markdownDescription": "Show function name and docs in parameter hints.", 395 "markdownDescription": "Show function name and docs in parameter hints.",
391 "default": true, 396 "default": true,
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index b17dde598..e084f0df6 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -15,5 +15,5 @@ ungrammar = "=1.11"
15walkdir = "2.3.1" 15walkdir = "2.3.1"
16write-json = "0.1.0" 16write-json = "0.1.0"
17xshell = "0.1" 17xshell = "0.1"
18xflags = "0.1.2" 18xflags = "0.2.1"
19# Avoid adding more dependencies to this crate 19# Avoid adding more dependencies to this crate
diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs
index 56eda5b1e..b39d937ca 100644
--- a/xtask/src/flags.rs
+++ b/xtask/src/flags.rs
@@ -2,7 +2,9 @@
2 2
3use crate::install::{ClientOpt, Malloc, ServerOpt}; 3use crate::install::{ClientOpt, Malloc, ServerOpt};
4 4
5xflags::args_parser! { 5xflags::xflags! {
6 src "./src/flags.rs"
7
6 /// Run custom build command. 8 /// Run custom build command.
7 cmd xtask { 9 cmd xtask {
8 default cmd help { 10 default cmd help {
@@ -55,7 +57,7 @@ xflags::args_parser! {
55 57
56// generated start 58// generated start
57// The following code is generated by `xflags` macro. 59// The following code is generated by `xflags` macro.
58// Run `env XFLAGS_DUMP= cargo build` to regenerate. 60// Run `env UPDATE_XFLAGS=1 cargo build` to regenerate.
59#[derive(Debug)] 61#[derive(Debug)]
60pub struct Xtask { 62pub struct Xtask {
61 pub subcommand: XtaskCmd, 63 pub subcommand: XtaskCmd,
@@ -96,13 +98,13 @@ pub struct Codegen {
96} 98}
97 99
98#[derive(Debug)] 100#[derive(Debug)]
99pub struct Lint {} 101pub struct Lint;
100 102
101#[derive(Debug)] 103#[derive(Debug)]
102pub struct FuzzTests {} 104pub struct FuzzTests;
103 105
104#[derive(Debug)] 106#[derive(Debug)]
105pub struct PreCache {} 107pub struct PreCache;
106 108
107#[derive(Debug)] 109#[derive(Debug)]
108pub struct Release { 110pub struct Release {
@@ -131,11 +133,10 @@ pub struct Bb {
131} 133}
132 134
133impl Xtask { 135impl Xtask {
134 pub const HELP: &'static str = Self::_HELP; 136 pub const HELP: &'static str = Self::HELP_;
135 137
136 pub fn from_env() -> xflags::Result<Self> { 138 pub fn from_env() -> xflags::Result<Self> {
137 let mut p = xflags::rt::Parser::new_from_env(); 139 Self::from_env_()
138 Self::_parse(&mut p)
139 } 140 }
140} 141}
141// generated end 142// generated end