use proposed tower lsp

This commit is contained in:
锦恢 2024-10-31 15:35:17 +08:00
parent 9f50823429
commit 2dd7f98d5f
7 changed files with 104 additions and 33 deletions

View File

@ -11,7 +11,7 @@ dirs-next = "2.0"
bincode = "1.3"
percent-encoding = "2.1.0"
log = "0.4.19"
tower-lsp = "0.20.0"
tower-lsp = { version = "0.20.0", features = ["proposed"]}
flexi_logger = "0.29.0"
ropey = "1.6.0"
tokio = { version = "1.29.1", features = ["macros", "io-std", "rt-multi-thread"] }

View File

@ -170,9 +170,9 @@ pub struct Instance {
#[serde(rename = "type")]
pub inst_type: String,
pub instparams: Option<Range>,
pub intstparams_assignment: Vec<InstParameter>,
pub intstparam_assignments: Vec<InstParameter>,
pub instports: Option<Range>,
pub intstport_assignment: Vec<InstPort>,
pub intstport_assignments: Vec<InstPort>,
pub range: Range
}
@ -334,9 +334,9 @@ impl FastHdlparam {
name: name.to_string(),
inst_type: inst_type.to_string(),
instparams: param_range,
intstparams_assignment: params_assign,
intstparam_assignments: params_assign,
instports: port_range,
intstport_assignment: ports_assign,
intstport_assignments: ports_assign,
range
};
last_module.instances.push(instance);

View File

