91 lines
2.4 KiB
Rust
91 lines
2.4 KiB
Rust
use std::path::{Path, PathBuf};
|
|
|
|
use aiken_lang::{ast::Span, line_numbers::LineNumbers};
|
|
use itertools::Itertools;
|
|
use lsp_types::TextEdit;
|
|
use urlencoding::decode;
|
|
|
|
use crate::error::Error;
|
|
|
|
pub const COMPILING_PROGRESS_TOKEN: &str = "compiling-aiken";
|
|
pub const CREATE_COMPILING_PROGRESS_TOKEN: &str = "create-compiling-progress-token";
|
|
|
|
pub fn text_edit_replace(new_text: String) -> TextEdit {
|
|
TextEdit {
|
|
range: lsp_types::Range {
|
|
start: lsp_types::Position {
|
|
line: 0,
|
|
character: 0,
|
|
},
|
|
end: lsp_types::Position {
|
|
line: u32::MAX,
|
|
character: 0,
|
|
},
|
|
},
|
|
new_text,
|
|
}
|
|
}
|
|
|
|
pub fn path_to_uri(path: PathBuf) -> Result<lsp_types::Url, Error> {
|
|
let mut file: String = "file://".into();
|
|
|
|
file.push_str(&path.as_os_str().to_string_lossy());
|
|
|
|
let uri = lsp_types::Url::parse(&file)?;
|
|
|
|
Ok(uri)
|
|
}
|
|
|
|
pub fn span_to_lsp_range(location: Span, line_numbers: &LineNumbers) -> lsp_types::Range {
|
|
let start = line_numbers
|
|
.line_and_column_number(location.start)
|
|
.expect("Spans are within bounds");
|
|
let end = line_numbers
|
|
.line_and_column_number(location.end)
|
|
.expect("Spans are within bounds");
|
|
|
|
lsp_types::Range {
|
|
start: lsp_types::Position {
|
|
line: start.line as u32 - 1,
|
|
character: start.column as u32 - 1,
|
|
},
|
|
end: lsp_types::Position {
|
|
line: end.line as u32 - 1,
|
|
character: end.column as u32 - 1,
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn uri_to_module_name(uri: &url::Url, root: &Path) -> Option<String> {
|
|
let path = if cfg!(target_os = "windows") {
|
|
let mut uri_path = decode(&uri.path().replace('/', "\\"))
|
|
.expect("Invalid formatting")
|
|
.to_string();
|
|
|
|
if uri_path.starts_with('\\') {
|
|
uri_path = uri_path
|
|
.strip_prefix('\\')
|
|
.expect("Failed to remove \"\\\" prefix")
|
|
.to_string();
|
|
}
|
|
|
|
PathBuf::from(uri_path)
|
|
} else {
|
|
PathBuf::from(uri.path())
|
|
};
|
|
|
|
let components = path
|
|
.strip_prefix(root)
|
|
.ok()?
|
|
.components()
|
|
.skip(1)
|
|
.map(|c| c.as_os_str().to_string_lossy());
|
|
|
|
let module_name = Itertools::intersperse(components, "/".into())
|
|
.collect::<String>()
|
|
.strip_suffix(".ak")?
|
|
.to_string();
|
|
|
|
Some(module_name)
|
|
}
|