this repo has no description
at wasm 138 lines 3.6 kB view raw
1mod code_action; 2mod compiler; 3mod completer; 4mod edits; 5mod engine; 6mod feedback; 7mod files; 8mod messages; 9mod progress; 10mod reference; 11mod rename; 12mod router; 13mod server; 14mod signature_help; 15 16#[cfg(test)] 17mod tests; 18 19pub use server::LanguageServer; 20 21use crate::{ 22 Result, ast::SrcSpan, build::Target, line_numbers::LineNumbers, manifest::Manifest, 23 paths::ProjectPaths, 24}; 25use camino::Utf8PathBuf; 26use lsp_types::{Position, Range, TextEdit, Url}; 27use std::any::Any; 28 29#[derive(Debug)] 30pub struct LockGuard(pub Box<dyn Any>); 31 32pub trait Locker { 33 fn lock_for_build(&self) -> Result<LockGuard>; 34} 35 36pub trait MakeLocker { 37 fn make_locker(&self, paths: &ProjectPaths, target: Target) -> Result<Box<dyn Locker>>; 38} 39 40pub trait DownloadDependencies { 41 fn download_dependencies(&self, paths: &ProjectPaths) -> Result<Manifest>; 42} 43 44pub fn src_span_to_lsp_range(location: SrcSpan, line_numbers: &LineNumbers) -> Range { 45 let start = line_numbers.line_and_column_number(location.start); 46 let end = line_numbers.line_and_column_number(location.end); 47 48 Range::new( 49 Position::new(start.line - 1, start.column - 1), 50 Position::new(end.line - 1, end.column - 1), 51 ) 52} 53 54pub fn lsp_range_to_src_span(range: Range, line_numbers: &LineNumbers) -> SrcSpan { 55 let start = line_numbers.byte_index(range.start); 56 let end = line_numbers.byte_index(range.end); 57 SrcSpan { start, end } 58} 59 60/// A little wrapper around LineNumbers to make it easier to build text edits. 61/// 62#[derive(Debug)] 63pub struct TextEdits<'a> { 64 line_numbers: &'a LineNumbers, 65 edits: Vec<TextEdit>, 66} 67 68impl<'a> TextEdits<'a> { 69 pub fn new(line_numbers: &'a LineNumbers) -> Self { 70 TextEdits { 71 line_numbers, 72 edits: vec![], 73 } 74 } 75 76 pub fn src_span_to_lsp_range(&self, location: SrcSpan) -> Range { 77 src_span_to_lsp_range(location, self.line_numbers) 78 } 79 80 pub fn lsp_range_to_src_span(&self, range: Range) -> SrcSpan { 81 lsp_range_to_src_span(range, self.line_numbers) 82 } 83 84 pub fn replace(&mut self, location: SrcSpan, new_text: String) { 85 self.edits.push(TextEdit { 86 range: src_span_to_lsp_range(location, self.line_numbers), 87 new_text, 88 }) 89 } 90 91 pub fn insert(&mut self, at: u32, new_text: String) { 92 self.replace(SrcSpan { start: at, end: at }, new_text) 93 } 94 95 pub fn delete(&mut self, location: SrcSpan) { 96 self.replace(location, "".to_string()) 97 } 98 99 fn delete_range(&mut self, range: Range) { 100 self.edits.push(TextEdit { 101 range, 102 new_text: "".into(), 103 }) 104 } 105} 106 107fn path(uri: &Url) -> Utf8PathBuf { 108 // The to_file_path method is available on these platforms 109 #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))] 110 return Utf8PathBuf::from_path_buf(uri.to_file_path().expect("URL file")) 111 .expect("Non Utf8 Path"); 112 113 #[cfg(not(any(unix, windows, target_os = "redox", target_os = "wasi")))] 114 return Utf8PathBuf::from_path_buf(uri.path().into()).expect("Non Utf8 Path"); 115} 116 117fn url_from_path(path: &str) -> Option<Url> { 118 // The targets for which `from_file_path` is defined 119 #[cfg(any( 120 unix, 121 windows, 122 target_os = "redox", 123 target_os = "wasi", 124 target_os = "hermit" 125 ))] 126 let uri = Url::from_file_path(path).ok(); 127 128 #[cfg(not(any( 129 unix, 130 windows, 131 target_os = "redox", 132 target_os = "wasi", 133 target_os = "hermit" 134 )))] 135 let uri = Url::parse(&format!("file://{path}")).ok(); 136 137 uri 138}