@ -206,8 +206,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
inst_type: get_value(&tokens[i+1]),
instports: None,
instparams: None,
intstport_assignment: Vec::new(),
intstparams_assignment: Vec::new(),
intstport_assignments: Vec::new(),
intstparam_assignments: Vec::new(),
range: Range {
start: Position {
line: tokens[i-1].pos.range.start.line + 1,
@ -228,8 +228,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
inst_type: get_value(&tokens[i+2]),
instports: None,
instparams: None,
intstport_assignment: Vec::new(),
intstparams_assignment: Vec::new(),
intstport_assignments: Vec::new(),
intstparam_assignments: Vec::new(),
range: Range {
start: Position {
line: tokens[i-1].pos.range.start.line + 1,
@ -261,8 +261,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
inst_type,
instports: None,
instparams: None,
intstport_assignment: Vec::new(),
intstparams_assignment: Vec::new(),
intstport_assignments: Vec::new(),
intstparam_assignments: Vec::new(),
range: Range {
start: Position {
line: tokens[i-1].pos.range.start.line + 1,

View File

@ -33,18 +33,18 @@ pub fn hover(server: &LSPServer, params: &HoverParams) -> Option<Hover> {
return Some(hover);
}
info!("enter hover_position_port_param");
// info!("enter hover_position_port_param");
// match positional port param
if let Some(hover) = hover_position_port_param(server, &line_text, doc, pos, &language_id) {
return Some(hover);
}
info!("enter hover_module_declaration");
// info!("enter hover_module_declaration");
// match module name
if let Some(hover) = hover_module_declaration(server, &token, &language_id) {
info!("[LSPServer] in hover: get module hover");
// info!("[LSPServer] in hover: get module hover");
if hover_for_module(server, pos, doc) {
info!("[LSPServer] in hover: it is instance");
// info!("[LSPServer] in hover: it is instance");
return Some(hover);
}
}

View File

@ -14,29 +14,97 @@ pub fn inlay_hint(server: &LSPServer, params: &InlayHintParams) -> Option<Vec<In
let path_string = path.to_str().unwrap();
let visible_range = core::hdlparam::Range::from_lsp_range(&params.range);
info!("enter hints");
let fast_map = server.srcs.hdl_param.path_to_hdl_file.read().unwrap();
// 先找到 当前 所在的 hdlfile
if let Some(hdl_file) = &fast_map.get(path_string) {
info!("enter some");
let fast = &hdl_file.fast;
let mut hints = Vec::<InlayHint>::new();
// 制作例化模块的 hint
for module in &fast.content {
for instance in &module.instances {
if let Some(instport_range) = &instance.instports {
// 根据在可见视图外面的 range 就不管了
if instport_range.before(&visible_range) || instport_range.after(&visible_range) {
continue;
}
// 根据在可见视图外面的 range 就不管了
if is_visible_range(&instance.instparams, &visible_range) {
hints.extend(make_instparam_hints(params, instance));
}
if is_visible_range(&instance.instports, &visible_range) {
hints.extend(make_instport_hints(params, instance));
}
}
}
return Some(hints);
}
None
}
fn make_instport_hint(params: &InlayHintParams) {
fn is_visible_range(
target_range: &Option<core::hdlparam::Range>,
visible_range: &core::hdlparam::Range
) -> bool {
if let Some(target_range) = target_range {
if target_range.before(visible_range) || target_range.after(visible_range) {
return false;
}
return true;
}
false
}
fn make_instparam_hints(
params: &InlayHintParams,
instance: &core::hdlparam::Instance
) -> Vec<InlayHint> {
let mut hints = Vec::<InlayHint>::new();
hints
}
fn make_instport_hints(
params: &InlayHintParams,
instance: &core::hdlparam::Instance
) -> Vec<InlayHint> {
let mut hints = Vec::<InlayHint>::new();
for port_assigment in &instance.intstport_assignments {
let port_desc = MarkupContent {
kind: MarkupKind::Markdown,
value: format!("```verilog\n{:?}\n```", port_assigment.port)
};
let hint = InlayHint {
position: port_assigment.range.to_lsp_range().start,
label: InlayHintLabel::String("start".to_string()),
padding_left: Some(true),
padding_right: Some(true),
kind: Some(InlayHintKind::PARAMETER),
text_edits: None,
tooltip: Some(InlayHintTooltip::MarkupContent(port_desc)),
data: None
};
hints.push(hint);
let port_desc = MarkupContent {
kind: MarkupKind::Markdown,
value: format!("```verilog\n{:?}\n```", port_assigment.port)
};
let hint = InlayHint {
position: port_assigment.range.to_lsp_range().end,
label: InlayHintLabel::String("end".to_string()),
padding_left: Some(true),
padding_right: Some(true),
kind: Some(InlayHintKind::PARAMETER),
text_edits: None,
tooltip: Some(InlayHintTooltip::MarkupContent(port_desc)),
data: None
};
hints.push(hint);
}
hints
}

View File

@ -34,7 +34,7 @@ async fn main() {
.start()
.unwrap();
info!("launch Digital LSP");
info!("launch Digital LSP, version: 0.4.0");
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();

View File

@ -4,7 +4,6 @@ use crate::completion::keyword::*;
use flexi_logger::LoggerHandle;
#[allow(unused)]
use log::{debug, info, warn};
use notification::DidDeleteFiles;
use serde::{Deserialize, Serialize};
use std::string::ToString;
use std::sync::{Mutex, RwLock};
@ -214,12 +213,13 @@ impl LanguageServer for Backend {
completion_provider: Some(completion_provider),
definition_provider: Some(OneOf::Left(true)),
hover_provider: Some(HoverProviderCapability::Simple(true)),
// inlay_hint_provider: Some(OneOf::Left(true)),
document_symbol_provider: Some(OneOf::Left(true)),
document_highlight_provider: Some(OneOf::Left(true)),
..ServerCapabilities::default()
};
Ok(InitializeResult { server_info, capabilities })
Ok(InitializeResult::default())
}
async fn initialized(&self, _: InitializedParams) {
@ -280,13 +280,6 @@ impl LanguageServer for Backend {
Ok(self.server.hover(params))
}
async fn document_symbol(
&self,
params: DocumentSymbolParams,
) -> Result<Option<DocumentSymbolResponse>> {
Ok(self.server.document_symbol(params))
}
async fn formatting(&self, params: DocumentFormattingParams) -> Result<Option<Vec<TextEdit>>> {
Ok(self.server.formatting(params))
}
@ -298,10 +291,19 @@ impl LanguageServer for Backend {
Ok(self.server.range_formatting(params))
}
async fn document_symbol(
&self,
params: DocumentSymbolParams,
) -> Result<Option<DocumentSymbolResponse>> {
info!("enter document");
Ok(self.server.document_symbol(params))
}
async fn document_highlight(
&self,
params: DocumentHighlightParams,
) -> Result<Option<Vec<DocumentHighlight>>> {
info!("enter highlight");
Ok(self.server.document_highlight(params))
}
@ -309,6 +311,7 @@ impl LanguageServer for Backend {
&self,
params: InlayHintParams
) -> Result<Option<Vec<InlayHint>>> {
info!("enter inlay_hint");
Ok(self.server.inlay_hint(params))
}
}