aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r--crates/ra_lsp_server/Cargo.toml1
-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.rs20
-rw-r--r--crates/ra_lsp_server/src/lib.rs6
-rw-r--r--crates/ra_lsp_server/src/main.rs4
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs21
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs144
-rw-r--r--crates/ra_lsp_server/src/markdown.rs17
-rw-r--r--crates/ra_lsp_server/src/req.rs28
-rw-r--r--crates/ra_lsp_server/src/vfs_filter.rs54
-rw-r--r--crates/ra_lsp_server/src/world.rs24
-rw-r--r--crates/ra_lsp_server/tests/heavy_tests/support.rs4
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" }
25gen_lsp_server = { path = "../gen_lsp_server" } 25gen_lsp_server = { path = "../gen_lsp_server" }
26ra_project_model = { path = "../ra_project_model" } 26ra_project_model = { path = "../ra_project_model" }
27ra_prof = { path = "../ra_prof" } 27ra_prof = { path = "../ra_prof" }
28ra_vfs_glob = { path = "../ra_vfs_glob" }
28 29
29[dev-dependencies] 30[dev-dependencies]
30tempfile = "3" 31tempfile = "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 @@
1use serde::{Deserialize, Deserializer}; 1use 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)]
6pub struct InitializationOptions { 6pub 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
24impl Default for InitializationOptions { 26impl 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 @@
1use lsp_types::{ 1use 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};
7use ra_ide_api::{ 7use 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};
12use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 12use ra_syntax::{SyntaxKind, TextRange, TextUnit};
13use ra_text_edit::{AtomTextEdit, TextEdit}; 13use ra_text_edit::{AtomTextEdit, TextEdit};
@@ -79,6 +79,16 @@ impl Conv for CompletionItemKind {
79 } 79 }
80} 80}
81 81
82impl 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
82impl ConvWith for CompletionItem { 92impl 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;
4mod main_loop; 4mod main_loop;
5mod markdown; 5mod markdown;
6mod project_model; 6mod project_model;
7mod vfs_filter;
8pub mod req; 7pub mod req;
9pub mod init; 8pub mod config;
10mod world; 9mod world;
11 10
12pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; 11pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
13pub use crate::{ 12pub 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};
2use gen_lsp_server::{run_server, stdio_transport}; 2use gen_lsp_server::{run_server, stdio_transport};
3use serde::Deserialize; 3use serde::Deserialize;
4 4
5use ra_lsp_server::{InitializationOptions, Result}; 5use ra_lsp_server::{Result, ServerConfig};
6use ra_prof; 6use ra_prof;
7 7
8fn main() -> Result<()> { 8fn 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
29const THREADPOOL_SIZE: usize = 8; 29const THREADPOOL_SIZE: usize = 8;
@@ -52,10 +52,11 @@ impl Error for LspError {}
52pub fn main_loop( 52pub 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 _};
3use gen_lsp_server::ErrorCode; 3use gen_lsp_server::ErrorCode;
4use lsp_types::{ 4use 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};
11use ra_ide_api::{ 11use ra_ide_api::{
12 AssistId, Cancelable, FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, 12 AssistId, FileId, FilePosition, FileRange, FoldKind, Query, Runnable, RunnableKind,
13}; 13};
14use ra_prof::profile; 14use ra_prof::profile;
15use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; 15use 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
49pub 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
69pub fn handle_selection_range( 48pub 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
803fn 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}
859fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { 829fn 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
874fn 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
883pub fn handle_inlay_hints( 844pub 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
61fn main(){}
62```
63Some comment.
64```
65let 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
46pub enum ExtendSelection {}
47
48impl 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")]
56pub struct ExtendSelectionParams {
57 pub text_document: TextDocumentIdentifier,
58 pub selections: Vec<Range>,
59}
60
61#[derive(Serialize, Debug)]
62#[serde(rename_all = "camelCase")]
63pub struct ExtendSelectionResult {
64 pub selections: Vec<Range>,
65}
66
67pub enum SelectionRangeRequest {} 46pub enum SelectionRangeRequest {}
68 47
69impl Request for SelectionRangeRequest { 48impl 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)]
215pub enum InlayKind { 194pub 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 @@
1use ra_project_model::ProjectRoot;
2use ra_vfs::{Filter, RelativePath, RootEntry};
3use std::path::PathBuf;
4
5/// `IncludeRustFiles` is used to convert
6/// from `ProjectRoot` to `RootEntry` for VFS
7pub struct IncludeRustFiles {
8 root: ProjectRoot,
9}
10
11impl 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
33impl 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
43impl std::convert::From<ProjectRoot> for IncludeRustFiles {
44 fn from(v: ProjectRoot) -> IncludeRustFiles {
45 IncludeRustFiles { root: v }
46 }
47}
48
49impl 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;
9use ra_ide_api::{ 9use ra_ide_api::{
10 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, 10 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId,
11}; 11};
12use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; 12use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot};
13use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
13use relative_path::RelativePathBuf; 14use relative_path::RelativePathBuf;
14 15
15use crate::{ 16use 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;
22use test_utils::{find_mismatch, parse_fixture}; 22use test_utils::{find_mismatch, parse_fixture};
23use thread_worker::Worker; 23use thread_worker::Worker;
24 24
25use ra_lsp_server::{main_loop, req, InitializationOptions}; 25use ra_lsp_server::{main_loop, req, ServerConfig};
26 26
27pub struct Project<'a> { 27pub 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 )