diff options
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/config.rs (renamed from crates/ra_lsp_server/src/init.rs) | 15 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 20 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 21 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 144 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/markdown.rs | 17 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/req.rs | 28 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/vfs_filter.rs | 54 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 24 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/support.rs | 4 |
12 files changed, 130 insertions, 208 deletions
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index cec360667..c282d6db8 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -25,6 +25,7 @@ ra_ide_api = { path = "../ra_ide_api" } | |||
25 | gen_lsp_server = { path = "../gen_lsp_server" } | 25 | gen_lsp_server = { path = "../gen_lsp_server" } |
26 | ra_project_model = { path = "../ra_project_model" } | 26 | ra_project_model = { path = "../ra_project_model" } |
27 | ra_prof = { path = "../ra_prof" } | 27 | ra_prof = { path = "../ra_prof" } |
28 | ra_vfs_glob = { path = "../ra_vfs_glob" } | ||
28 | 29 | ||
29 | [dev-dependencies] | 30 | [dev-dependencies] |
30 | tempfile = "3" | 31 | tempfile = "3" |
diff --git a/crates/ra_lsp_server/src/init.rs b/crates/ra_lsp_server/src/config.rs index b894b449d..6dcdc695a 100644 --- a/crates/ra_lsp_server/src/init.rs +++ b/crates/ra_lsp_server/src/config.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use serde::{Deserialize, Deserializer}; | 1 | use serde::{Deserialize, Deserializer}; |
2 | 2 | ||
3 | /// Client provided initialization options | 3 | /// Client provided initialization options |
4 | #[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)] | 4 | #[derive(Deserialize, Clone, Debug, PartialEq, Eq)] |
5 | #[serde(rename_all = "camelCase", default)] | 5 | #[serde(rename_all = "camelCase", default)] |
6 | pub struct InitializationOptions { | 6 | pub struct ServerConfig { |
7 | /// Whether the client supports our custom highlighting publishing decorations. | 7 | /// Whether the client supports our custom highlighting publishing decorations. |
8 | /// This is different to the highlightingOn setting, which is whether the user | 8 | /// This is different to the highlightingOn setting, which is whether the user |
9 | /// wants our custom highlighting to be used. | 9 | /// wants our custom highlighting to be used. |
@@ -18,14 +18,17 @@ pub struct InitializationOptions { | |||
18 | #[serde(deserialize_with = "nullable_bool_true")] | 18 | #[serde(deserialize_with = "nullable_bool_true")] |
19 | pub show_workspace_loaded: bool, | 19 | pub show_workspace_loaded: bool, |
20 | 20 | ||
21 | pub exclude_globs: Vec<String>, | ||
22 | |||
21 | pub lru_capacity: Option<usize>, | 23 | pub lru_capacity: Option<usize>, |
22 | } | 24 | } |
23 | 25 | ||
24 | impl Default for InitializationOptions { | 26 | impl Default for ServerConfig { |
25 | fn default() -> InitializationOptions { | 27 | fn default() -> ServerConfig { |
26 | InitializationOptions { | 28 | ServerConfig { |
27 | publish_decorations: false, | 29 | publish_decorations: false, |
28 | show_workspace_loaded: true, | 30 | show_workspace_loaded: true, |
31 | exclude_globs: Vec::new(), | ||
29 | lru_capacity: None, | 32 | lru_capacity: None, |
30 | } | 33 | } |
31 | } | 34 | } |
@@ -56,7 +59,7 @@ mod test { | |||
56 | #[test] | 59 | #[test] |
57 | fn deserialize_init_options_defaults() { | 60 | fn deserialize_init_options_defaults() { |
58 | // check that null == default for both fields | 61 | // check that null == default for both fields |
59 | let default = InitializationOptions::default(); | 62 | let default = ServerConfig::default(); |
60 | assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); | 63 | assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); |
61 | assert_eq!( | 64 | assert_eq!( |
62 | default, | 65 | default, |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 59c5e1582..df8ea6e0d 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -1,13 +1,13 @@ | |||
1 | use lsp_types::{ | 1 | use lsp_types::{ |
2 | self, CreateFile, DocumentChangeOperation, DocumentChanges, Documentation, Location, | 2 | self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation, |
3 | LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp, SymbolKind, | 3 | Location, LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp, |
4 | TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, Url, | 4 | SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, |
5 | VersionedTextDocumentIdentifier, WorkspaceEdit, | 5 | TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, |
6 | }; | 6 | }; |
7 | use ra_ide_api::{ | 7 | use ra_ide_api::{ |
8 | translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, | 8 | translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, |
9 | FileRange, FileSystemEdit, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo, | 9 | FileRange, FileSystemEdit, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo, |
10 | SourceChange, SourceFileEdit, | 10 | Severity, SourceChange, SourceFileEdit, |
11 | }; | 11 | }; |
12 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | 12 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; |
13 | use ra_text_edit::{AtomTextEdit, TextEdit}; | 13 | use ra_text_edit::{AtomTextEdit, TextEdit}; |
@@ -79,6 +79,16 @@ impl Conv for CompletionItemKind { | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | impl Conv for Severity { | ||
83 | type Output = DiagnosticSeverity; | ||
84 | fn conv(self) -> DiagnosticSeverity { | ||
85 | match self { | ||
86 | Severity::Error => DiagnosticSeverity::Error, | ||
87 | Severity::WeakWarning => DiagnosticSeverity::Hint, | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
82 | impl ConvWith for CompletionItem { | 92 | impl ConvWith for CompletionItem { |
83 | type Ctx = LineIndex; | 93 | type Ctx = LineIndex; |
84 | type Output = ::lsp_types::CompletionItem; | 94 | type Output = ::lsp_types::CompletionItem; |
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 56a263aa5..795f86383 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs | |||
@@ -4,13 +4,11 @@ mod conv; | |||
4 | mod main_loop; | 4 | mod main_loop; |
5 | mod markdown; | 5 | mod markdown; |
6 | mod project_model; | 6 | mod project_model; |
7 | mod vfs_filter; | ||
8 | pub mod req; | 7 | pub mod req; |
9 | pub mod init; | 8 | pub mod config; |
10 | mod world; | 9 | mod world; |
11 | 10 | ||
12 | pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; | 11 | pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; |
13 | pub use crate::{ | 12 | pub use crate::{ |
14 | caps::server_capabilities, init::InitializationOptions, main_loop::main_loop, | 13 | caps::server_capabilities, config::ServerConfig, main_loop::main_loop, main_loop::LspError, |
15 | main_loop::LspError, | ||
16 | }; | 14 | }; |
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index c1f8243be..1a2ab1bc2 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -2,7 +2,7 @@ use flexi_logger::{Duplicate, Logger}; | |||
2 | use gen_lsp_server::{run_server, stdio_transport}; | 2 | use gen_lsp_server::{run_server, stdio_transport}; |
3 | use serde::Deserialize; | 3 | use serde::Deserialize; |
4 | 4 | ||
5 | use ra_lsp_server::{InitializationOptions, Result}; | 5 | use ra_lsp_server::{Result, ServerConfig}; |
6 | use ra_prof; | 6 | use ra_prof; |
7 | 7 | ||
8 | fn main() -> Result<()> { | 8 | fn main() -> Result<()> { |
@@ -48,7 +48,7 @@ fn main_inner() -> Result<()> { | |||
48 | 48 | ||
49 | let opts = params | 49 | let opts = params |
50 | .initialization_options | 50 | .initialization_options |
51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | 51 | .and_then(|v| ServerConfig::deserialize(v).ok()) |
52 | .unwrap_or_default(); | 52 | .unwrap_or_default(); |
53 | 53 | ||
54 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) | 54 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 8e830c8b8..b9c99a223 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -23,7 +23,7 @@ use crate::{ | |||
23 | project_model::workspace_loader, | 23 | project_model::workspace_loader, |
24 | req, | 24 | req, |
25 | world::{Options, WorldSnapshot, WorldState}, | 25 | world::{Options, WorldSnapshot, WorldState}, |
26 | InitializationOptions, Result, | 26 | Result, ServerConfig, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | const THREADPOOL_SIZE: usize = 8; | 29 | const THREADPOOL_SIZE: usize = 8; |
@@ -52,10 +52,11 @@ impl Error for LspError {} | |||
52 | pub fn main_loop( | 52 | pub fn main_loop( |
53 | ws_roots: Vec<PathBuf>, | 53 | ws_roots: Vec<PathBuf>, |
54 | client_caps: ClientCapabilities, | 54 | client_caps: ClientCapabilities, |
55 | options: InitializationOptions, | 55 | config: ServerConfig, |
56 | msg_receiver: &Receiver<RawMessage>, | 56 | msg_receiver: &Receiver<RawMessage>, |
57 | msg_sender: &Sender<RawMessage>, | 57 | msg_sender: &Sender<RawMessage>, |
58 | ) -> Result<()> { | 58 | ) -> Result<()> { |
59 | log::debug!("server_config: {:?}", config); | ||
59 | // FIXME: support dynamic workspace loading. | 60 | // FIXME: support dynamic workspace loading. |
60 | let workspaces = { | 61 | let workspaces = { |
61 | let ws_worker = workspace_loader(); | 62 | let ws_worker = workspace_loader(); |
@@ -77,14 +78,19 @@ pub fn main_loop( | |||
77 | } | 78 | } |
78 | loaded_workspaces | 79 | loaded_workspaces |
79 | }; | 80 | }; |
80 | 81 | let globs = config | |
82 | .exclude_globs | ||
83 | .iter() | ||
84 | .map(|glob| ra_vfs_glob::Glob::new(glob)) | ||
85 | .collect::<std::result::Result<Vec<_>, _>>()?; | ||
81 | let mut state = WorldState::new( | 86 | let mut state = WorldState::new( |
82 | ws_roots, | 87 | ws_roots, |
83 | workspaces, | 88 | workspaces, |
84 | options.lru_capacity, | 89 | config.lru_capacity, |
90 | &globs, | ||
85 | Options { | 91 | Options { |
86 | publish_decorations: options.publish_decorations, | 92 | publish_decorations: config.publish_decorations, |
87 | show_workspace_loaded: options.show_workspace_loaded, | 93 | show_workspace_loaded: config.show_workspace_loaded, |
88 | supports_location_link: client_caps | 94 | supports_location_link: client_caps |
89 | .text_document | 95 | .text_document |
90 | .and_then(|it| it.definition) | 96 | .and_then(|it| it.definition) |
@@ -269,7 +275,7 @@ fn main_loop_inner( | |||
269 | && pending_libraries.is_empty() | 275 | && pending_libraries.is_empty() |
270 | && in_flight_libraries == 0 | 276 | && in_flight_libraries == 0 |
271 | { | 277 | { |
272 | let n_packages: usize = state.workspaces.iter().map(|it| it.count()).sum(); | 278 | let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum(); |
273 | if state.options.show_workspace_loaded { | 279 | if state.options.show_workspace_loaded { |
274 | let msg = format!("workspace loaded, {} rust packages", n_packages); | 280 | let msg = format!("workspace loaded, {} rust packages", n_packages); |
275 | show_message(req::MessageType::Info, msg, msg_sender); | 281 | show_message(req::MessageType::Info, msg, msg_sender); |
@@ -340,7 +346,6 @@ fn on_request( | |||
340 | })? | 346 | })? |
341 | .on::<req::AnalyzerStatus>(handlers::handle_analyzer_status)? | 347 | .on::<req::AnalyzerStatus>(handlers::handle_analyzer_status)? |
342 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? | 348 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? |
343 | .on::<req::ExtendSelection>(handlers::handle_extend_selection)? | ||
344 | .on::<req::OnTypeFormatting>(handlers::handle_on_type_formatting)? | 349 | .on::<req::OnTypeFormatting>(handlers::handle_on_type_formatting)? |
345 | .on::<req::DocumentSymbolRequest>(handlers::handle_document_symbol)? | 350 | .on::<req::DocumentSymbolRequest>(handlers::handle_document_symbol)? |
346 | .on::<req::WorkspaceSymbol>(handlers::handle_workspace_symbol)? | 351 | .on::<req::WorkspaceSymbol>(handlers::handle_workspace_symbol)? |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index c2a44ffa0..a3d3f167c 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -3,13 +3,13 @@ use std::{fmt::Write as _, io::Write as _}; | |||
3 | use gen_lsp_server::ErrorCode; | 3 | use gen_lsp_server::ErrorCode; |
4 | use lsp_types::{ | 4 | use lsp_types::{ |
5 | CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic, | 5 | CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic, |
6 | DiagnosticSeverity, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, | 6 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeKind, |
7 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, | 7 | FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, |
8 | MarkupKind, Position, PrepareRenameResponse, Range, RenameParams, SymbolInformation, | 8 | PrepareRenameResponse, Range, RenameParams, SymbolInformation, TextDocumentIdentifier, |
9 | TextDocumentIdentifier, TextEdit, WorkspaceEdit, | 9 | TextEdit, WorkspaceEdit, |
10 | }; | 10 | }; |
11 | use ra_ide_api::{ | 11 | use ra_ide_api::{ |
12 | AssistId, Cancelable, FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, | 12 | AssistId, FileId, FilePosition, FileRange, FoldKind, Query, Runnable, RunnableKind, |
13 | }; | 13 | }; |
14 | use ra_prof::profile; | 14 | use ra_prof::profile; |
15 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; | 15 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; |
@@ -45,27 +45,6 @@ pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) - | |||
45 | Ok(res) | 45 | Ok(res) |
46 | } | 46 | } |
47 | 47 | ||
48 | // FIXME: drop this API | ||
49 | pub fn handle_extend_selection( | ||
50 | world: WorldSnapshot, | ||
51 | params: req::ExtendSelectionParams, | ||
52 | ) -> Result<req::ExtendSelectionResult> { | ||
53 | log::error!( | ||
54 | "extend selection is deprecated and will be removed soon, | ||
55 | use the new selection range API in LSP", | ||
56 | ); | ||
57 | let file_id = params.text_document.try_conv_with(&world)?; | ||
58 | let line_index = world.analysis().file_line_index(file_id)?; | ||
59 | let selections = params | ||
60 | .selections | ||
61 | .into_iter() | ||
62 | .map_conv_with(&line_index) | ||
63 | .map(|range| FileRange { file_id, range }) | ||
64 | .map(|frange| world.analysis().extend_selection(frange).map(|it| it.conv_with(&line_index))) | ||
65 | .collect::<Cancelable<Vec<_>>>()?; | ||
66 | Ok(req::ExtendSelectionResult { selections }) | ||
67 | } | ||
68 | |||
69 | pub fn handle_selection_range( | 48 | pub fn handle_selection_range( |
70 | world: WorldSnapshot, | 49 | world: WorldSnapshot, |
71 | params: req::SelectionRangeParams, | 50 | params: req::SelectionRangeParams, |
@@ -325,27 +304,7 @@ pub fn handle_runnables( | |||
325 | continue; | 304 | continue; |
326 | } | 305 | } |
327 | } | 306 | } |
328 | 307 | res.push(to_lsp_runnable(&world, file_id, runnable)?); | |
329 | let args = runnable_args(&world, file_id, &runnable.kind)?; | ||
330 | |||
331 | let r = req::Runnable { | ||
332 | range: runnable.range.conv_with(&line_index), | ||
333 | label: match &runnable.kind { | ||
334 | RunnableKind::Test { name } => format!("test {}", name), | ||
335 | RunnableKind::TestMod { path } => format!("test-mod {}", path), | ||
336 | RunnableKind::Bench { name } => format!("bench {}", name), | ||
337 | RunnableKind::Bin => "run binary".to_string(), | ||
338 | }, | ||
339 | bin: "cargo".to_string(), | ||
340 | args, | ||
341 | env: { | ||
342 | let mut m = FxHashMap::default(); | ||
343 | m.insert("RUST_BACKTRACE".to_string(), "short".to_string()); | ||
344 | m | ||
345 | }, | ||
346 | cwd: workspace_root.map(|root| root.to_string_lossy().to_string()), | ||
347 | }; | ||
348 | res.push(r); | ||
349 | } | 308 | } |
350 | let mut check_args = vec!["check".to_string()]; | 309 | let mut check_args = vec!["check".to_string()]; |
351 | let label; | 310 | let label; |
@@ -693,42 +652,27 @@ pub fn handle_code_lens( | |||
693 | let line_index = world.analysis().file_line_index(file_id)?; | 652 | let line_index = world.analysis().file_line_index(file_id)?; |
694 | 653 | ||
695 | let mut lenses: Vec<CodeLens> = Default::default(); | 654 | let mut lenses: Vec<CodeLens> = Default::default(); |
696 | let workspace_root = world.workspace_root_for(file_id); | ||
697 | 655 | ||
698 | // Gather runnables | 656 | // Gather runnables |
699 | for runnable in world.analysis().runnables(file_id)? { | 657 | for runnable in world.analysis().runnables(file_id)? { |
700 | let title = match &runnable.kind { | 658 | let title = match &runnable.kind { |
701 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => Some("▶️Run Test"), | 659 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶️Run Test", |
702 | RunnableKind::Bench { .. } => Some("Run Bench"), | 660 | RunnableKind::Bench { .. } => "Run Bench", |
703 | RunnableKind::Bin => Some("️Run"), | 661 | RunnableKind::Bin => "Run", |
662 | } | ||
663 | .to_string(); | ||
664 | let r = to_lsp_runnable(&world, file_id, runnable)?; | ||
665 | let lens = CodeLens { | ||
666 | range: r.range, | ||
667 | command: Some(Command { | ||
668 | title, | ||
669 | command: "rust-analyzer.runSingle".into(), | ||
670 | arguments: Some(vec![to_value(r).unwrap()]), | ||
671 | }), | ||
672 | data: None, | ||
704 | }; | 673 | }; |
705 | 674 | ||
706 | if let Some(title) = title { | 675 | lenses.push(lens); |
707 | let args = runnable_args(&world, file_id, &runnable.kind)?; | ||
708 | let range = runnable.range.conv_with(&line_index); | ||
709 | |||
710 | // This represents the actual command that will be run. | ||
711 | let r: req::Runnable = req::Runnable { | ||
712 | range, | ||
713 | label: Default::default(), | ||
714 | bin: "cargo".into(), | ||
715 | args, | ||
716 | env: Default::default(), | ||
717 | cwd: workspace_root.map(|root| root.to_string_lossy().to_string()), | ||
718 | }; | ||
719 | |||
720 | let lens = CodeLens { | ||
721 | range, | ||
722 | command: Some(Command { | ||
723 | title: title.into(), | ||
724 | command: "rust-analyzer.runSingle".into(), | ||
725 | arguments: Some(vec![to_value(r).unwrap()]), | ||
726 | }), | ||
727 | data: None, | ||
728 | }; | ||
729 | |||
730 | lenses.push(lens); | ||
731 | } | ||
732 | } | 676 | } |
733 | 677 | ||
734 | // Handle impls | 678 | // Handle impls |
@@ -838,7 +782,7 @@ pub fn publish_diagnostics( | |||
838 | .into_iter() | 782 | .into_iter() |
839 | .map(|d| Diagnostic { | 783 | .map(|d| Diagnostic { |
840 | range: d.range.conv_with(&line_index), | 784 | range: d.range.conv_with(&line_index), |
841 | severity: Some(to_diagnostic_severity(d.severity)), | 785 | severity: Some(d.severity.conv()), |
842 | code: None, | 786 | code: None, |
843 | source: Some("rust-analyzer".to_string()), | 787 | source: Some("rust-analyzer".to_string()), |
844 | message: d.message, | 788 | message: d.message, |
@@ -856,6 +800,32 @@ pub fn publish_decorations( | |||
856 | Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) | 800 | Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) |
857 | } | 801 | } |
858 | 802 | ||
803 | fn to_lsp_runnable( | ||
804 | world: &WorldSnapshot, | ||
805 | file_id: FileId, | ||
806 | runnable: Runnable, | ||
807 | ) -> Result<req::Runnable> { | ||
808 | let args = runnable_args(world, file_id, &runnable.kind)?; | ||
809 | let line_index = world.analysis().file_line_index(file_id)?; | ||
810 | let label = match &runnable.kind { | ||
811 | RunnableKind::Test { name } => format!("test {}", name), | ||
812 | RunnableKind::TestMod { path } => format!("test-mod {}", path), | ||
813 | RunnableKind::Bench { name } => format!("bench {}", name), | ||
814 | RunnableKind::Bin => "run binary".to_string(), | ||
815 | }; | ||
816 | Ok(req::Runnable { | ||
817 | range: runnable.range.conv_with(&line_index), | ||
818 | label, | ||
819 | bin: "cargo".to_string(), | ||
820 | args, | ||
821 | env: { | ||
822 | let mut m = FxHashMap::default(); | ||
823 | m.insert("RUST_BACKTRACE".to_string(), "short".to_string()); | ||
824 | m | ||
825 | }, | ||
826 | cwd: world.workspace_root_for(file_id).map(|root| root.to_string_lossy().to_string()), | ||
827 | }) | ||
828 | } | ||
859 | fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { | 829 | fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { |
860 | let line_index = world.analysis().file_line_index(file_id)?; | 830 | let line_index = world.analysis().file_line_index(file_id)?; |
861 | let res = world | 831 | let res = world |
@@ -871,15 +841,6 @@ fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> | |||
871 | Ok(res) | 841 | Ok(res) |
872 | } | 842 | } |
873 | 843 | ||
874 | fn to_diagnostic_severity(severity: Severity) -> DiagnosticSeverity { | ||
875 | use ra_ide_api::Severity::*; | ||
876 | |||
877 | match severity { | ||
878 | Error => DiagnosticSeverity::Error, | ||
879 | WeakWarning => DiagnosticSeverity::Hint, | ||
880 | } | ||
881 | } | ||
882 | |||
883 | pub fn handle_inlay_hints( | 844 | pub fn handle_inlay_hints( |
884 | world: WorldSnapshot, | 845 | world: WorldSnapshot, |
885 | params: InlayHintsParams, | 846 | params: InlayHintsParams, |
@@ -894,14 +855,7 @@ pub fn handle_inlay_hints( | |||
894 | label: api_type.label.to_string(), | 855 | label: api_type.label.to_string(), |
895 | range: api_type.range.conv_with(&line_index), | 856 | range: api_type.range.conv_with(&line_index), |
896 | kind: match api_type.kind { | 857 | kind: match api_type.kind { |
897 | ra_ide_api::InlayKind::LetBindingType => InlayKind::LetBindingType, | 858 | ra_ide_api::InlayKind::TypeHint => InlayKind::TypeHint, |
898 | ra_ide_api::InlayKind::ClosureParameterType => InlayKind::ClosureParameterType, | ||
899 | ra_ide_api::InlayKind::ForExpressionBindingType => { | ||
900 | InlayKind::ForExpressionBindingType | ||
901 | } | ||
902 | ra_ide_api::InlayKind::IfExpressionType => InlayKind::IfExpressionType, | ||
903 | ra_ide_api::InlayKind::WhileLetExpressionType => InlayKind::WhileLetExpressionType, | ||
904 | ra_ide_api::InlayKind::MatchArmType => InlayKind::MatchArmType, | ||
905 | }, | 859 | }, |
906 | }) | 860 | }) |
907 | .collect()) | 861 | .collect()) |
diff --git a/crates/ra_lsp_server/src/markdown.rs b/crates/ra_lsp_server/src/markdown.rs index 947ef77cd..c1eb0236a 100644 --- a/crates/ra_lsp_server/src/markdown.rs +++ b/crates/ra_lsp_server/src/markdown.rs | |||
@@ -54,4 +54,21 @@ mod tests { | |||
54 | let comment = "this\nis\nultiline"; | 54 | let comment = "this\nis\nultiline"; |
55 | assert_eq!(format_docs(comment), comment); | 55 | assert_eq!(format_docs(comment), comment); |
56 | } | 56 | } |
57 | |||
58 | #[test] | ||
59 | fn test_code_blocks_in_comments_marked_as_rust() { | ||
60 | let comment = r#"```rust | ||
61 | fn main(){} | ||
62 | ``` | ||
63 | Some comment. | ||
64 | ``` | ||
65 | let a = 1; | ||
66 | ```"#; | ||
67 | |||
68 | assert_eq!( | ||
69 | format_docs(comment), | ||
70 | "```rust\nfn main(){}\n```\nSome comment.\n```rust\nlet a = 1;\n```" | ||
71 | ); | ||
72 | } | ||
73 | |||
57 | } | 74 | } |
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs index 570438643..b2f3c509d 100644 --- a/crates/ra_lsp_server/src/req.rs +++ b/crates/ra_lsp_server/src/req.rs | |||
@@ -43,27 +43,6 @@ pub struct SyntaxTreeParams { | |||
43 | pub range: Option<Range>, | 43 | pub range: Option<Range>, |
44 | } | 44 | } |
45 | 45 | ||
46 | pub enum ExtendSelection {} | ||
47 | |||
48 | impl Request for ExtendSelection { | ||
49 | type Params = ExtendSelectionParams; | ||
50 | type Result = ExtendSelectionResult; | ||
51 | const METHOD: &'static str = "rust-analyzer/extendSelection"; | ||
52 | } | ||
53 | |||
54 | #[derive(Deserialize, Debug)] | ||
55 | #[serde(rename_all = "camelCase")] | ||
56 | pub struct ExtendSelectionParams { | ||
57 | pub text_document: TextDocumentIdentifier, | ||
58 | pub selections: Vec<Range>, | ||
59 | } | ||
60 | |||
61 | #[derive(Serialize, Debug)] | ||
62 | #[serde(rename_all = "camelCase")] | ||
63 | pub struct ExtendSelectionResult { | ||
64 | pub selections: Vec<Range>, | ||
65 | } | ||
66 | |||
67 | pub enum SelectionRangeRequest {} | 46 | pub enum SelectionRangeRequest {} |
68 | 47 | ||
69 | impl Request for SelectionRangeRequest { | 48 | impl Request for SelectionRangeRequest { |
@@ -213,12 +192,7 @@ pub struct InlayHintsParams { | |||
213 | 192 | ||
214 | #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] | 193 | #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] |
215 | pub enum InlayKind { | 194 | pub enum InlayKind { |
216 | LetBindingType, | 195 | TypeHint, |
217 | ClosureParameterType, | ||
218 | ForExpressionBindingType, | ||
219 | IfExpressionType, | ||
220 | WhileLetExpressionType, | ||
221 | MatchArmType, | ||
222 | } | 196 | } |
223 | 197 | ||
224 | #[derive(Debug, Deserialize, Serialize)] | 198 | #[derive(Debug, Deserialize, Serialize)] |
diff --git a/crates/ra_lsp_server/src/vfs_filter.rs b/crates/ra_lsp_server/src/vfs_filter.rs deleted file mode 100644 index e16a57da5..000000000 --- a/crates/ra_lsp_server/src/vfs_filter.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | use ra_project_model::ProjectRoot; | ||
2 | use ra_vfs::{Filter, RelativePath, RootEntry}; | ||
3 | use std::path::PathBuf; | ||
4 | |||
5 | /// `IncludeRustFiles` is used to convert | ||
6 | /// from `ProjectRoot` to `RootEntry` for VFS | ||
7 | pub struct IncludeRustFiles { | ||
8 | root: ProjectRoot, | ||
9 | } | ||
10 | |||
11 | impl IncludeRustFiles { | ||
12 | pub fn from_roots<R>(roots: R) -> impl Iterator<Item = RootEntry> | ||
13 | where | ||
14 | R: IntoIterator<Item = ProjectRoot>, | ||
15 | { | ||
16 | roots.into_iter().map(IncludeRustFiles::from_root) | ||
17 | } | ||
18 | |||
19 | pub fn from_root(root: ProjectRoot) -> RootEntry { | ||
20 | IncludeRustFiles::from(root).into() | ||
21 | } | ||
22 | |||
23 | #[allow(unused)] | ||
24 | pub fn external(path: PathBuf) -> RootEntry { | ||
25 | IncludeRustFiles::from_root(ProjectRoot::new(path, false)) | ||
26 | } | ||
27 | |||
28 | pub fn member(path: PathBuf) -> RootEntry { | ||
29 | IncludeRustFiles::from_root(ProjectRoot::new(path, true)) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl Filter for IncludeRustFiles { | ||
34 | fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
35 | self.root.include_dir(dir_path) | ||
36 | } | ||
37 | |||
38 | fn include_file(&self, file_path: &RelativePath) -> bool { | ||
39 | self.root.include_file(file_path) | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl std::convert::From<ProjectRoot> for IncludeRustFiles { | ||
44 | fn from(v: ProjectRoot) -> IncludeRustFiles { | ||
45 | IncludeRustFiles { root: v } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | impl std::convert::From<IncludeRustFiles> for RootEntry { | ||
50 | fn from(v: IncludeRustFiles) -> RootEntry { | ||
51 | let path = v.root.path().clone(); | ||
52 | RootEntry::new(path, Box::new(v)) | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 1d7755910..9990ef62e 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -9,13 +9,13 @@ use parking_lot::RwLock; | |||
9 | use ra_ide_api::{ | 9 | use ra_ide_api::{ |
10 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, | 10 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, |
11 | }; | 11 | }; |
12 | use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; | 12 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; |
13 | use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; | ||
13 | use relative_path::RelativePathBuf; | 14 | use relative_path::RelativePathBuf; |
14 | 15 | ||
15 | use crate::{ | 16 | use crate::{ |
16 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, | 17 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, |
17 | project_model::ProjectWorkspace, | 18 | project_model::ProjectWorkspace, |
18 | vfs_filter::IncludeRustFiles, | ||
19 | LspError, Result, | 19 | LspError, Result, |
20 | }; | 20 | }; |
21 | 21 | ||
@@ -56,14 +56,28 @@ impl WorldState { | |||
56 | folder_roots: Vec<PathBuf>, | 56 | folder_roots: Vec<PathBuf>, |
57 | workspaces: Vec<ProjectWorkspace>, | 57 | workspaces: Vec<ProjectWorkspace>, |
58 | lru_capacity: Option<usize>, | 58 | lru_capacity: Option<usize>, |
59 | exclude_globs: &[Glob], | ||
59 | options: Options, | 60 | options: Options, |
60 | ) -> WorldState { | 61 | ) -> WorldState { |
61 | let mut change = AnalysisChange::new(); | 62 | let mut change = AnalysisChange::new(); |
62 | 63 | ||
63 | let mut roots = Vec::new(); | 64 | let mut roots = Vec::new(); |
64 | roots.extend(folder_roots.iter().cloned().map(IncludeRustFiles::member)); | 65 | roots.extend(folder_roots.iter().map(|path| { |
66 | let mut filter = RustPackageFilterBuilder::default().set_member(true); | ||
67 | for glob in exclude_globs.iter() { | ||
68 | filter = filter.exclude(glob.clone()); | ||
69 | } | ||
70 | RootEntry::new(path.clone(), filter.into_vfs_filter()) | ||
71 | })); | ||
65 | for ws in workspaces.iter() { | 72 | for ws in workspaces.iter() { |
66 | roots.extend(IncludeRustFiles::from_roots(ws.to_roots())); | 73 | roots.extend(ws.to_roots().into_iter().map(|pkg_root| { |
74 | let mut filter = | ||
75 | RustPackageFilterBuilder::default().set_member(pkg_root.is_member()); | ||
76 | for glob in exclude_globs.iter() { | ||
77 | filter = filter.exclude(glob.clone()); | ||
78 | } | ||
79 | RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) | ||
80 | })); | ||
67 | } | 81 | } |
68 | 82 | ||
69 | let (mut vfs, vfs_roots) = Vfs::new(roots); | 83 | let (mut vfs, vfs_roots) = Vfs::new(roots); |
@@ -211,7 +225,7 @@ impl WorldSnapshot { | |||
211 | } else { | 225 | } else { |
212 | res.push_str("workspaces:\n"); | 226 | res.push_str("workspaces:\n"); |
213 | for w in self.workspaces.iter() { | 227 | for w in self.workspaces.iter() { |
214 | res += &format!("{} packages loaded\n", w.count()); | 228 | res += &format!("{} packages loaded\n", w.n_packages()); |
215 | } | 229 | } |
216 | } | 230 | } |
217 | res.push_str("\nanalysis:\n"); | 231 | res.push_str("\nanalysis:\n"); |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 5dddbbe17..ba8ee8b06 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -22,7 +22,7 @@ use tempfile::TempDir; | |||
22 | use test_utils::{find_mismatch, parse_fixture}; | 22 | use test_utils::{find_mismatch, parse_fixture}; |
23 | use thread_worker::Worker; | 23 | use thread_worker::Worker; |
24 | 24 | ||
25 | use ra_lsp_server::{main_loop, req, InitializationOptions}; | 25 | use ra_lsp_server::{main_loop, req, ServerConfig}; |
26 | 26 | ||
27 | pub struct Project<'a> { | 27 | pub struct Project<'a> { |
28 | fixture: &'a str, | 28 | fixture: &'a str, |
@@ -107,7 +107,7 @@ impl Server { | |||
107 | window: None, | 107 | window: None, |
108 | experimental: None, | 108 | experimental: None, |
109 | }, | 109 | }, |
110 | InitializationOptions::default(), | 110 | ServerConfig::default(), |
111 | &msg_receiver, | 111 | &msg_receiver, |
112 | &msg_sender, | 112 | &msg_sender, |
113 | ) | 113 | ) |