Skip to content

Commit 1c6a2eb

Browse files
committed
Move the rest of the features to generated docs
1 parent b795a07 commit 1c6a2eb

File tree

10 files changed

+358
-240
lines changed

10 files changed

+358
-240
lines changed

crates/ra_ide/src/completion.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//! FIXME: write short doc here
2-
31
mod completion_config;
42
mod completion_item;
53
mod completion_context;
@@ -35,6 +33,51 @@ pub use crate::completion::{
3533
completion_item::{CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat},
3634
};
3735

36+
//FIXME: split the following feature into fine-grained features.
37+
38+
// Feature: Magic Completions
39+
//
40+
// In addition to usual reference completion, rust-analyzer provides some ✨magic✨
41+
// completions as well:
42+
//
43+
// Keywords like `if`, `else` `while`, `loop` are completed with braces, and cursor
44+
// is placed at the appropriate position. Even though `if` is easy to type, you
45+
// still want to complete it, to get ` { }` for free! `return` is inserted with a
46+
// space or `;` depending on the return type of the function.
47+
//
48+
// When completing a function call, `()` are automatically inserted. If a function
49+
// takes arguments, the cursor is positioned inside the parenthesis.
50+
//
51+
// There are postfix completions, which can be triggered by typing something like
52+
// `foo().if`. The word after `.` determines postfix completion. Possible variants are:
53+
//
54+
// - `expr.if` -> `if expr {}` or `if let ... {}` for `Option` or `Result`
55+
// - `expr.match` -> `match expr {}`
56+
// - `expr.while` -> `while expr {}` or `while let ... {}` for `Option` or `Result`
57+
// - `expr.ref` -> `&expr`
58+
// - `expr.refm` -> `&mut expr`
59+
// - `expr.not` -> `!expr`
60+
// - `expr.dbg` -> `dbg!(expr)`
61+
//
62+
// There also snippet completions:
63+
//
64+
// .Expressions
65+
// - `pd` -> `println!("{:?}")`
66+
// - `ppd` -> `println!("{:#?}")`
67+
//
68+
// .Items
69+
// - `tfn` -> `#[test] fn f(){}`
70+
// - `tmod` ->
71+
// ```rust
72+
// #[cfg(test)]
73+
// mod tests {
74+
// use super::*;
75+
//
76+
// #[test]
77+
// fn test_fn() {}
78+
// }
79+
// ```
80+
3881
/// Main entry point for completion. We run completion as a two-phase process.
3982
///
4083
/// First, we look at the position and collect a so-called `CompletionContext.

crates/ra_ide/src/completion/complete_postfix.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
//! FIXME: write short doc here
2-
2+
use ra_assists::utils::TryEnum;
33
use ra_syntax::{
44
ast::{self, AstNode},
55
TextRange, TextSize,
66
};
77
use ra_text_edit::TextEdit;
88

9-
use super::completion_config::SnippetCap;
109
use crate::{
1110
completion::{
1211
completion_context::CompletionContext,
1312
completion_item::{Builder, CompletionKind, Completions},
1413
},
1514
CompletionItem,
1615
};
17-
use ra_assists::utils::TryEnum;
16+
17+
use super::completion_config::SnippetCap;
1818

