mirror of https://github.com/helix-editor/helix
Merge 1cf3d19722
into 362e97e927
commit
7ab7bfcf9e
|
@ -208,6 +208,7 @@
|
|||
| `remove_primary_selection` | Remove primary selection | normal: `` <A-,> ``, select: `` <A-,> `` |
|
||||
| `completion` | Invoke completion popup | insert: `` <C-x> `` |
|
||||
| `hover` | Show docs for item under cursor | normal: `` <space>k ``, select: `` <space>k `` |
|
||||
| `hover_dump` | Show docs for item under cursor in a new buffer | normal: `` <space>K ``, select: `` <space>K `` |
|
||||
| `toggle_comments` | Comment/uncomment selections | normal: `` <C-c> ``, `` <space>c ``, select: `` <C-c> ``, `` <space>c `` |
|
||||
| `toggle_line_comments` | Line comment/uncomment selections | normal: `` <space><A-c> ``, select: `` <space><A-c> `` |
|
||||
| `toggle_block_comments` | Block comment/uncomment selections | normal: `` <space>C ``, select: `` <space>C `` |
|
||||
|
|
|
@ -291,6 +291,7 @@ This layer is a kludge of mappings, mostly pickers.
|
|||
| `g` | Open changed file picker | `changed_file_picker` |
|
||||
| `G` | Debug (experimental) | N/A |
|
||||
| `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` |
|
||||
| `K` | Go to documentation for item under cursor in a new buffer (**LSP**) | `goto_hover` |
|
||||
| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
|
||||
| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
|
||||
| `d` | Open document diagnostics picker (**LSP**) | `diagnostics_picker` |
|
||||
|
|
|
@ -506,6 +506,7 @@ impl MappableCommand {
|
|||
remove_primary_selection, "Remove primary selection",
|
||||
completion, "Invoke completion popup",
|
||||
hover, "Show docs for item under cursor",
|
||||
goto_hover, "Show docs for item under cursor in a new buffer",
|
||||
toggle_comments, "Comment/uncomment selections",
|
||||
toggle_line_comments, "Line comment/uncomment selections",
|
||||
toggle_block_comments, "Block comment/uncomment selections",
|
||||
|
|
|
@ -15,7 +15,7 @@ use super::{align_view, push_jump, Align, Context, Editor};
|
|||
|
||||
use helix_core::{
|
||||
diagnostic::DiagnosticProvider, syntax::config::LanguageServerFeature,
|
||||
text_annotations::InlineAnnotation, Selection, Uri,
|
||||
text_annotations::InlineAnnotation, Rope, Selection, Uri,
|
||||
};
|
||||
use helix_stdx::path;
|
||||
use helix_view::{
|
||||
|
@ -32,7 +32,9 @@ use crate::{
|
|||
ui::{self, overlay::overlaid, FileLocation, Picker, Popup, PromptEvent},
|
||||
};
|
||||
|
||||
use std::{cmp::Ordering, collections::HashSet, fmt::Display, future::Future, path::Path};
|
||||
use std::{
|
||||
cmp::Ordering, collections::HashSet, fmt::Display, future::Future, path::Path, sync::Arc,
|
||||
};
|
||||
|
||||
/// Gets the first language server that is attached to a document which supports a specific feature.
|
||||
/// If there is no configured language server that supports the feature, this displays a status message.
|
||||
|
@ -1015,7 +1017,12 @@ pub fn signature_help(cx: &mut Context) {
|
|||
.trigger_signature_help(SignatureHelpInvoked::Manual, cx.editor)
|
||||
}
|
||||
|
||||
pub fn hover(cx: &mut Context) {
|
||||
enum HoverDisplay {
|
||||
Popup,
|
||||
File,
|
||||
}
|
||||
|
||||
fn hover_impl(cx: &mut Context, hover_action: HoverDisplay) {
|
||||
use ui::lsp::hover::Hover;
|
||||
|
||||
let (view, doc) = current!(cx.editor);
|
||||
|
@ -1062,15 +1069,42 @@ pub fn hover(cx: &mut Context) {
|
|||
return;
|
||||
}
|
||||
|
||||
// create new popup
|
||||
let contents = Hover::new(hovers, editor.syn_loader.clone());
|
||||
let popup = Popup::new(Hover::ID, contents).auto_close(true);
|
||||
compositor.replace_or_push(Hover::ID, popup);
|
||||
let hover = Hover::new(hovers, editor.syn_loader.clone());
|
||||
|
||||
match hover_action {
|
||||
HoverDisplay::Popup => {
|
||||
let popup = Popup::new(Hover::ID, hover).auto_close(true);
|
||||
compositor.replace_or_push(Hover::ID, popup);
|
||||
}
|
||||
HoverDisplay::File => {
|
||||
editor.new_file_from_document(
|
||||
Action::Replace,
|
||||
Document::from(
|
||||
Rope::from(hover.content_string()),
|
||||
None,
|
||||
Arc::clone(&editor.config),
|
||||
Arc::clone(&editor.syn_loader),
|
||||
),
|
||||
);
|
||||
let hover_doc = doc_mut!(editor);
|
||||
|
||||
let _ = hover_doc
|
||||
.set_language_by_language_id("markdown", &editor.syn_loader.load());
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(Callback::EditorCompositor(Box::new(call)))
|
||||
});
|
||||
}
|
||||
|
||||
pub fn hover(cx: &mut Context) {
|
||||
hover_impl(cx, HoverDisplay::Popup)
|
||||
}
|
||||
|
||||
pub fn goto_hover(cx: &mut Context) {
|
||||
hover_impl(cx, HoverDisplay::File)
|
||||
}
|
||||
|
||||
pub fn rename_symbol(cx: &mut Context) {
|
||||
fn get_prefill_from_word_boundary(editor: &Editor) -> String {
|
||||
let (view, doc) = current_ref!(editor);
|
||||
|
|
|
@ -284,6 +284,7 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
|
|||
"R" => replace_selections_with_clipboard,
|
||||
"/" => global_search,
|
||||
"k" => hover,
|
||||
"K" => goto_hover,
|
||||
"r" => rename_symbol,
|
||||
"h" => select_references_to_symbol_under_cursor,
|
||||
"c" => toggle_comments,
|
||||
|
|
|
@ -30,16 +30,15 @@ impl Hover {
|
|||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(idx, (server_name, hover))| {
|
||||
let header = (n_hovers > 1).then(|| {
|
||||
Markdown::new(
|
||||
format!("**[{}/{}] {}**", idx + 1, n_hovers, server_name),
|
||||
config_loader.clone(),
|
||||
)
|
||||
});
|
||||
let header = (n_hovers > 1)
|
||||
.then(|| format!("**[{}/{}] {}**\n", idx + 1, n_hovers, server_name))
|
||||
.map(|h| Markdown::new(h, Arc::clone(&config_loader)));
|
||||
|
||||
let body = Markdown::new(
|
||||
hover_contents_to_string(hover.contents),
|
||||
config_loader.clone(),
|
||||
Arc::clone(&config_loader),
|
||||
);
|
||||
|
||||
(header, body)
|
||||
})
|
||||
.collect();
|
||||
|
@ -54,10 +53,26 @@ impl Hover {
|
|||
self.contents.len() > 1
|
||||
}
|
||||
|
||||
fn content(&self) -> &(Option<Markdown>, Markdown) {
|
||||
fn content_markdown(&self) -> &(Option<Markdown>, Markdown) {
|
||||
&self.contents[self.active_index]
|
||||
}
|
||||
|
||||
pub fn content_string(&self) -> String {
|
||||
self.contents
|
||||
.iter()
|
||||
.map(|(header, body)| {
|
||||
let header: String = header
|
||||
.iter()
|
||||
.map(|header| header.contents.clone())
|
||||
.collect();
|
||||
|
||||
format!("{}{}", header, body.contents)
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n\n---\n\n")
|
||||
+ "\n"
|
||||
}
|
||||
|
||||
fn set_index(&mut self, index: usize) {
|
||||
assert!((0..self.contents.len()).contains(&index));
|
||||
self.active_index = index;
|
||||
|
@ -75,7 +90,7 @@ impl Component for Hover {
|
|||
let margin = Margin::all(1);
|
||||
let area = area.inner(margin);
|
||||
|
||||
let (header, contents) = self.content();
|
||||
let (header, contents) = self.content_markdown();
|
||||
|
||||
// show header and border only when more than one results
|
||||
if let Some(header) = header {
|
||||
|
@ -110,7 +125,7 @@ impl Component for Hover {
|
|||
fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {
|
||||
let max_text_width = viewport.0.saturating_sub(PADDING_HORIZONTAL).clamp(10, 120);
|
||||
|
||||
let (header, contents) = self.content();
|
||||
let (header, contents) = self.content_markdown();
|
||||
|
||||
let header_width = header
|
||||
.as_ref()
|
||||
|
|
|
@ -132,7 +132,7 @@ pub fn highlighted_code_block<'a>(
|
|||
}
|
||||
|
||||
pub struct Markdown {
|
||||
contents: String,
|
||||
pub contents: String,
|
||||
|
||||
config_loader: Arc<ArcSwap<syntax::Loader>>,
|
||||
}
|
||||
|
|
|
@ -1744,7 +1744,7 @@ impl Editor {
|
|||
id
|
||||
}
|
||||
|
||||
fn new_file_from_document(&mut self, action: Action, doc: Document) -> DocumentId {
|
||||
pub fn new_file_from_document(&mut self, action: Action, doc: Document) -> DocumentId {
|
||||
let id = self.new_document(doc);
|
||||
self.switch(id, action);
|
||||
id
|
||||
|
|
Loading…
Reference in New Issue