add open Cargo.toml action

This commit is contained in:
Anatol Liu 2020-11-12 17:48:07 -08:00
parent 111cc34c8f
commit b1b7727e04
15 changed files with 114 additions and 42 deletions

1
.gitignore vendored
View file

@ -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
View file

@ -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"

View file

@ -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"] }

View file

@ -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

Binary file not shown.

View file

@ -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;
}
} }
_ => (),
} }
} }
} }

View file

@ -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, &params.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()

View file

@ -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,
}

View file

@ -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)

View file

@ -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::*;

View file

@ -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.

View file

@ -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"
} }
] ]
} }

View file

@ -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;

View file

@ -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;
}

View file

@ -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);