diff --git a/src/lsp.rs b/src/lsp.rs index 6b828c80..5a00ee2f 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -1,7 +1,13 @@ use crate::types::Column; -use crate::{Arch, Instruction, NameToInstructionMap, NameToRegisterMap, Register, TargetConfig}; +use crate::{ + Arch, Hoverable, Instruction, NameToInstructionMap, NameToRegisterMap, Register, TargetConfig, +}; use log::{error, info}; -use lsp_types::{InitializeParams, TextDocumentPositionParams, Url}; +use lsp_types::{ + Documentation, Hover, HoverContents, InitializeParams, TextDocumentPositionParams, Url, +}; +use std::collections::HashMap; +use std::fmt::Display; use std::fs::File; use std::io::BufRead; use std::path::PathBuf; @@ -53,6 +59,48 @@ pub fn get_word_from_file_params( } } +pub fn get_hover_resp( + word: &str, + map: &HashMap<(Arch, &str), T>, +) -> Option { + let (x86_res, x86_64_res) = search_for_hoverable(word, map); + + let hover_res: Option = match (x86_res.is_some(), x86_64_res.is_some()) { + (true, _) | (_, true) => { + let mut value = String::new(); + if let Some(x86_res) = x86_res { + value += &format!("{}", x86_res); + } + if let Some(x86_64_res) = x86_64_res { + value += &format!( + "{}{}", + if x86_res.is_some() { "\n\n" } else { "" }, + x86_64_res + ); + } + Some(Hover { + contents: HoverContents::Markup(MarkupContent { + kind: MarkupKind::Markdown, + value, + }), + range: None, + }) + } + _ => { + // don't know of this word + None + } + }; + None +} + +fn search_for_hoverable<'a: 'b, 'b, T: Hoverable>( + word: &str, + map: &'a HashMap<(Arch, &str), T>, +) -> (Option<&'b T>, Option<&'b T>) { + (None, None) +} + // Note: Have to call .cloned() on the results of .get() // here because of compiler issue regarding entangled lifetimes: https://github.com/rust-lang/rust/issues/80389 pub fn search_for_instr<'a: 'b, 'b>( diff --git a/src/types.rs b/src/types.rs index 9b0ae02b..dbad014c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,10 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{AsRefStr, Display, EnumString}; +// Define a trait for types we display on Hover Requests so we can avoid some +// duplicate code +pub trait Hoverable {} + // Instruction ------------------------------------------------------------------------------------ #[derive(Debug, Clone)] pub struct Instruction { @@ -12,6 +16,8 @@ pub struct Instruction { pub arch: Option, } +impl Hoverable for Instruction {} + impl Default for Instruction { fn default() -> Self { let name = String::new(); @@ -170,6 +176,8 @@ pub struct Register { pub url: Option, } +impl Hoverable for Register {} + impl Default for Register { fn default() -> Self { let name = String::new();