save
This commit is contained in:
parent
3a64906029
commit
302dafbc05
4
config.toml
Normal file
4
config.toml
Normal file
@ -0,0 +1,4 @@
|
||||
[build]
|
||||
jobs = 16 # 并行构建任务的数量,默认等于 CPU 的核心数
|
||||
rustc = "rustc" # rust 编译器
|
||||
target-dir = "target" # 存放编译输出结果的目录
|
@ -1,2 +1,2 @@
|
||||
edition = "2018"
|
||||
max_width = 100
|
||||
max_width = 76
|
||||
|
@ -69,7 +69,9 @@ impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (DoFastApiRequestParams, )
|
||||
fn invoke(&self, _server: &'a Arc<Backend>, _params: (DoFastApiRequestParams, )) -> Self::Future {
|
||||
let request_param = _params.0;
|
||||
let path = request_param.path;
|
||||
future::ready(do_fast(path))
|
||||
let fut = future::ready(do_fast(path));
|
||||
info!("get future: {:?}", fut);
|
||||
fut
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +121,7 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
|
||||
|
||||
if let Some(syntax_tree) = parse_result {
|
||||
if let Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
|
||||
info!("after parse {}, get hdlparam {:?}", path, hdlparam);
|
||||
info!("after parse {}, get hdlparam", path);
|
||||
return Ok(hdlparam);
|
||||
}
|
||||
}
|
||||
|
125
src/server.rs
125
src/server.rs
@ -4,18 +4,12 @@ use flexi_logger::LoggerHandle;
|
||||
#[allow(unused)]
|
||||
use log::{debug, info, warn};
|
||||
use once_cell::sync::OnceCell;
|
||||
use path_clean::PathClean;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env::current_dir;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::string::ToString;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use tower_lsp::jsonrpc::{Error, ErrorCode, Result};
|
||||
use tower_lsp::jsonrpc::Result;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use tower_lsp::{Client, LanguageServer};
|
||||
use which::which;
|
||||
|
||||
pub static GLOBAL_BACKEND: OnceCell<Arc<Backend>> = OnceCell::new();
|
||||
|
||||
@ -25,6 +19,7 @@ pub struct LSPServer {
|
||||
pub sys_tasks: Vec<CompletionItem>,
|
||||
pub directives: Vec<CompletionItem>,
|
||||
pub conf: RwLock<ProjectConfig>,
|
||||
#[allow(unused)]
|
||||
pub log_handle: Mutex<Option<LoggerHandle>>,
|
||||
}
|
||||
|
||||
@ -171,95 +166,19 @@ impl Default for VeribleFormat {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_config(root_uri: Option<Url>) -> anyhow::Result<ProjectConfig> {
|
||||
let path = root_uri
|
||||
.ok_or_else(|| anyhow::anyhow!("couldn't resolve workdir path"))?
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow::anyhow!("couldn't resolve workdir path"))?;
|
||||
let mut config: Option<PathBuf> = None;
|
||||
for dir in path.ancestors() {
|
||||
let config_path = dir.join("veridian.yaml");
|
||||
if config_path.exists() {
|
||||
info!("found config: veridian.yaml");
|
||||
config = Some(config_path);
|
||||
break;
|
||||
}
|
||||
let config_path = dir.join("veridian.yml");
|
||||
if config_path.exists() {
|
||||
info!("found config: veridian.yml");
|
||||
config = Some(config_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mut contents = String::new();
|
||||
File::open(config.ok_or_else(|| anyhow::anyhow!("unable to read config file"))?)?
|
||||
.read_to_string(&mut contents)?;
|
||||
info!("reading config file");
|
||||
Ok(serde_yaml::from_str(&contents)?)
|
||||
}
|
||||
|
||||
// convert string path to absolute path
|
||||
fn absolute_path(path_str: &str) -> Option<PathBuf> {
|
||||
let path = PathBuf::from(path_str);
|
||||
if !path.exists() {
|
||||
return None;
|
||||
}
|
||||
if !path.has_root() {
|
||||
Some(current_dir().unwrap().join(path).clean())
|
||||
} else {
|
||||
Some(path)
|
||||
}
|
||||
}
|
||||
|
||||
#[tower_lsp::async_trait]
|
||||
impl LanguageServer for Backend {
|
||||
async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> {
|
||||
// grab include dirs and source dirs from config, and convert to abs path
|
||||
let mut inc_dirs = self.server.srcs.include_dirs.write().unwrap();
|
||||
let mut src_dirs = self.server.srcs.source_dirs.write().unwrap();
|
||||
match read_config(params.root_uri) {
|
||||
Ok(conf) => {
|
||||
inc_dirs.extend(conf.include_dirs.iter().filter_map(|x| absolute_path(x)));
|
||||
src_dirs.extend(conf.source_dirs.iter().filter_map(|x| absolute_path(x)));
|
||||
let mut log_handle = self.server.log_handle.lock().unwrap();
|
||||
let log_handle = log_handle.as_mut();
|
||||
if let Some(handle) = log_handle {
|
||||
handle
|
||||
.parse_and_push_temp_spec(&conf.log_level.to_string())
|
||||
.map_err(|e| Error {
|
||||
code: ErrorCode::InvalidParams,
|
||||
message: e.to_string().into(),
|
||||
data: None,
|
||||
})?;
|
||||
}
|
||||
*self.server.conf.write().unwrap() = conf;
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("found errors in config file: {:#?}", e);
|
||||
}
|
||||
}
|
||||
let mut conf = self.server.conf.write().unwrap();
|
||||
conf.verible.syntax.enabled = which(&conf.verible.syntax.path).is_ok();
|
||||
|
||||
if conf.verilator.syntax.enabled {
|
||||
info!("enabled linting with verilator")
|
||||
} else if conf.verible.syntax.enabled {
|
||||
info!("enabled linting with verible-verilog-syntax")
|
||||
}
|
||||
conf.verible.format.enabled = which(&conf.verible.format.path).is_ok();
|
||||
if conf.verible.format.enabled {
|
||||
info!("enabled formatting with verible-verilog-format");
|
||||
} else {
|
||||
info!("formatting unavailable");
|
||||
}
|
||||
drop(inc_dirs);
|
||||
drop(src_dirs);
|
||||
// parse all source files found from walking source dirs and include dirs
|
||||
async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
|
||||
self.server.srcs.init();
|
||||
Ok(InitializeResult {
|
||||
server_info: None,
|
||||
capabilities: ServerCapabilities {
|
||||
text_document_sync: Some(TextDocumentSyncCapability::Options(
|
||||
|
||||
// 申明 LSP 的基本信息和提供的能力
|
||||
let server_info = Some(ServerInfo {
|
||||
name: "Digital IDE 专用 LSP 后端服务器".to_string(),
|
||||
version: Some("0.4.0".to_string())
|
||||
});
|
||||
|
||||
let text_document_sync = TextDocumentSyncCapability::Options(
|
||||
TextDocumentSyncOptions {
|
||||
open_close: Some(true),
|
||||
change: Some(TextDocumentSyncKind::INCREMENTAL),
|
||||
@ -268,9 +187,10 @@ impl LanguageServer for Backend {
|
||||
save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions {
|
||||
include_text: None,
|
||||
})),
|
||||
},
|
||||
)),
|
||||
completion_provider: Some(CompletionOptions {
|
||||
}
|
||||
);
|
||||
|
||||
let completion_provider = CompletionOptions {
|
||||
resolve_provider: Some(false),
|
||||
trigger_characters: Some(vec![
|
||||
".".to_string(),
|
||||
@ -281,18 +201,21 @@ impl LanguageServer for Backend {
|
||||
work_done_progress: None,
|
||||
},
|
||||
all_commit_characters: None,
|
||||
// TODO: check if corect
|
||||
// TODO: 检查这里的选项
|
||||
completion_item: None,
|
||||
}),
|
||||
};
|
||||
|
||||
let capabilities = ServerCapabilities {
|
||||
text_document_sync: Some(text_document_sync),
|
||||
completion_provider: Some(completion_provider),
|
||||
definition_provider: Some(OneOf::Left(true)),
|
||||
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
||||
document_symbol_provider: Some(OneOf::Left(true)),
|
||||
document_formatting_provider: Some(OneOf::Left(conf.verible.format.enabled)),
|
||||
document_range_formatting_provider: Some(OneOf::Left(conf.verible.format.enabled)),
|
||||
document_highlight_provider: Some(OneOf::Left(true)),
|
||||
..ServerCapabilities::default()
|
||||
},
|
||||
})
|
||||
};
|
||||
|
||||
Ok(InitializeResult { server_info, capabilities })
|
||||
}
|
||||
|
||||
async fn initialized(&self, _: InitializedParams) {
|
||||
|
@ -247,7 +247,6 @@ impl Sources {
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
||||
info!("finish parse {:?}", uri.to_string());
|
||||
|
||||
// 计算 fast
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 90e9d4cb3ba4e3a55a9b3fcd0fb83389a376ec35
|
||||
Subproject commit 4a73dc87f7ab8dfdc0b08de89a04d9e39fd26895
|
Loading…
x
Reference in New Issue
Block a user