about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-06 15:03:41 +0000
committerGitHub <noreply@github.com>2024-12-06 15:03:41 +0000
commit5b2fcf327ec4e2c00f40a9173c7b6700f7201816 (patch)
tree943cf7e62572ff50360d9d63d2113931a0d18190
parent9549e473a02aba6f3bd8bf5b988c5c7ca1c03e82 (diff)
parent3fe75c7d90e9e42dbbc7c6542337a68ff9b817cf (diff)
downloadrust-5b2fcf327ec4e2c00f40a9173c7b6700f7201816.tar.gz
rust-5b2fcf327ec4e2c00f40a9173c7b6700f7201816.zip
Merge pull request #18628 from Veykril/push-sqpymrtxysmw
Add typing handler for param list pipe
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/typing.rs67
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs17
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc4
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json4
6 files changed, 69 insertions, 29 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index b43685ffeed..c960b88a3e9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -402,6 +402,8 @@ impl Analysis {
         self.with_db(|db| typing::on_enter(db, position))
     }
 
+    pub const SUPPORTED_TRIGGER_CHARS: &'static str = typing::TRIGGER_CHARS;
+
     /// Returns an edit which should be applied after a character was typed.
     ///
     /// This is useful for some on-the-fly fixups, like adding `;` to `let =`
diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs
index cfa1d6ff031..3d9146cc4c7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/typing.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs
@@ -32,7 +32,7 @@ use crate::SourceChange;
 pub(crate) use on_enter::on_enter;
 
 // Don't forget to add new trigger characters to `server_capabilities` in `caps.rs`.
-pub(crate) const TRIGGER_CHARS: &str = ".=<>{(";
+pub(crate) const TRIGGER_CHARS: &str = ".=<>{(|";
 
 struct ExtendedTextEdit {
     edit: TextEdit,
@@ -99,6 +99,7 @@ fn on_char_typed_(
         '=' => on_eq_typed(&file.tree(), offset),
         '>' => on_right_angle_typed(&file.tree(), offset),
         '{' | '(' | '<' => on_opening_delimiter_typed(file, offset, char_typed, edition),
+        '|' => on_pipe_typed(&file.tree(), offset),
         _ => None,
     }
     .map(conv)
@@ -212,10 +213,6 @@ fn on_delimited_node_typed(
 // FIXME: use a snippet completion instead of this hack here.
 fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
     let text = file.syntax().text();
-    if !stdx::always!(text.char_at(offset) == Some('=')) {
-        return None;
-    }
-
     let has_newline = iter::successors(Some(offset), |&offset| Some(offset + TextSize::new(1)))
         .filter_map(|offset| text.char_at(offset))
         .find(|&c| !c.is_whitespace() || c == '\n')
@@ -308,9 +305,6 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
 
 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
 fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
-    if !stdx::always!(file.syntax().text().char_at(offset) == Some('.')) {
-        return None;
-    }
     let whitespace =
         file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?;
 
@@ -380,7 +374,9 @@ fn on_left_angle_typed(
     if ancestors_at_offset(file.syntax(), offset)
         .take_while(|n| !ast::Item::can_cast(n.kind()))
         .any(|n| {
-            ast::GenericParamList::can_cast(n.kind()) || ast::GenericArgList::can_cast(n.kind())
+            ast::GenericParamList::can_cast(n.kind())
+                || ast::GenericArgList::can_cast(n.kind())
+                || ast::UseBoundGenericArgs::can_cast(n.kind())
         })
     {
         // Insert the closing bracket right after
@@ -390,12 +386,21 @@ fn on_left_angle_typed(
     }
 }
 
+fn on_pipe_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
+    let pipe_token = file.syntax().token_at_offset(offset).right_biased()?;
+    if pipe_token.kind() != SyntaxKind::PIPE {
+        return None;
+    }
+    if pipe_token.parent().and_then(ast::ParamList::cast)?.r_paren_token().is_some() {
+        return None;
+    }
+    let after_lpipe = offset + TextSize::of('|');
+    Some(TextEdit::insert(after_lpipe, "|".to_owned()))
+}
+
 /// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }`
 fn on_right_angle_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
     let file_text = file.syntax().text();
-    if !stdx::always!(file_text.char_at(offset) == Some('>')) {
-        return None;
-    }
     let after_arrow = offset + TextSize::of('>');
     if file_text.char_at(after_arrow) != Some('{') {
         return None;
@@ -1530,4 +1535,42 @@ fn foo() {
 "#,
         );
     }
+
+    #[test]
+    fn completes_pipe_param_list() {
+        type_char(
+            '|',
+            r#"
+fn foo() {
+    $0
+}
+"#,
+            r#"
+fn foo() {
+    ||
+}
+"#,
+        );
+        type_char(
+            '|',
+            r#"
+fn foo() {
+    $0 a
+}
+"#,
+            r#"
+fn foo() {
+    || a
+}
+"#,
+        );
+        type_char_noop(
+            '|',
+            r#"
+fn foo() {
+    let $0
+}
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 392bfbf15fe..0fdc48a0e7a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -308,8 +308,8 @@ config_data! {
         /// Show documentation.
         signatureInfo_documentation_enable: bool                       = true,
 
-        /// Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`. Setting this to a string will disable typing assists for the specified characters.
-        typing_excludeChars: Option<String> = None,
+        /// Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.
+        typing_excludeChars: Option<String> = Some('<'.to_string()),
 
 
         /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs
index bd496e8ddc3..82e6ae2b49c 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs
@@ -72,9 +72,12 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
             RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
             _ => Some(OneOf::Left(false)),
         },
-        document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
-            first_trigger_character: "=".to_owned(),
-            more_trigger_character: Some(more_trigger_character(config)),
+        document_on_type_formatting_provider: Some({
+            let mut chars = ide::Analysis::SUPPORTED_TRIGGER_CHARS.chars();
+            DocumentOnTypeFormattingOptions {
+                first_trigger_character: chars.next().unwrap().to_string(),
+                more_trigger_character: Some(chars.map(|c| c.to_string()).collect()),
+            }
         }),
         selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
         folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
@@ -528,11 +531,3 @@ impl ClientCapabilities {
         .unwrap_or_default()
     }
 }
-
-fn more_trigger_character(config: &Config) -> Vec<String> {
-    let mut res = vec![".".to_owned(), ">".to_owned(), "{".to_owned(), "(".to_owned()];
-    if config.snippet_cap().is_some() {
-        res.push("<".to_owned());
-    }
-    res
-}
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index a3172c7ca2c..715f8d43adc 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -992,10 +992,10 @@ Show full signature of the callable. Only shows parameters if disabled.
 --
 Show documentation.
 --
-[[rust-analyzer.typing.excludeChars]]rust-analyzer.typing.excludeChars (default: `null`)::
+[[rust-analyzer.typing.excludeChars]]rust-analyzer.typing.excludeChars (default: `"<"`)::
 +
 --
-Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`. Setting this to a string will disable typing assists for the specified characters.
+Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.
 --
 [[rust-analyzer.workspace.discoverConfig]]rust-analyzer.workspace.discoverConfig (default: `null`)::
 +
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 68c61e4bf62..70d26c97078 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -2606,8 +2606,8 @@
                 "title": "typing",
                 "properties": {
                     "rust-analyzer.typing.excludeChars": {
-                        "markdownDescription": "Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`. Setting this to a string will disable typing assists for the specified characters.",
-                        "default": null,
+                        "markdownDescription": "Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.",
+                        "default": "<",
                         "type": [
                             "null",
                             "string"