aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src')
-rw-r--r--crates/server/src/main.rs1
-rw-r--r--crates/server/src/main_loop/handlers.rs52
-rw-r--r--crates/server/src/path_map.rs23
-rw-r--r--crates/server/src/server_world.rs5
4 files changed, 56 insertions, 25 deletions
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs
index 615dd082c..1a93af65b 100644
--- a/crates/server/src/main.rs
+++ b/crates/server/src/main.rs
@@ -18,6 +18,7 @@ extern crate libeditor;
18extern crate libanalysis; 18extern crate libanalysis;
19extern crate libsyntax2; 19extern crate libsyntax2;
20extern crate im; 20extern crate im;
21extern crate relative_path;
21 22
22mod io; 23mod io;
23mod caps; 24mod caps;
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs
index ca5cd5ab1..92ffb30c3 100644
--- a/crates/server/src/main_loop/handlers.rs
+++ b/crates/server/src/main_loop/handlers.rs
@@ -7,7 +7,8 @@ use languageserver_types::{
7 CompletionItem, 7 CompletionItem,
8}; 8};
9use serde_json::{to_value, from_value}; 9use serde_json::{to_value, from_value};
10use libanalysis::{Query, QuickFix, FileId}; 10use url_serde;
11use libanalysis::{self, Query, FileId};
11use libeditor; 12use libeditor;
12use libsyntax2::{ 13use libsyntax2::{
13 TextUnit, 14 TextUnit,
@@ -144,24 +145,49 @@ pub fn handle_code_action(
144 if !contains_offset_nonstrict(diag.range, offset) { 145 if !contains_offset_nonstrict(diag.range, offset) {
145 continue; 146 continue;
146 } 147 }
147 let cmd = match quick_fix { 148 let mut ops = Vec::new();
148 QuickFix::CreateFile(path) => { 149 for op in quick_fix.fs_ops {
149 let path = &path.to_str().unwrap()[3..]; // strip `../` b/c url is weird 150 let op = match op {
150 let uri = params.text_document.uri.join(path) 151 libanalysis::FsOp::CreateFile { anchor, path } => {
151 .unwrap(); 152 let uri = world.file_id_to_uri(anchor)?;
152 let uri = ::url_serde::Ser::new(&uri); 153 let path = &path.as_str()[3..]; // strip `../` b/c url is weird
153 Command { 154 let uri = uri.join(path)?;
154 title: "Create file".to_string(), 155 FsOp::CreateFile { uri }
155 command: "libsyntax-rust.createFile".to_string(), 156 },
156 arguments: Some(vec![to_value(uri).unwrap()]), 157 libanalysis::FsOp::MoveFile { file, path } => {
157 } 158 let src = world.file_id_to_uri(file)?;
158 } 159 let path = &path.as_str()[3..]; // strip `../` b/c url is weird
160 let dst = src.join(path)?;
161 FsOp::MoveFile { src, dst }
162 },
163 };
164 ops.push(op)
165 }
166 let cmd = Command {
167 title: "Create module".to_string(),
168 command: "libsyntax-rust.fsEdit".to_string(),
169 arguments: Some(vec![to_value(ops).unwrap()]),
159 }; 170 };
160 res.push(cmd) 171 res.push(cmd)
161 } 172 }
162 return Ok(Some(res)); 173 return Ok(Some(res));
163} 174}
164 175
176#[derive(Serialize)]
177#[serde(tag = "type", rename_all = "camelCase")]
178enum FsOp {
179 CreateFile {
180 #[serde(with = "url_serde")]
181 uri: Url
182 },
183 MoveFile {
184 #[serde(with = "url_serde")]
185 src: Url,
186 #[serde(with = "url_serde")]
187 dst: Url,
188 }
189}
190
165pub fn handle_runnables( 191pub fn handle_runnables(
166 world: ServerWorld, 192 world: ServerWorld,
167 params: req::RunnablesParams, 193 params: req::RunnablesParams,
diff --git a/crates/server/src/path_map.rs b/crates/server/src/path_map.rs
index d2b811a3b..f4ac47e70 100644
--- a/crates/server/src/path_map.rs
+++ b/crates/server/src/path_map.rs
@@ -1,6 +1,7 @@
1use std::path::{PathBuf, Path, Component}; 1use std::path::{PathBuf, Path, Component};
2use im; 2use im;
3use libanalysis::{FileId}; 3use relative_path::RelativePath;
4use libanalysis::{FileId, FileResolver};
4 5
5#[derive(Debug, Default, Clone)] 6#[derive(Debug, Default, Clone)]
6pub struct PathMap { 7pub struct PathMap {
@@ -34,12 +35,6 @@ impl PathMap {
34 .as_path() 35 .as_path()
35 } 36 }
36 37
37 pub fn resolve(&self, id: FileId, relpath: &Path) -> Option<FileId> {
38 let path = self.get_path(id).join(relpath);
39 let path = normalize(&path);
40 self.get_id(&path)
41 }
42
43 fn insert(&mut self, path: PathBuf, id: FileId) { 38 fn insert(&mut self, path: PathBuf, id: FileId) {
44 self.path2id.insert(path.clone(), id); 39 self.path2id.insert(path.clone(), id);
45 self.id2path.insert(id, path.clone()); 40 self.id2path.insert(id, path.clone());
@@ -52,6 +47,18 @@ impl PathMap {
52 } 47 }
53} 48}
54 49
50impl FileResolver for PathMap {
51 fn file_stem(&self, id: FileId) -> String {
52 self.get_path(id).file_stem().unwrap().to_str().unwrap().to_string()
53 }
54
55 fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId> {
56 let path = path.to_path(&self.get_path(id));
57 let path = normalize(&path);
58 self.get_id(&path)
59 }
60}
61
55fn normalize(path: &Path) -> PathBuf { 62fn normalize(path: &Path) -> PathBuf {
56 let mut components = path.components().peekable(); 63 let mut components = path.components().peekable();
57 let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { 64 let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
@@ -89,7 +96,7 @@ mod test {
89 let id1 = m.get_or_insert(PathBuf::from("/foo")); 96 let id1 = m.get_or_insert(PathBuf::from("/foo"));
90 let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs")); 97 let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs"));
91 assert_eq!( 98 assert_eq!(
92 m.resolve(id1, &PathBuf::from("bar.rs")), 99 m.resolve(id1, &RelativePath::new("bar.rs")),
93 Some(id2), 100 Some(id2),
94 ) 101 )
95 } 102 }
diff --git a/crates/server/src/server_world.rs b/crates/server/src/server_world.rs
index c0d2efb86..1593cd59f 100644
--- a/crates/server/src/server_world.rs
+++ b/crates/server/src/server_world.rs
@@ -87,11 +87,8 @@ impl ServerWorldState {
87 } 87 }
88 88
89 pub fn snapshot(&self) -> ServerWorld { 89 pub fn snapshot(&self) -> ServerWorld {
90 let pm = self.path_map.clone();
91 ServerWorld { 90 ServerWorld {
92 analysis: self.analysis.snapshot(move |id, path| { 91 analysis: self.analysis.snapshot(self.path_map.clone()),
93 pm.resolve(id, path)
94 }),
95 path_map: self.path_map.clone() 92 path_map: self.path_map.clone()
96 } 93 }
97 } 94 }