aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/commands.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-02-25 09:07:47 +0000
committerBlaž Hrastnik2021-02-25 09:07:47 +0000
commit7162632eb739557ededaee902b23e48a577817b4 (patch)
tree22dbfc57f04e72e2f7dfbbcc2f3dee42bf00cd0a /helix-term/src/commands.rs
parent8289bd1cb0cf34d26a9f452850081799311e3f45 (diff)
lsp: Hover documentation draft.
Diffstat (limited to 'helix-term/src/commands.rs')
-rw-r--r--helix-term/src/commands.rs59
1 files changed, 58 insertions, 1 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 6b1109ba..c5c2ecf1 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -11,7 +11,7 @@ use helix_core::{
use once_cell::sync::Lazy;
use crate::compositor::Compositor;
-use crate::ui::{self, Prompt, PromptEvent};
+use crate::ui::{self, Popup, Prompt, PromptEvent};
use helix_view::{
document::Mode,
@@ -1000,6 +1000,63 @@ pub fn completion(cx: &mut Context) {
}
}
+pub fn hover(cx: &mut Context) {
+ use helix_lsp::lsp;
+
+ let doc = cx.doc();
+
+ let language_server = match doc.language_server.as_ref() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ // TODO: factor out a doc.position_identifier() that returns lsp::TextDocumentPositionIdentifier
+
+ // TODO: blocking here is not ideal, make commands async fn?
+ // not like we can process additional input meanwhile though
+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
+
+ // TODO: handle fails
+ let res = smol::block_on(language_server.text_document_hover(doc.identifier(), pos))
+ .unwrap_or_default();
+
+ if let Some(hover) = res {
+ // hover.contents / .range <- used for visualizing
+ let contents = match hover.contents {
+ lsp::HoverContents::Scalar(contents) => {
+ // markedstring(string/languagestring to be highlighted)
+ // TODO
+ unimplemented!("{:?}", contents)
+ }
+ lsp::HoverContents::Array(contents) => {
+ unimplemented!("{:?}", contents)
+ }
+ // TODO: render markdown
+ lsp::HoverContents::Markup(contents) => contents.value,
+ };
+
+ // skip if contents empty
+
+ // Popup: box frame + Box<Component> for internal content.
+ // it will use the contents.size_hint/required size to figure out sizing & positioning
+ // can also use render_buffer to render the content.
+ // render_buffer(highlights/scopes, text, surface, theme)
+ //
+ let mut popup = Popup::new(contents);
+
+ cx.callback = Some(Box::new(
+ move |compositor: &mut Compositor, editor: &mut Editor| {
+ let area = tui::layout::Rect::default(); // TODO: unused remove from cursor_position
+ let mut pos = compositor.cursor_position(area, editor);
+ pos.row += 1; // shift down by one row
+ popup.set_position(pos);
+
+ compositor.push(Box::new(popup));
+ },
+ ));
+ }
+}
+
// view movements
pub fn next_view(cx: &mut Context) {
cx.editor.tree.focus_next()