diff options
author | Anatol Liu <[email protected]> | 2020-11-13 01:48:07 +0000 |
---|---|---|
committer | Anatol Liu <[email protected]> | 2020-11-13 01:48:07 +0000 |
commit | b1b7727e046b4b25dcca034ee767a7fc3238409d (patch) | |
tree | c1942b7af1e73b139d2c62d1d81e8d6749dc8cd2 | |
parent | 111cc34c8f181315f4dcfa85c616d54d47eff0b9 (diff) |
add open Cargo.toml action
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 5 | ||||
-rw-r--r-- | crates/hir_ty/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/hir_ty/src/tests.rs | 7 | ||||
-rw-r--r-- | crates/ide/.DS_Store | bin | 0 -> 6148 bytes | |||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 9 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 22 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_ext.rs | 14 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 1 | ||||
-rw-r--r-- | crates/stdx/src/lib.rs | 30 | ||||
-rw-r--r-- | docs/dev/lsp-extensions.md | 29 | ||||
-rw-r--r-- | editors/code/package.json | 9 | ||||
-rw-r--r-- | editors/code/src/commands.ts | 21 | ||||
-rw-r--r-- | editors/code/src/lsp_ext.ts | 6 | ||||
-rw-r--r-- | editors/code/src/main.ts | 1 |
15 files changed, 114 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore index b205bf3fb..7e097c015 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -10,3 +10,4 @@ crates/*/target | |||
10 | generated_assists.adoc | 10 | generated_assists.adoc |
11 | generated_features.adoc | 11 | generated_features.adoc |
12 | generated_diagnostic.adoc | 12 | generated_diagnostic.adoc |
13 | .DS_Store | ||
diff --git a/Cargo.lock b/Cargo.lock index 1a4a63550..c5645b2d2 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -612,6 +612,7 @@ dependencies = [ | |||
612 | "hir_expand", | 612 | "hir_expand", |
613 | "itertools", | 613 | "itertools", |
614 | "log", | 614 | "log", |
615 | "once_cell", | ||
615 | "profile", | 616 | "profile", |
616 | "rustc-hash", | 617 | "rustc-hash", |
617 | "scoped-tls", | 618 | "scoped-tls", |
@@ -1053,9 +1054,9 @@ checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" | |||
1053 | 1054 | ||
1054 | [[package]] | 1055 | [[package]] |
1055 | name = "once_cell" | 1056 | name = "once_cell" |
1056 | version = "1.4.1" | 1057 | version = "1.5.1" |
1057 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1058 | checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" | 1059 | checksum = "f53cef67919d7d247eb9a2f128ca9e522789967ef1eb4ccd8c71a95a8aedf596" |
1059 | 1060 | ||
1060 | [[package]] | 1061 | [[package]] |
1061 | name = "oorandom" | 1062 | name = "oorandom" |
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index fdc65a5c3..cf5c38a23 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -35,3 +35,4 @@ expect-test = "1.0" | |||
35 | tracing = "0.1" | 35 | tracing = "0.1" |
36 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } | 36 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } |
37 | tracing-tree = { version = "0.1.4" } | 37 | tracing-tree = { version = "0.1.4" } |
38 | once_cell = { version = "1.5.0", features = ["unstable"] } | ||
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 104ef334c..0a400cb70 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs | |||
@@ -22,7 +22,8 @@ use hir_def::{ | |||
22 | AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, | 22 | AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, |
23 | }; | 23 | }; |
24 | use hir_expand::{db::AstDatabase, InFile}; | 24 | use hir_expand::{db::AstDatabase, InFile}; |
25 | use stdx::{format_to, RacyFlag}; | 25 | use once_cell::race::OnceBool; |
26 | use stdx::format_to; | ||
26 | use syntax::{ | 27 | use syntax::{ |
27 | algo, | 28 | algo, |
28 | ast::{self, AstNode}, | 29 | ast::{self, AstNode}, |
@@ -40,8 +41,8 @@ use crate::{ | |||
40 | // `env UPDATE_EXPECT=1 cargo test -p hir_ty` to update the snapshots. | 41 | // `env UPDATE_EXPECT=1 cargo test -p hir_ty` to update the snapshots. |
41 | 42 | ||
42 | fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> { | 43 | fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> { |
43 | static ENABLE: RacyFlag = RacyFlag::new(); | 44 | static ENABLE: OnceBool = OnceBool::new(); |
44 | if !ENABLE.get(|| env::var("CHALK_DEBUG").is_ok()) { | 45 | if !ENABLE.get_or_init(|| env::var("CHALK_DEBUG").is_ok()) { |
45 | return None; | 46 | return None; |
46 | } | 47 | } |
47 | 48 | ||
diff --git a/crates/ide/.DS_Store b/crates/ide/.DS_Store new file mode 100644 index 000000000..a566736aa --- /dev/null +++ b/crates/ide/.DS_Store | |||
Binary files differ | |||
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index b4c738272..9cc14fe82 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -385,13 +385,10 @@ impl Config { | |||
385 | } | 385 | } |
386 | 386 | ||
387 | if let Some(code_action) = &doc_caps.code_action { | 387 | if let Some(code_action) = &doc_caps.code_action { |
388 | match (code_action.data_support, &code_action.resolve_support) { | 388 | if let Some(resolve_support) = &code_action.resolve_support { |
389 | (Some(true), Some(resolve_support)) => { | 389 | if resolve_support.properties.iter().any(|it| it == "edit") { |
390 | if resolve_support.properties.iter().any(|it| it == "edit") { | 390 | self.client_caps.code_action_resolve = true; |
391 | self.client_caps.code_action_resolve = true; | ||
392 | } | ||
393 | } | 391 | } |
394 | _ => (), | ||
395 | } | 392 | } |
396 | } | 393 | } |
397 | } | 394 | } |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 95659b0db..782797e85 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -1322,6 +1322,28 @@ pub(crate) fn handle_open_docs( | |||
1322 | Ok(remote.and_then(|remote| Url::parse(&remote).ok())) | 1322 | Ok(remote.and_then(|remote| Url::parse(&remote).ok())) |
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | pub(crate) fn handle_open_cargo_toml( | ||
1326 | snap: GlobalStateSnapshot, | ||
1327 | params: lsp_ext::OpenCargoTomlParams, | ||
1328 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { | ||
1329 | let _p = profile::span("handle_open_cargo_toml"); | ||
1330 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | ||
1331 | let maybe_cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; | ||
1332 | if maybe_cargo_spec.is_none() { | ||
1333 | return Ok(None); | ||
1334 | } | ||
1335 | |||
1336 | let cargo_spec = maybe_cargo_spec.unwrap(); | ||
1337 | let cargo_toml_path = cargo_spec.workspace_root.join("Cargo.toml"); | ||
1338 | if !cargo_toml_path.exists() { | ||
1339 | return Ok(None); | ||
1340 | } | ||
1341 | let cargo_toml_url = to_proto::url_from_abs_path(&cargo_toml_path); | ||
1342 | let cargo_toml_location = Location::new(cargo_toml_url, Range::default()); | ||
1343 | let res = lsp_types::GotoDefinitionResponse::from(cargo_toml_location); | ||
1344 | Ok(Some(res)) | ||
1345 | } | ||
1346 | |||
1325 | fn implementation_title(count: usize) -> String { | 1347 | fn implementation_title(count: usize) -> String { |
1326 | if count == 1 { | 1348 | if count == 1 { |
1327 | "1 implementation".into() | 1349 | "1 implementation".into() |
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index a7c3028e4..a5c65fa3e 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs | |||
@@ -354,3 +354,17 @@ impl Request for ExternalDocs { | |||
354 | type Result = Option<lsp_types::Url>; | 354 | type Result = Option<lsp_types::Url>; |
355 | const METHOD: &'static str = "experimental/externalDocs"; | 355 | const METHOD: &'static str = "experimental/externalDocs"; |
356 | } | 356 | } |
357 | |||
358 | pub enum OpenCargoToml {} | ||
359 | |||
360 | impl Request for OpenCargoToml { | ||
361 | type Params = OpenCargoTomlParams; | ||
362 | type Result = Option<lsp_types::GotoDefinitionResponse>; | ||
363 | const METHOD: &'static str = "experimental/openCargoToml"; | ||
364 | } | ||
365 | |||
366 | #[derive(Serialize, Deserialize, Debug)] | ||
367 | #[serde(rename_all = "camelCase")] | ||
368 | pub struct OpenCargoTomlParams { | ||
369 | pub text_document: TextDocumentIdentifier, | ||
370 | } | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 6e6cac42e..68a53bbcb 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -438,6 +438,7 @@ impl GlobalState { | |||
438 | .on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve) | 438 | .on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve) |
439 | .on::<lsp_ext::HoverRequest>(handlers::handle_hover) | 439 | .on::<lsp_ext::HoverRequest>(handlers::handle_hover) |
440 | .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs) | 440 | .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs) |
441 | .on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml) | ||
441 | .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting) | 442 | .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting) |
442 | .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol) | 443 | .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol) |
443 | .on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol) | 444 | .on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol) |
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 59d89f47d..374ed5910 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs | |||
@@ -1,8 +1,5 @@ | |||
1 | //! Missing batteries for standard libraries. | 1 | //! Missing batteries for standard libraries. |
2 | use std::{ | 2 | use std::time::Instant; |
3 | sync::atomic::{AtomicUsize, Ordering}, | ||
4 | time::Instant, | ||
5 | }; | ||
6 | 3 | ||
7 | mod macros; | 4 | mod macros; |
8 | pub mod panic_context; | 5 | pub mod panic_context; |
@@ -150,31 +147,6 @@ where | |||
150 | left | 147 | left |
151 | } | 148 | } |
152 | 149 | ||
153 | pub struct RacyFlag(AtomicUsize); | ||
154 | |||
155 | impl RacyFlag { | ||
156 | pub const fn new() -> RacyFlag { | ||
157 | RacyFlag(AtomicUsize::new(!0)) | ||
158 | } | ||
159 | |||
160 | pub fn get(&self, init: impl FnMut() -> bool) -> bool { | ||
161 | let mut init = Some(init); | ||
162 | self.get_impl(&mut || init.take().map_or(false, |mut f| f())) | ||
163 | } | ||
164 | |||
165 | fn get_impl(&self, init: &mut dyn FnMut() -> bool) -> bool { | ||
166 | match self.0.load(Ordering::Relaxed) { | ||
167 | 0 => false, | ||
168 | 1 => true, | ||
169 | _ => { | ||
170 | let res = init(); | ||
171 | self.0.store(if res { 1 } else { 0 }, Ordering::Relaxed); | ||
172 | res | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | #[cfg(test)] | 150 | #[cfg(test)] |
179 | mod tests { | 151 | mod tests { |
180 | use super::*; | 152 | use super::*; |
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 77d4e0ec9..db9727bee 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
@@ -1,8 +1,8 @@ | |||
1 | <!--- | 1 | <!--- |
2 | lsp_ext.rs hash: 4f86fb54e4b2870e | 2 | lsp_ext.rs hash: 9d5daed5b25dc4f6 |
3 | 3 | ||
4 | If you need to change the above hash to make the test pass, please check if you | 4 | If you need to change the above hash to make the test pass, please check if you |
5 | need to adjust this doc as well and ping this issue: | 5 | need to adjust this doc as well and ping this issue: |
6 | 6 | ||
7 | https://github.com/rust-analyzer/rust-analyzer/issues/4604 | 7 | https://github.com/rust-analyzer/rust-analyzer/issues/4604 |
8 | 8 | ||
@@ -537,3 +537,28 @@ Such actions on the client side are appended to a hover bottom as command links: | |||
537 | +-----------------------------+ | 537 | +-----------------------------+ |
538 | ... | 538 | ... |
539 | ``` | 539 | ``` |
540 | |||
541 | ## Open Cargo.toml | ||
542 | |||
543 | **Issue:** https://github.com/rust-analyzer/rust-analyzer/issues/6462 | ||
544 | |||
545 | This request is sent from client to server to open the current project's Cargo.toml | ||
546 | |||
547 | **Method:** `experimental/openCargoToml` | ||
548 | |||
549 | **Request:** `OpenCargoTomlParams` | ||
550 | |||
551 | **Response:** `Location | null` | ||
552 | |||
553 | |||
554 | ### Example | ||
555 | |||
556 | ```rust | ||
557 | // Cargo.toml | ||
558 | [package] | ||
559 | // src/main.rs | ||
560 | |||
561 | /* cursor here*/ | ||
562 | ``` | ||
563 | |||
564 | `experimental/openCargoToml` returns a single `Link` to the start of the `[package]` keyword. | ||
diff --git a/editors/code/package.json b/editors/code/package.json index eccafccdd..b02c80773 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -187,6 +187,11 @@ | |||
187 | "command": "rust-analyzer.openDocs", | 187 | "command": "rust-analyzer.openDocs", |
188 | "title": "Open docs under cursor", | 188 | "title": "Open docs under cursor", |
189 | "category": "Rust Analyzer" | 189 | "category": "Rust Analyzer" |
190 | }, | ||
191 | { | ||
192 | "command": "rust-analyzer.openCargoToml", | ||
193 | "title": "Open Cargo.toml", | ||
194 | "category": "Rust Analyzer" | ||
190 | } | 195 | } |
191 | ], | 196 | ], |
192 | "keybindings": [ | 197 | "keybindings": [ |
@@ -1057,6 +1062,10 @@ | |||
1057 | { | 1062 | { |
1058 | "command": "rust-analyzer.openDocs", | 1063 | "command": "rust-analyzer.openDocs", |
1059 | "when": "inRustProject" | 1064 | "when": "inRustProject" |
1065 | }, | ||
1066 | { | ||
1067 | "command": "rust-analyzer.openCargoToml", | ||
1068 | "when": "inRustProject" | ||
1060 | } | 1069 | } |
1061 | ] | 1070 | ] |
1062 | } | 1071 | } |
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index cf34622c3..92bc4d7f7 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts | |||
@@ -188,6 +188,27 @@ export function parentModule(ctx: Ctx): Cmd { | |||
188 | }; | 188 | }; |
189 | } | 189 | } |
190 | 190 | ||
191 | export function openCargoToml(ctx: Ctx): Cmd { | ||
192 | return async () => { | ||
193 | const editor = ctx.activeRustEditor; | ||
194 | const client = ctx.client; | ||
195 | if (!editor || !client) return; | ||
196 | |||
197 | const response = await client.sendRequest(ra.openCargoToml, { | ||
198 | textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), | ||
199 | }); | ||
200 | if (!response) return; | ||
201 | |||
202 | const uri = client.protocol2CodeConverter.asUri(response.uri); | ||
203 | const range = client.protocol2CodeConverter.asRange(response.range); | ||
204 | |||
205 | const doc = await vscode.workspace.openTextDocument(uri); | ||
206 | const e = await vscode.window.showTextDocument(doc); | ||
207 | e.selection = new vscode.Selection(range.start, range.start); | ||
208 | e.revealRange(range, vscode.TextEditorRevealType.InCenter); | ||
209 | }; | ||
210 | } | ||
211 | |||
191 | export function ssr(ctx: Ctx): Cmd { | 212 | export function ssr(ctx: Ctx): Cmd { |
192 | return async () => { | 213 | return async () => { |
193 | const editor = vscode.window.activeTextEditor; | 214 | const editor = vscode.window.activeTextEditor; |
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index d320c3cd7..5e877ce65 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts | |||
@@ -114,3 +114,9 @@ export interface CommandLinkGroup { | |||
114 | } | 114 | } |
115 | 115 | ||
116 | export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs'); | 116 | export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs'); |
117 | |||
118 | export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>("experimental/openCargoToml"); | ||
119 | |||
120 | export interface OpenCargoTomlParams { | ||
121 | textDocument: lc.TextDocumentIdentifier; | ||
122 | } | ||
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 09543e348..2f3dde8ac 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts | |||
@@ -111,6 +111,7 @@ async function tryActivate(context: vscode.ExtensionContext) { | |||
111 | ctx.registerCommand('debug', commands.debug); | 111 | ctx.registerCommand('debug', commands.debug); |
112 | ctx.registerCommand('newDebugConfig', commands.newDebugConfig); | 112 | ctx.registerCommand('newDebugConfig', commands.newDebugConfig); |
113 | ctx.registerCommand('openDocs', commands.openDocs); | 113 | ctx.registerCommand('openDocs', commands.openDocs); |
114 | ctx.registerCommand('openCargoToml', commands.openCargoToml); | ||
114 | 115 | ||
115 | defaultOnEnter.dispose(); | 116 | defaultOnEnter.dispose(); |
116 | ctx.registerCommand('onEnter', commands.onEnter); | 117 | ctx.registerCommand('onEnter', commands.onEnter); |