aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/conv.rs53
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs4
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs5
-rw-r--r--crates/ra_lsp_server/src/req.rs22
-rw-r--r--crates/ra_lsp_server/src/server_world.rs32
5 files changed, 65 insertions, 51 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 1107ffc8b..e8eb3940f 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -1,11 +1,16 @@
1use languageserver_types::{ 1use languageserver_types::{
2 self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, 2 self, CreateFile, DocumentChangeOperation, DocumentChanges, InsertTextFormat, Location,
3 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat, 3 Position, Range, RenameFile, ResourceOp, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
4 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
5 WorkspaceEdit,
4}; 6};
5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition,FileRange, CompletionItem, CompletionItemKind, InsertText, NavigationTarget}; 7use ra_analysis::{
6use ra_editor::{LineCol, LineIndex, translate_offset_with_edit}; 8 CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit,
7use ra_text_edit::{AtomTextEdit, TextEdit}; 9 InsertText, NavigationTarget, SourceChange, SourceFileEdit,
10};
11use ra_editor::{translate_offset_with_edit, LineCol, LineIndex};
8use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 12use ra_syntax::{SyntaxKind, TextRange, TextUnit};
13use ra_text_edit::{AtomTextEdit, TextEdit};
9 14
10use crate::{req, server_world::ServerWorld, Result}; 15use crate::{req, server_world::ServerWorld, Result};
11 16
@@ -39,7 +44,7 @@ impl Conv for SyntaxKind {
39 SyntaxKind::TYPE_DEF => SymbolKind::TypeParameter, 44 SyntaxKind::TYPE_DEF => SymbolKind::TypeParameter,
40 SyntaxKind::STATIC_DEF => SymbolKind::Constant, 45 SyntaxKind::STATIC_DEF => SymbolKind::Constant,
41 SyntaxKind::CONST_DEF => SymbolKind::Constant, 46 SyntaxKind::CONST_DEF => SymbolKind::Constant,
42 SyntaxKind::IMPL_ITEM => SymbolKind::Object, 47 SyntaxKind::IMPL_BLOCK => SymbolKind::Object,
43 _ => SymbolKind::Variable, 48 _ => SymbolKind::Variable,
44 } 49 }
45 } 50 }
@@ -49,7 +54,7 @@ impl Conv for CompletionItemKind {
49 type Output = ::languageserver_types::CompletionItemKind; 54 type Output = ::languageserver_types::CompletionItemKind;
50 55
51 fn conv(self) -> <Self as Conv>::Output { 56 fn conv(self) -> <Self as Conv>::Output {
52 use ::languageserver_types::CompletionItemKind::*; 57 use languageserver_types::CompletionItemKind::*;
53 match self { 58 match self {
54 CompletionItemKind::Keyword => Keyword, 59 CompletionItemKind::Keyword => Keyword,
55 CompletionItemKind::Snippet => Snippet, 60 CompletionItemKind::Snippet => Snippet,
@@ -266,12 +271,20 @@ impl TryConvWith for SourceChange {
266 }) 271 })
267 } 272 }
268 }; 273 };
269 let source_file_edits = self.source_file_edits.try_conv_with(world)?; 274 let mut document_changes: Vec<DocumentChangeOperation> = Vec::new();
270 let file_system_edits = self.file_system_edits.try_conv_with(world)?; 275 for resource_op in self.file_system_edits.try_conv_with(world)? {
276 document_changes.push(DocumentChangeOperation::Op(resource_op));
277 }
278 for text_document_edit in self.source_file_edits.try_conv_with(world)? {
279 document_changes.push(DocumentChangeOperation::Edit(text_document_edit));
280 }
281 let workspace_edit = WorkspaceEdit {
282 changes: None,
283 document_changes: Some(DocumentChanges::Operations(document_changes)),
284 };
271 Ok(req::SourceChange { 285 Ok(req::SourceChange {
272 label: self.label, 286 label: self.label,
273 source_file_edits, 287 workspace_edit,
274 file_system_edits,
275 cursor_position, 288 cursor_position,
276 }) 289 })
277 } 290 }
@@ -301,21 +314,25 @@ impl TryConvWith for SourceFileEdit {
301 314
302impl TryConvWith for FileSystemEdit { 315impl TryConvWith for FileSystemEdit {
303 type Ctx = ServerWorld; 316 type Ctx = ServerWorld;
304 type Output = req::FileSystemEdit; 317 type Output = ResourceOp;
305 fn try_conv_with(self, world: &ServerWorld) -> Result<req::FileSystemEdit> { 318 fn try_conv_with(self, world: &ServerWorld) -> Result<ResourceOp> {
306 let res = match self { 319 let res = match self {
307 FileSystemEdit::CreateFile { source_root, path } => { 320 FileSystemEdit::CreateFile { source_root, path } => {
308 let uri = world.path_to_uri(source_root, &path)?; 321 let uri = world.path_to_uri(source_root, &path)?.to_string();
309 req::FileSystemEdit::CreateFile { uri } 322 ResourceOp::Create(CreateFile { uri, options: None })
310 } 323 }
311 FileSystemEdit::MoveFile { 324 FileSystemEdit::MoveFile {
312 src, 325 src,
313 dst_source_root, 326 dst_source_root,
314 dst_path, 327 dst_path,
315 } => { 328 } => {
316 let src = world.file_id_to_uri(src)?; 329 let old_uri = world.file_id_to_uri(src)?.to_string();
317 let dst = world.path_to_uri(dst_source_root, &dst_path)?; 330 let new_uri = world.path_to_uri(dst_source_root, &dst_path)?.to_string();
318 req::FileSystemEdit::MoveFile { src, dst } 331 ResourceOp::Rename(RenameFile {
332 old_uri,
333 new_uri,
334 options: None,
335 })
319 } 336 }
320 }; 337 };
321 Ok(res) 338 Ok(res)
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 06dd373c0..60d9671de 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -350,7 +350,7 @@ fn on_notification(
350 .write() 350 .write()
351 .add_file_overlay(&path, params.text_document.text) 351 .add_file_overlay(&path, params.text_document.text)
352 { 352 {
353 subs.add_sub(FileId(file_id.0)); 353 subs.add_sub(FileId(file_id.0.into()));
354 } 354 }
355 return Ok(()); 355 return Ok(());
356 } 356 }
@@ -379,7 +379,7 @@ fn on_notification(
379 .to_file_path() 379 .to_file_path()
380 .map_err(|()| format_err!("invalid uri: {}", uri))?; 380 .map_err(|()| format_err!("invalid uri: {}", uri))?;
381 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { 381 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) {
382 subs.remove_sub(FileId(file_id.0)); 382 subs.remove_sub(FileId(file_id.0.into()));
383 } 383 }
384 let params = req::PublishDiagnosticsParams { 384 let params = req::PublishDiagnosticsParams {
385 uri, 385 uri,
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 06ae9a64a..2fc4d3649 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -337,7 +337,10 @@ pub fn handle_runnables(
337 None => return Ok(None), 337 None => return Ok(None),
338 }; 338 };
339 let file_id = world.analysis().crate_root(crate_id)?; 339 let file_id = world.analysis().crate_root(crate_id)?;
340 let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0)); 340 let path = world
341 .vfs
342 .read()
343 .file2path(ra_vfs::VfsFile(file_id.0.into()));
341 let res = world.workspaces.iter().find_map(|ws| { 344 let res = world.workspaces.iter().find_map(|ws| {
342 let tgt = ws.target_by_root(&path)?; 345 let tgt = ws.target_by_root(&path)?;
343 let res = CargoTargetSpec { 346 let res = CargoTargetSpec {
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index 747ab8a8c..b41e90328 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -1,6 +1,6 @@
1use serde::{Serialize, Deserialize};
2use languageserver_types::{Location, Position, Range, TextDocumentIdentifier, Url}; 1use languageserver_types::{Location, Position, Range, TextDocumentIdentifier, Url};
3use rustc_hash::FxHashMap; 2use rustc_hash::FxHashMap;
3use serde::{Deserialize, Serialize};
4use url_serde; 4use url_serde;
5 5
6pub use languageserver_types::{ 6pub use languageserver_types::{
@@ -8,7 +8,7 @@ pub use languageserver_types::{
8 CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams, 8 CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams,
9 DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult, 9 DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult,
10 PublishDiagnosticsParams, ReferenceParams, SignatureHelp, TextDocumentEdit, 10 PublishDiagnosticsParams, ReferenceParams, SignatureHelp, TextDocumentEdit,
11 TextDocumentPositionParams, TextEdit, WorkspaceSymbolParams, 11 TextDocumentPositionParams, TextEdit, WorkspaceEdit, WorkspaceSymbolParams,
12}; 12};
13 13
14pub enum SyntaxTree {} 14pub enum SyntaxTree {}
@@ -151,26 +151,10 @@ pub struct Runnable {
151#[serde(rename_all = "camelCase")] 151#[serde(rename_all = "camelCase")]
152pub struct SourceChange { 152pub struct SourceChange {
153 pub label: String, 153 pub label: String,
154 pub source_file_edits: Vec<TextDocumentEdit>, 154 pub workspace_edit: WorkspaceEdit,
155 pub file_system_edits: Vec<FileSystemEdit>,
156 pub cursor_position: Option<TextDocumentPositionParams>, 155 pub cursor_position: Option<TextDocumentPositionParams>,
157} 156}
158 157
159#[derive(Serialize, Debug)]
160#[serde(tag = "type", rename_all = "camelCase")]
161pub enum FileSystemEdit {
162 CreateFile {
163 #[serde(with = "url_serde")]
164 uri: Url,
165 },
166 MoveFile {
167 #[serde(with = "url_serde")]
168 src: Url,
169 #[serde(with = "url_serde")]
170 dst: Url,
171 },
172}
173
174pub enum InternalFeedback {} 158pub enum InternalFeedback {}
175 159
176impl Notification for InternalFeedback { 160impl Notification for InternalFeedback {
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index c183c25af..ebf2b15cc 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -49,7 +49,7 @@ impl ServerWorldState {
49 let (mut vfs, roots) = Vfs::new(roots); 49 let (mut vfs, roots) = Vfs::new(roots);
50 for r in roots { 50 for r in roots {
51 let is_local = vfs.root2path(r).starts_with(&root); 51 let is_local = vfs.root2path(r).starts_with(&root);
52 change.add_root(SourceRootId(r.0), is_local); 52 change.add_root(SourceRootId(r.0.into()), is_local);
53 } 53 }
54 54
55 let mut crate_graph = CrateGraph::default(); 55 let mut crate_graph = CrateGraph::default();
@@ -60,7 +60,7 @@ impl ServerWorldState {
60 for tgt in pkg.targets(ws) { 60 for tgt in pkg.targets(ws) {
61 let root = tgt.root(ws); 61 let root = tgt.root(ws);
62 if let Some(file_id) = vfs.load(root) { 62 if let Some(file_id) = vfs.load(root) {
63 let file_id = FileId(file_id.0); 63 let file_id = FileId(file_id.0.into());
64 let crate_id = crate_graph.add_crate_root(file_id); 64 let crate_id = crate_graph.add_crate_root(file_id);
65 if tgt.kind(ws) == TargetKind::Lib { 65 if tgt.kind(ws) == TargetKind::Lib {
66 pkg_to_lib_crate.insert(pkg, crate_id); 66 pkg_to_lib_crate.insert(pkg, crate_id);
@@ -113,14 +113,19 @@ impl ServerWorldState {
113 if root_path.starts_with(&self.root) { 113 if root_path.starts_with(&self.root) {
114 self.roots_to_scan -= 1; 114 self.roots_to_scan -= 1;
115 for (file, path, text) in files { 115 for (file, path, text) in files {
116 change.add_file(SourceRootId(root.0), FileId(file.0), path, text); 116 change.add_file(
117 SourceRootId(root.0.into()),
118 FileId(file.0.into()),
119 path,
120 text,
121 );
117 } 122 }
118 } else { 123 } else {
119 let files = files 124 let files = files
120 .into_iter() 125 .into_iter()
121 .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) 126 .map(|(vfsfile, path, text)| (FileId(vfsfile.0.into()), path, text))
122 .collect(); 127 .collect();
123 libs.push((SourceRootId(root.0), files)); 128 libs.push((SourceRootId(root.0.into()), files));
124 } 129 }
125 } 130 }
126 VfsChange::AddFile { 131 VfsChange::AddFile {
@@ -129,13 +134,18 @@ impl ServerWorldState {
129 path, 134 path,
130 text, 135 text,
131 } => { 136 } => {
132 change.add_file(SourceRootId(root.0), FileId(file.0), path, text); 137 change.add_file(
138 SourceRootId(root.0.into()),
139 FileId(file.0.into()),
140 path,
141 text,
142 );
133 } 143 }
134 VfsChange::RemoveFile { root, file, path } => { 144 VfsChange::RemoveFile { root, file, path } => {
135 change.remove_file(SourceRootId(root.0), FileId(file.0), path) 145 change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path)
136 } 146 }
137 VfsChange::ChangeFile { file, text } => { 147 VfsChange::ChangeFile { file, text } => {
138 change.change_file(FileId(file.0), text); 148 change.change_file(FileId(file.0.into()), text);
139 } 149 }
140 } 150 }
141 } 151 }
@@ -173,18 +183,18 @@ impl ServerWorld {
173 .read() 183 .read()
174 .path2file(&path) 184 .path2file(&path)
175 .ok_or_else(|| format_err!("unknown file: {}", path.display()))?; 185 .ok_or_else(|| format_err!("unknown file: {}", path.display()))?;
176 Ok(FileId(file.0)) 186 Ok(FileId(file.0.into()))
177 } 187 }
178 188
179 pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { 189 pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> {
180 let path = self.vfs.read().file2path(VfsFile(id.0)); 190 let path = self.vfs.read().file2path(VfsFile(id.0.into()));
181 let url = Url::from_file_path(&path) 191 let url = Url::from_file_path(&path)
182 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; 192 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
183 Ok(url) 193 Ok(url)
184 } 194 }
185 195
186 pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { 196 pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> {
187 let base = self.vfs.read().root2path(VfsRoot(root.0)); 197 let base = self.vfs.read().root2path(VfsRoot(root.0.into()));
188 let path = path.to_path(base); 198 let path = path.to_path(base);
189 let url = Url::from_file_path(&path) 199 let url = Url::from_file_path(&path)
190 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; 200 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;