mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 20:43:21 +00:00
Generate features docs from source
This commit is contained in:
parent
383247a9ae
commit
c8f27a4a88
15 changed files with 258 additions and 58 deletions
|
@ -18,6 +18,19 @@ pub struct StructureNode {
|
|||
pub deprecated: bool,
|
||||
}
|
||||
|
||||
// Feature: File Structure
|
||||
//
|
||||
// Provides a tree of the symbols defined in the file. Can be used to
|
||||
//
|
||||
// * fuzzy search symbol in a file (super useful)
|
||||
// * draw breadcrumbs to describe the context around the cursor
|
||||
// * draw outline of the file
|
||||
//
|
||||
// |===
|
||||
// | Editor | Shortcut
|
||||
//
|
||||
// | VS Code | kbd:[Ctrl+Shift+O]
|
||||
// |===
|
||||
pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
|
||||
let mut res = Vec::new();
|
||||
let mut stack = Vec::new();
|
||||
|
|
|
@ -14,6 +14,16 @@ use ra_syntax::{
|
|||
|
||||
use crate::FileRange;
|
||||
|
||||
// Feature: Extend Selection
|
||||
//
|
||||
// Extends the current selection to the encompassing syntactic construct
|
||||
// (expression, statement, item, module, etc). It works with multiple cursors.
|
||||
//
|
||||
// |===
|
||||
// | Editor | Shortcut
|
||||
//
|
||||
// | VS Code | kbd:[Ctrl+Shift+→]
|
||||
// |===
|
||||
pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
|
||||
let sema = Semantics::new(db);
|
||||
let src = sema.parse(frange.file_id);
|
||||
|
|
|
@ -17,6 +17,15 @@ use crate::{
|
|||
FilePosition, NavigationTarget, RangeInfo,
|
||||
};
|
||||
|
||||
// Feature: Go To Definition
|
||||
//
|
||||
// Navigates to the definition of an identifier.
|
||||
//
|
||||
// |===
|
||||
// | Editor | Shortcut
|
||||
//
|
||||
// | VS Code | kbd:[F12]
|
||||
// |===
|
||||
pub(crate) fn goto_definition(
|
||||
db: &RootDatabase,
|
||||
position: FilePosition,
|
||||
|
|
|
@ -6,6 +6,15 @@ use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
|
|||
|
||||
use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||
|
||||
// Feature: Go To Implementation
|
||||
//
|
||||
// Navigates to the impl block of structs, enums or traits. Also implemented as a code lens.
|
||||
//
|
||||
// |===
|
||||
// | Editor | Shortcut
|
||||
//
|
||||
// | VS Code | kbd:[Ctrl+F12]
|
||||
// |===
|
||||
pub(crate) fn goto_implementation(
|
||||
db: &RootDatabase,
|
||||
position: FilePosition,
|
|
@ -5,6 +5,9 @@ use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffs
|
|||
|
||||
use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||
|
||||
// Feature: Go To Type Definition
|
||||
//
|
||||
// Navigates to the type of an identifier.
|
||||
pub(crate) fn goto_type_definition(
|
||||
db: &RootDatabase,
|
||||
position: FilePosition,
|
||||
|
|
|
@ -23,6 +23,7 @@ mod completion;
|
|||
mod runnables;
|
||||
mod goto_definition;
|
||||
mod goto_type_definition;
|
||||
mod goto_implementation;
|
||||
mod extend_selection;
|
||||
mod hover;
|
||||
mod call_hierarchy;
|
||||
|
@ -30,7 +31,6 @@ mod call_info;
|
|||
mod syntax_highlighting;
|
||||
mod parent_module;
|
||||
mod references;
|
||||
mod impls;
|
||||
mod diagnostics;
|
||||
mod syntax_tree;
|
||||
mod folding_ranges;
|
||||
|
@ -373,7 +373,7 @@ impl Analysis {
|
|||
&self,
|
||||
position: FilePosition,
|
||||
) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> {
|
||||
self.with_db(|db| impls::goto_implementation(db, position))
|
||||
self.with_db(|db| goto_implementation::goto_implementation(db, position))
|
||||
}
|
||||
|
||||
/// Returns the type definitions for the symbol at `position`.
|
||||
|
|
|
@ -32,6 +32,13 @@ pub(crate) use on_enter::on_enter;
|
|||
|
||||
pub(crate) const TRIGGER_CHARS: &str = ".=>";
|
||||
|
||||
// Feature: On Typing Assists
|
||||
//
|
||||
// Some features trigger on typing certain characters:
|
||||
//
|
||||
// - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression
|
||||
// - Enter inside comments automatically inserts `///`
|
||||
// - typing `.` in a chain method call auto-indents
|
||||
pub(crate) fn on_char_typed(
|
||||
db: &RootDatabase,
|
||||
position: FilePosition,
|
||||
|
|
|
@ -110,6 +110,27 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex>
|
|||
Arc::new(SymbolIndex::new(symbols))
|
||||
}
|
||||
|
||||
// Feature: Workspace Symbol
|
||||
//
|
||||
// Uses fuzzy-search to find types, modules and functions by name across your
|
||||
// project and dependencies. This is **the** most useful feature, which improves code
|
||||
// navigation tremendously. It mostly works on top of the built-in LSP
|
||||
// functionality, however `#` and `*` symbols can be used to narrow down the
|
||||
// search. Specifically,
|
||||
//
|
||||
// - `Foo` searches for `Foo` type in the current workspace
|
||||
// - `foo#` searches for `foo` function in the current workspace
|
||||
// - `Foo*` searches for `Foo` type among dependencies, including `stdlib`
|
||||
// - `foo#*` searches for `foo` function among dependencies
|
||||
//
|
||||
// That is, `#` switches from "types" to all symbols, `*` switches from the current
|
||||
// workspace to dependencies.
|
||||
//
|
||||
// |===
|
||||
// | Editor | Shortcut
|
||||
//
|
||||
// | VS Code | kbd:[Ctrl+T]
|
||||
// |===
|
||||
pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
|
||||
/// Need to wrap Snapshot to provide `Clone` impl for `map_with`
|
||||
struct Snap(salsa::Snapshot<RootDatabase>);
|
||||
|
|
|
@ -2,58 +2,6 @@ This document is an index of features that the rust-analyzer language server
|
|||
provides. Shortcuts are for the default VS Code layout. If there's no shortcut,
|
||||
you can use <kbd>Ctrl+Shift+P</kbd> to search for the corresponding action.
|
||||
|
||||
### Workspace Symbol <kbd>ctrl+t</kbd>
|
||||
|
||||
Uses fuzzy-search to find types, modules and functions by name across your
|
||||
project and dependencies. This is **the** most useful feature, which improves code
|
||||
navigation tremendously. It mostly works on top of the built-in LSP
|
||||
functionality, however `#` and `*` symbols can be used to narrow down the
|
||||
search. Specifically,
|
||||
|
||||
- `Foo` searches for `Foo` type in the current workspace
|
||||
- `foo#` searches for `foo` function in the current workspace
|
||||
- `Foo*` searches for `Foo` type among dependencies, including `stdlib`
|
||||
- `foo#*` searches for `foo` function among dependencies
|
||||
|
||||
That is, `#` switches from "types" to all symbols, `*` switches from the current
|
||||
workspace to dependencies.
|
||||
|
||||
### Document Symbol <kbd>ctrl+shift+o</kbd>
|
||||
|
||||
Provides a tree of the symbols defined in the file. Can be used to
|
||||
|
||||
* fuzzy search symbol in a file (super useful)
|
||||
* draw breadcrumbs to describe the context around the cursor
|
||||
* draw outline of the file
|
||||
|
||||
### On Typing Assists
|
||||
|
||||
Some features trigger on typing certain characters:
|
||||
|
||||
- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression
|
||||
- Enter inside comments automatically inserts `///`
|
||||
- typing `.` in a chain method call auto-indents
|
||||
|
||||
### Extend Selection
|
||||
|
||||
Extends the current selection to the encompassing syntactic construct
|
||||
(expression, statement, item, module, etc). It works with multiple cursors. This
|
||||
is a relatively new feature of LSP:
|
||||
https://github.com/Microsoft/language-server-protocol/issues/613, check your
|
||||
editor's LSP library to see if this feature is supported.
|
||||
|
||||
### Go to Definition
|
||||
|
||||
Navigates to the definition of an identifier.
|
||||
|
||||
### Go to Implementation
|
||||
|
||||
Navigates to the impl block of structs, enums or traits. Also implemented as a code lens.
|
||||
|
||||
### Go to Type Defintion
|
||||
|
||||
Navigates to the type of an identifier.
|
||||
|
||||
### Commands <kbd>ctrl+shift+p</kbd>
|
||||
|
||||
#### Run
|
||||
|
|
98
docs/user/generated_features.adoc
Normal file
98
docs/user/generated_features.adoc
Normal file
|
@ -0,0 +1,98 @@
|
|||
=== Extend Selection
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/extend_selection.rs[extend_selection.rs]
|
||||
|
||||
|
||||
Extends the current selection to the encompassing syntactic construct
|
||||
(expression, statement, item, module, etc). It works with multiple cursors.
|
||||
|
||||
|===
|
||||
| Editor | Shortcut
|
||||
|
||||
| VS Code | kbd:[Ctrl+Shift+→]
|
||||
|===
|
||||
|
||||
|
||||
=== File Structure
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/display/structure.rs[structure.rs]
|
||||
|
||||
|
||||
Provides a tree of the symbols defined in the file. Can be used to
|
||||
|
||||
* fuzzy search symbol in a file (super useful)
|
||||
* draw breadcrumbs to describe the context around the cursor
|
||||
* draw outline of the file
|
||||
|
||||
|===
|
||||
| Editor | Shortcut
|
||||
|
||||
| VS Code | kbd:[Ctrl+Shift+O]
|
||||
|===
|
||||
|
||||
|
||||
=== Go To Definition
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_definition.rs[goto_definition.rs]
|
||||
|
||||
|
||||
Navigates to the definition of an identifier.
|
||||
|
||||
|===
|
||||
| Editor | Shortcut
|
||||
|
||||
| VS Code | kbd:[F12]
|
||||
|===
|
||||
|
||||
|
||||
=== Go To Implementation
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_implementation.rs[goto_implementation.rs]
|
||||
|
||||
|
||||
Navigates to the impl block of structs, enums or traits. Also implemented as a code lens.
|
||||
|
||||
|===
|
||||
| Editor | Shortcut
|
||||
|
||||
| VS Code | kbd:[Ctrl+F12]
|
||||
|===
|
||||
|
||||
|
||||
=== Go To Type Definition
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_type_definition.rs[goto_type_definition.rs]
|
||||
|
||||
|
||||
Navigates to the type of an identifier.
|
||||
|
||||
|
||||
=== On Typing Assists
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/typing.rs[typing.rs]
|
||||
|
||||
|
||||
Some features trigger on typing certain characters:
|
||||
|
||||
- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression
|
||||
- Enter inside comments automatically inserts `///`
|
||||
- typing `.` in a chain method call auto-indents
|
||||
|
||||
|
||||
=== Workspace Symbol
|
||||
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide_db/src/symbol_index.rs[symbol_index.rs]
|
||||
|
||||
|
||||
Uses fuzzy-search to find types, modules and functions by name across your
|
||||
project and dependencies. This is **the** most useful feature, which improves code
|
||||
navigation tremendously. It mostly works on top of the built-in LSP
|
||||
functionality, however `#` and `*` symbols can be used to narrow down the
|
||||
search. Specifically,
|
||||
|
||||
- `Foo` searches for `Foo` type in the current workspace
|
||||
- `foo#` searches for `foo` function in the current workspace
|
||||
- `Foo*` searches for `Foo` type among dependencies, including `stdlib`
|
||||
- `foo#*` searches for `foo` function among dependencies
|
||||
|
||||
That is, `#` switches from "types" to all symbols, `*` switches from the current
|
||||
workspace to dependencies.
|
||||
|
||||
|===
|
||||
| Editor | Shortcut
|
||||
|
||||
| VS Code | kbd:[Ctrl+T]
|
||||
|===
|
|
@ -8,6 +8,7 @@
|
|||
:important-caption: :heavy_exclamation_mark:
|
||||
:caution-caption: :fire:
|
||||
:warning-caption: :warning:
|
||||
:experimental:
|
||||
|
||||
// Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository
|
||||
|
||||
|
@ -268,6 +269,6 @@ Gnome Builder currently has support for RLS, and there's no way to configure the
|
|||
1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`).
|
||||
2. Enable the Rust Builder plugin.
|
||||
|
||||
== Usage
|
||||
== Features
|
||||
|
||||
See https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/features.md[features.md].
|
||||
include::./generated_features.adoc[]
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
mod gen_syntax;
|
||||
mod gen_parser_tests;
|
||||
mod gen_assists_docs;
|
||||
mod gen_feature_docs;
|
||||
|
||||
use std::{mem, path::Path};
|
||||
|
||||
use crate::{not_bash::fs2, Result};
|
||||
|
||||
pub use self::{
|
||||
gen_assists_docs::generate_assists_docs, gen_parser_tests::generate_parser_tests,
|
||||
gen_syntax::generate_syntax,
|
||||
gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs,
|
||||
gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax,
|
||||
};
|
||||
|
||||
const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar";
|
||||
|
|
72
xtask/src/codegen/gen_feature_docs.rs
Normal file
72
xtask/src/codegen/gen_feature_docs.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
//! Generates `assists.md` documentation.
|
||||
|
||||
use std::{fmt, fs, path::PathBuf};
|
||||
|
||||
use crate::{
|
||||
codegen::{self, extract_comment_blocks_with_empty_lines, Mode},
|
||||
project_root, rust_files, Result,
|
||||
};
|
||||
|
||||
pub fn generate_feature_docs(mode: Mode) -> Result<()> {
|
||||
let features = Feature::collect()?;
|
||||
let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
|
||||
|
||||
let dst = project_root().join("docs/user/generated_features.adoc");
|
||||
codegen::update(&dst, &contents, mode)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Feature {
|
||||
id: String,
|
||||
path: PathBuf,
|
||||
doc: String,
|
||||
}
|
||||
|
||||
impl Feature {
|
||||
fn collect() -> Result<Vec<Feature>> {
|
||||
let mut res = Vec::new();
|
||||
for path in rust_files(&project_root()) {
|
||||
collect_file(&mut res, path)?;
|
||||
}
|
||||
res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id));
|
||||
return Ok(res);
|
||||
|
||||
fn collect_file(acc: &mut Vec<Feature>, path: PathBuf) -> Result<()> {
|
||||
let text = fs::read_to_string(&path)?;
|
||||
let comment_blocks = extract_comment_blocks_with_empty_lines("Feature", &text);
|
||||
|
||||
for block in comment_blocks {
|
||||
let id = block.id;
|
||||
assert!(
|
||||
id.split_ascii_whitespace().all(|it| it.starts_with(char::is_uppercase)),
|
||||
"bad feature: {}",
|
||||
id
|
||||
);
|
||||
let doc = block.contents.join("\n");
|
||||
acc.push(Feature { id, path: path.clone(), doc })
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Feature {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "=== {}", self.id)?;
|
||||
let path = self.path.strip_prefix(&project_root()).unwrap();
|
||||
let name = self.path.file_name().unwrap();
|
||||
|
||||
//FIXME: generate line number as well
|
||||
writeln!(
|
||||
f,
|
||||
"**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/{}[{}]",
|
||||
path.display(),
|
||||
name.to_str().unwrap(),
|
||||
)?;
|
||||
|
||||
writeln!(f, "\n{}", self.doc)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@ FLAGS:
|
|||
codegen::generate_syntax(Mode::Overwrite)?;
|
||||
codegen::generate_parser_tests(Mode::Overwrite)?;
|
||||
codegen::generate_assists_docs(Mode::Overwrite)?;
|
||||
codegen::generate_feature_docs(Mode::Overwrite)?;
|
||||
Ok(())
|
||||
}
|
||||
"format" => {
|
||||
|
|
|
@ -30,6 +30,13 @@ fn generated_assists_are_fresh() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_features_are_fresh() {
|
||||
if let Err(error) = codegen::generate_feature_docs(Mode::Verify) {
|
||||
panic!("{}. Please update features by running `cargo xtask codegen`", error);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_code_formatting() {
|
||||
if let Err(error) = run_rustfmt(Mode::Verify) {
|
||||
|
|
Loading…
Reference in a new issue