mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-24 12:03:31 +00:00
add open Cargo.toml action
This commit is contained in:
parent
111cc34c8f
commit
b1b7727e04
15 changed files with 114 additions and 42 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,3 +10,4 @@ crates/*/target
|
||||||
generated_assists.adoc
|
generated_assists.adoc
|
||||||
generated_features.adoc
|
generated_features.adoc
|
||||||
generated_diagnostic.adoc
|
generated_diagnostic.adoc
|
||||||
|
.DS_Store
|
||||||
|
|
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -612,6 +612,7 @@ dependencies = [
|
||||||
"hir_expand",
|
"hir_expand",
|
||||||
"itertools",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
|
"once_cell",
|
||||||
"profile",
|
"profile",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"scoped-tls",
|
"scoped-tls",
|
||||||
|
@ -1053,9 +1054,9 @@ checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.4.1"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
|
checksum = "f53cef67919d7d247eb9a2f128ca9e522789967ef1eb4ccd8c71a95a8aedf596"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oorandom"
|
name = "oorandom"
|
||||||
|
|
|
@ -35,3 +35,4 @@ expect-test = "1.0"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] }
|
tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] }
|
||||||
tracing-tree = { version = "0.1.4" }
|
tracing-tree = { version = "0.1.4" }
|
||||||
|
once_cell = { version = "1.5.0", features = ["unstable"] }
|
||||||
|
|
|
@ -22,7 +22,8 @@ use hir_def::{
|
||||||
AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
|
AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
|
||||||
};
|
};
|
||||||
use hir_expand::{db::AstDatabase, InFile};
|
use hir_expand::{db::AstDatabase, InFile};
|
||||||
use stdx::{format_to, RacyFlag};
|
use once_cell::race::OnceBool;
|
||||||
|
use stdx::format_to;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo,
|
algo,
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
|
@ -40,8 +41,8 @@ use crate::{
|
||||||
// `env UPDATE_EXPECT=1 cargo test -p hir_ty` to update the snapshots.
|
// `env UPDATE_EXPECT=1 cargo test -p hir_ty` to update the snapshots.
|
||||||
|
|
||||||
fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> {
|
fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> {
|
||||||
static ENABLE: RacyFlag = RacyFlag::new();
|
static ENABLE: OnceBool = OnceBool::new();
|
||||||
if !ENABLE.get(|| env::var("CHALK_DEBUG").is_ok()) {
|
if !ENABLE.get_or_init(|| env::var("CHALK_DEBUG").is_ok()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
crates/ide/.DS_Store
vendored
Normal file
BIN
crates/ide/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -385,13 +385,10 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(code_action) = &doc_caps.code_action {
|
if let Some(code_action) = &doc_caps.code_action {
|
||||||
match (code_action.data_support, &code_action.resolve_support) {
|
if let Some(resolve_support) = &code_action.resolve_support {
|
||||||
(Some(true), Some(resolve_support)) => {
|
if resolve_support.properties.iter().any(|it| it == "edit") {
|
||||||
if resolve_support.properties.iter().any(|it| it == "edit") {
|
self.client_caps.code_action_resolve = true;
|
||||||
self.client_caps.code_action_resolve = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1322,6 +1322,28 @@ pub(crate) fn handle_open_docs(
|
||||||
Ok(remote.and_then(|remote| Url::parse(&remote).ok()))
|
Ok(remote.and_then(|remote| Url::parse(&remote).ok()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn handle_open_cargo_toml(
|
||||||
|
snap: GlobalStateSnapshot,
|
||||||
|
params: lsp_ext::OpenCargoTomlParams,
|
||||||
|
) -> Result<Option<lsp_types::GotoDefinitionResponse>> {
|
||||||
|
let _p = profile::span("handle_open_cargo_toml");
|
||||||
|
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
||||||
|
let maybe_cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?;
|
||||||
|
if maybe_cargo_spec.is_none() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cargo_spec = maybe_cargo_spec.unwrap();
|
||||||
|
let cargo_toml_path = cargo_spec.workspace_root.join("Cargo.toml");
|
||||||
|
if !cargo_toml_path.exists() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let cargo_toml_url = to_proto::url_from_abs_path(&cargo_toml_path);
|
||||||
|
let cargo_toml_location = Location::new(cargo_toml_url, Range::default());
|
||||||
|
let res = lsp_types::GotoDefinitionResponse::from(cargo_toml_location);
|
||||||
|
Ok(Some(res))
|
||||||
|
}
|
||||||
|
|
||||||
fn implementation_title(count: usize) -> String {
|
fn implementation_title(count: usize) -> String {
|
||||||
if count == 1 {
|
if count == 1 {
|
||||||
"1 implementation".into()
|
"1 implementation".into()
|
||||||
|
|
|
@ -354,3 +354,17 @@ impl Request for ExternalDocs {
|
||||||
type Result = Option<lsp_types::Url>;
|
type Result = Option<lsp_types::Url>;
|
||||||
const METHOD: &'static str = "experimental/externalDocs";
|
const METHOD: &'static str = "experimental/externalDocs";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum OpenCargoToml {}
|
||||||
|
|
||||||
|
impl Request for OpenCargoToml {
|
||||||
|
type Params = OpenCargoTomlParams;
|
||||||
|
type Result = Option<lsp_types::GotoDefinitionResponse>;
|
||||||
|
const METHOD: &'static str = "experimental/openCargoToml";
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct OpenCargoTomlParams {
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
}
|
||||||
|
|
|
@ -438,6 +438,7 @@ impl GlobalState {
|
||||||
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
|
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
|
||||||
.on::<lsp_ext::HoverRequest>(handlers::handle_hover)
|
.on::<lsp_ext::HoverRequest>(handlers::handle_hover)
|
||||||
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
|
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
|
||||||
|
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
|
||||||
.on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
|
.on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
|
||||||
.on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
|
.on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
|
||||||
.on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol)
|
.on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol)
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
//! Missing batteries for standard libraries.
|
//! Missing batteries for standard libraries.
|
||||||
use std::{
|
use std::time::Instant;
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
|
||||||
time::Instant,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod macros;
|
mod macros;
|
||||||
pub mod panic_context;
|
pub mod panic_context;
|
||||||
|
@ -150,31 +147,6 @@ where
|
||||||
left
|
left
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RacyFlag(AtomicUsize);
|
|
||||||
|
|
||||||
impl RacyFlag {
|
|
||||||
pub const fn new() -> RacyFlag {
|
|
||||||
RacyFlag(AtomicUsize::new(!0))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, init: impl FnMut() -> bool) -> bool {
|
|
||||||
let mut init = Some(init);
|
|
||||||
self.get_impl(&mut || init.take().map_or(false, |mut f| f()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_impl(&self, init: &mut dyn FnMut() -> bool) -> bool {
|
|
||||||
match self.0.load(Ordering::Relaxed) {
|
|
||||||
0 => false,
|
|
||||||
1 => true,
|
|
||||||
_ => {
|
|
||||||
let res = init();
|
|
||||||
self.0.store(if res { 1 } else { 0 }, Ordering::Relaxed);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<!---
|
<!---
|
||||||
lsp_ext.rs hash: 4f86fb54e4b2870e
|
lsp_ext.rs hash: 9d5daed5b25dc4f6
|
||||||
|
|
||||||
If you need to change the above hash to make the test pass, please check if you
|
If you need to change the above hash to make the test pass, please check if you
|
||||||
need to adjust this doc as well and ping this issue:
|
need to adjust this doc as well and ping this issue:
|
||||||
|
|
||||||
https://github.com/rust-analyzer/rust-analyzer/issues/4604
|
https://github.com/rust-analyzer/rust-analyzer/issues/4604
|
||||||
|
|
||||||
|
@ -537,3 +537,28 @@ Such actions on the client side are appended to a hover bottom as command links:
|
||||||
+-----------------------------+
|
+-----------------------------+
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Open Cargo.toml
|
||||||
|
|
||||||
|
**Issue:** https://github.com/rust-analyzer/rust-analyzer/issues/6462
|
||||||
|
|
||||||
|
This request is sent from client to server to open the current project's Cargo.toml
|
||||||
|
|
||||||
|
**Method:** `experimental/openCargoToml`
|
||||||
|
|
||||||
|
**Request:** `OpenCargoTomlParams`
|
||||||
|
|
||||||
|
**Response:** `Location | null`
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Cargo.toml
|
||||||
|
[package]
|
||||||
|
// src/main.rs
|
||||||
|
|
||||||
|
/* cursor here*/
|
||||||
|
```
|
||||||
|
|
||||||
|
`experimental/openCargoToml` returns a single `Link` to the start of the `[package]` keyword.
|
||||||
|
|
|
@ -187,6 +187,11 @@
|
||||||
"command": "rust-analyzer.openDocs",
|
"command": "rust-analyzer.openDocs",
|
||||||
"title": "Open docs under cursor",
|
"title": "Open docs under cursor",
|
||||||
"category": "Rust Analyzer"
|
"category": "Rust Analyzer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "rust-analyzer.openCargoToml",
|
||||||
|
"title": "Open Cargo.toml",
|
||||||
|
"category": "Rust Analyzer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"keybindings": [
|
"keybindings": [
|
||||||
|
@ -1057,6 +1062,10 @@
|
||||||
{
|
{
|
||||||
"command": "rust-analyzer.openDocs",
|
"command": "rust-analyzer.openDocs",
|
||||||
"when": "inRustProject"
|
"when": "inRustProject"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "rust-analyzer.openCargoToml",
|
||||||
|
"when": "inRustProject"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,6 +188,27 @@ export function parentModule(ctx: Ctx): Cmd {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function openCargoToml(ctx: Ctx): Cmd {
|
||||||
|
return async () => {
|
||||||
|
const editor = ctx.activeRustEditor;
|
||||||
|
const client = ctx.client;
|
||||||
|
if (!editor || !client) return;
|
||||||
|
|
||||||
|
const response = await client.sendRequest(ra.openCargoToml, {
|
||||||
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
|
});
|
||||||
|
if (!response) return;
|
||||||
|
|
||||||
|
const uri = client.protocol2CodeConverter.asUri(response.uri);
|
||||||
|
const range = client.protocol2CodeConverter.asRange(response.range);
|
||||||
|
|
||||||
|
const doc = await vscode.workspace.openTextDocument(uri);
|
||||||
|
const e = await vscode.window.showTextDocument(doc);
|
||||||
|
e.selection = new vscode.Selection(range.start, range.start);
|
||||||
|
e.revealRange(range, vscode.TextEditorRevealType.InCenter);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function ssr(ctx: Ctx): Cmd {
|
export function ssr(ctx: Ctx): Cmd {
|
||||||
return async () => {
|
return async () => {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
|
|
|
@ -114,3 +114,9 @@ export interface CommandLinkGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs');
|
export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs');
|
||||||
|
|
||||||
|
export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>("experimental/openCargoToml");
|
||||||
|
|
||||||
|
export interface OpenCargoTomlParams {
|
||||||
|
textDocument: lc.TextDocumentIdentifier;
|
||||||
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
|
||||||
ctx.registerCommand('debug', commands.debug);
|
ctx.registerCommand('debug', commands.debug);
|
||||||
ctx.registerCommand('newDebugConfig', commands.newDebugConfig);
|
ctx.registerCommand('newDebugConfig', commands.newDebugConfig);
|
||||||
ctx.registerCommand('openDocs', commands.openDocs);
|
ctx.registerCommand('openDocs', commands.openDocs);
|
||||||
|
ctx.registerCommand('openCargoToml', commands.openCargoToml);
|
||||||
|
|
||||||
defaultOnEnter.dispose();
|
defaultOnEnter.dispose();
|
||||||
ctx.registerCommand('onEnter', commands.onEnter);
|
ctx.registerCommand('onEnter', commands.onEnter);
|
||||||
|
|
Loading…
Reference in a new issue