1919
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
2020
if !ctx.config.enable_postfix_completions {

crates/ra_ide/src/hover.rs

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
//! Logic for computing info that is displayed when the user hovers over any
2-
//! source code items (e.g. function call, struct field, variable symbol...)
1+
use std::iter::once;
32

43
use hir::{
54
Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef,
65
ModuleSource, Semantics,
76
};
7+
use itertools::Itertools;
88
use ra_db::SourceDatabase;
99
use ra_ide_db::{
1010
defs::{classify_name, classify_name_ref, Definition},
@@ -21,8 +21,6 @@ use crate::{
2121
display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
2222
FilePosition, RangeInfo,
2323
};
24-
use itertools::Itertools;
25-
use std::iter::once;
2624

2725
/// Contains the results when hovering over an item
2826
#[derive(Debug, Default)]
@@ -62,6 +60,63 @@ impl HoverResult {
6260
}
6361
}
6462

63+
// Feature: Hover
64+
//
65+
// Shows additional information, like type of an expression or documentation for definition when "focusing" code.
66+
// Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
67+
pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
68+
let sema = Semantics::new(db);
69+
let file = sema.parse(position.file_id).syntax().clone();
70+
let token = pick_best(file.token_at_offset(position.offset))?;
71+
let token = sema.descend_into_macros(token);
72+
73+
let mut res = HoverResult::new();
74+
75+
if let Some((node, name_kind)) = match_ast! {
76+
match (token.parent()) {
77+
ast::NameRef(name_ref) => {
78+
classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d.definition()))
79+
},
80+
ast::Name(name) => {
81+
classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition()))
82+
},
83+
_ => None,
84+
}
85+
} {
86+
let range = sema.original_range(&node).range;
87+
res.extend(hover_text_from_name_kind(db, name_kind));
88+
89+
if !res.is_empty() {
90+
return Some(RangeInfo::new(range, res));
91+
}
92+
}
93+
94+
let node = token
95+
.ancestors()
96+
.find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?;
97+
98+
let ty = match_ast! {
99+
match node {
100+
ast::MacroCall(_it) => {
101+
// If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
102+
// (e.g expanding a builtin macro). So we give up here.
103+
return None;
104+
},
105+
ast::Expr(it) => {
106+
sema.type_of_expr(&it)
107+
},
108+
ast::Pat(it) => {
109+
sema.type_of_pat(&it)
110+
},
111+
_ => None,
112+
}
113+
}?;
114+
115+
res.extend(Some(rust_code_markup(&ty.display(db))));
116+
let range = sema.original_range(&node).range;
117+
Some(RangeInfo::new(range, res))
118+
}
119+
65120
fn hover_text(
66121
docs: Option<String>,
67122
desc: Option<String>,
@@ -160,59 +215,6 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin
160215
}
161216
}
162217

163-
pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
164-
let sema = Semantics::new(db);
165-
let file = sema.parse(position.file_id).syntax().clone();
166-
let token = pick_best(file.token_at_offset(position.offset))?;
167-
let token = sema.descend_into_macros(token);
168-
169-
let mut res = HoverResult::new();
170-
171-
if let Some((node, name_kind)) = match_ast! {
172-
match (token.parent()) {
173-
ast::NameRef(name_ref) => {
174-
classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d.definition()))
175-
},
176-
ast::Name(name) => {
177-
classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition()))
178-
},
179-
_ => None,
180-
}
181-
} {
182-
let range = sema.original_range(&node).range;
183-
res.extend(hover_text_from_name_kind(db, name_kind));
184-
185-
if !res.is_empty() {
186-
return Some(RangeInfo::new(range, res));
187-
}
188-
}
189-
190-
let node = token
191-
.ancestors()
192-
.find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?;
193-
194-
let ty = match_ast! {
195-
match node {
196-
ast::MacroCall(_it) => {
197-
// If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
198-
// (e.g expanding a builtin macro). So we give up here.
199-
return None;
200-
},
201-
ast::Expr(it) => {
202-
sema.type_of_expr(&it)
203-
},
204-
ast::Pat(it) => {
205-
sema.type_of_pat(&it)
206-
},
207-
_ => None,
208-
}
209-
}?;
210-
211-
res.extend(Some(rust_code_markup(&ty.display(db))));
212-
let range = sema.original_range(&node).range;
213-
Some(RangeInfo::new(range, res))
214-
}
215-
216218
fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
217219
return tokens.max_by_key(priority);
218220
fn priority(n: &SyntaxToken) -> usize {

crates/ra_ide/src/inlay_hints.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//! This module defines multiple types of inlay hints and their visibility
2-
31
use hir::{Adt, HirDisplay, Semantics, Type};
42
use ra_ide_db::RootDatabase;
53
use ra_prof::profile;
@@ -39,6 +37,26 @@ pub struct InlayHint {
3937
pub label: SmolStr,
4038
}
4139

40+
// Feature: Inlay Hints
41+
//
42+
// rust-analyzer shows additional information inline with the source code.
43+
// Editors usually render this using read-only virtual text snippets interspersed with code.
44+
//
45+
// rust-analyzer shows hits for
46+
//
47+
// * types of local variables
48+
// * names of function arguments
49+
// * types of chained expressions
50+
//
51+
// **Note:** VS Code does not have native support for inlay hints https://github.com/microsoft/vscode/issues/16221[yet] and the hints are implemented using decorations.
52+
// This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird:
53+
// https://github.com/rust-analyzer/rust-analyzer/issues/1623[1], https://github.com/rust-analyzer/rust-analyzer/issues/3453[2].
54+
//
55+
// |===
56+
// | Editor | Action Name
57+
//
58+
// | VS Code | **Rust Analyzer: Toggle inlay hints*
59+
// |===
4260
pub(crate) fn inlay_hints(
4361
db: &RootDatabase,
4462
file_id: FileId,

0 commit comments

Comments
 (0)