Skip to content

Commit 54dbf1b

Browse files
committed
Add typing handler for param list pipe
1 parent 5dc5107 commit 54dbf1b

File tree

6 files changed

+69
-29
lines changed

6 files changed

+69
-29
lines changed

crates/ide/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ impl Analysis {
402402
self.with_db(|db| typing::on_enter(db, position))
403403
}
404404

405+
pub const SUPPORTED_TRIGGER_CHARS: &'static str = typing::TRIGGER_CHARS;
406+
405407
/// Returns an edit which should be applied after a character was typed.
406408
///
407409
/// This is useful for some on-the-fly fixups, like adding `;` to `let =`

crates/ide/src/typing.rs

+55-12
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::SourceChange;
3232
pub(crate) use on_enter::on_enter;
3333

3434
// Don't forget to add new trigger characters to `server_capabilities` in `caps.rs`.
35-
pub(crate) const TRIGGER_CHARS: &str = ".=<>{(";
35+
pub(crate) const TRIGGER_CHARS: &str = ".=<>{(|";
3636

3737
struct ExtendedTextEdit {
3838
edit: TextEdit,
@@ -99,6 +99,7 @@ fn on_char_typed_(
9999
'=' => on_eq_typed(&file.tree(), offset),
100100
'>' => on_right_angle_typed(&file.tree(), offset),
101101
'{' | '(' | '<' => on_opening_delimiter_typed(file, offset, char_typed, edition),
102+
'|' => on_pipe_typed(&file.tree(), offset),
102103
_ => None,
103104
}
104105
.map(conv)
@@ -212,10 +213,6 @@ fn on_delimited_node_typed(
212213
// FIXME: use a snippet completion instead of this hack here.
213214
fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
214215
let text = file.syntax().text();
215-
if !stdx::always!(text.char_at(offset) == Some('=')) {
216-
return None;
217-
}
218-
219216
let has_newline = iter::successors(Some(offset), |&offset| Some(offset + TextSize::new(1)))
220217
.filter_map(|offset| text.char_at(offset))
221218
.find(|&c| !c.is_whitespace() || c == '\n')
@@ -308,9 +305,6 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
308305

309306
/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
310307
fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
311-
if !stdx::always!(file.syntax().text().char_at(offset) == Some('.')) {
312-
return None;
313-
}
314308
let whitespace =
315309
file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?;
316310

@@ -380,7 +374,9 @@ fn on_left_angle_typed(
380374
if ancestors_at_offset(file.syntax(), offset)
381375
.take_while(|n| !ast::Item::can_cast(n.kind()))
382376
.any(|n| {
383-
ast::GenericParamList::can_cast(n.kind()) || ast::GenericArgList::can_cast(n.kind())
377+
ast::GenericParamList::can_cast(n.kind())
378+
|| ast::GenericArgList::can_cast(n.kind())
379+
|| ast::UseBoundGenericArgs::can_cast(n.kind())
384380
})
385381
{
386382
// Insert the closing bracket right after
@@ -390,12 +386,21 @@ fn on_left_angle_typed(
390386
}
391387
}
392388

389+
fn on_pipe_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
390+
let pipe_token = file.syntax().token_at_offset(offset).right_biased()?;
391+
if pipe_token.kind() != SyntaxKind::PIPE {
392+
return None;
393+
}
394+
if pipe_token.parent().and_then(ast::ParamList::cast)?.r_paren_token().is_some() {
395+
return None;
396+
}
397+
let after_lpipe = offset + TextSize::of('|');
398+
Some(TextEdit::insert(after_lpipe, "|".to_owned()))
399+
}
400+
393401
/// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }`
394402
fn on_right_angle_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
395403
let file_text = file.syntax().text();
396-
if !stdx::always!(file_text.char_at(offset) == Some('>')) {
397-
return None;
398-
}
399404
let after_arrow = offset + TextSize::of('>');
400405
if file_text.char_at(after_arrow) != Some('{') {
401406
return None;
@@ -1527,6 +1532,44 @@ fn foo() {
15271532
)
15281533
$0
15291534
}
1535+
"#,
1536+
);
1537+
}
1538+
1539+
#[test]
1540+
fn completes_pipe_param_list() {
1541+
type_char(
1542+
'|',
1543+
r#"
1544+
fn foo() {
1545+
$0
1546+
}
1547+
"#,
1548+
r#"
1549+
fn foo() {
1550+
||
1551+
}
1552+
"#,
1553+
);
1554+
type_char(
1555+
'|',
1556+
r#"
1557+
fn foo() {
1558+
$0 a
1559+
}
1560+
"#,
1561+
r#"
1562+
fn foo() {
1563+
|| a
1564+
}
1565+
"#,
1566+
);
1567+
type_char_noop(
1568+
'|',
1569+
r#"
1570+
fn foo() {
1571+
let $0
1572+
}
15301573
"#,
15311574
);
15321575
}

crates/rust-analyzer/src/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ config_data! {
308308
/// Show documentation.
309309
signatureInfo_documentation_enable: bool = true,
310310

311-
/// 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.
312-
typing_excludeChars: Option<String> = None,
311+
/// Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.
312+
typing_excludeChars: Option<String> = Some('<'.to_string()),
313313

314314

315315
/// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].

crates/rust-analyzer/src/lsp/capabilities.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,12 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
7272
RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
7373
_ => Some(OneOf::Left(false)),
7474
},
75-
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
76-
first_trigger_character: "=".to_owned(),
77-
more_trigger_character: Some(more_trigger_character(config)),
75+
document_on_type_formatting_provider: Some({
76+
let mut chars = ide::Analysis::SUPPORTED_TRIGGER_CHARS.chars();
77+
DocumentOnTypeFormattingOptions {
78+
first_trigger_character: chars.next().unwrap().to_string(),
79+
more_trigger_character: Some(chars.map(|c| c.to_string()).collect()),
80+
}
7881
}),
7982
selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
8083
folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
@@ -528,11 +531,3 @@ impl ClientCapabilities {
528531
.unwrap_or_default()
529532
}
530533
}
531-
532-
fn more_trigger_character(config: &Config) -> Vec<String> {
533-
let mut res = vec![".".to_owned(), ">".to_owned(), "{".to_owned(), "(".to_owned()];
534-
if config.snippet_cap().is_some() {
535-
res.push("<".to_owned());
536-
}
537-
res
538-
}

docs/user/generated_config.adoc

+2-2
Original file line numberDiff line numberDiff line change
@@ -992,10 +992,10 @@ Show full signature of the callable. Only shows parameters if disabled.
992992
--
993993
Show documentation.
994994
--
995-
[[rust-analyzer.typing.excludeChars]]rust-analyzer.typing.excludeChars (default: `null`)::
995+
[[rust-analyzer.typing.excludeChars]]rust-analyzer.typing.excludeChars (default: `"<"`)::
996996
+
997997
--
998-
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.
998+
Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.
999999
--
10001000
[[rust-analyzer.workspace.discoverConfig]]rust-analyzer.workspace.discoverConfig (default: `null`)::
10011001
+

editors/code/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2606,8 +2606,8 @@
26062606
"title": "typing",
26072607
"properties": {
26082608
"rust-analyzer.typing.excludeChars": {
2609-
"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.",
2610-
"default": null,
2609+
"markdownDescription": "Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.",
2610+
"default": "<",
26112611
"type": [
26122612
"null",
26132613
"string"

0 commit comments

Comments
 (0)