on master help sign in
Use early return in rendering completion doc
8e9c329Gokul Soumya
helix-term/src/ui/completion.rs+93−91
@@ -381,104 +381,106 @@ impl Component for Completion {
381 self.popup.render(area, surface, cx);
381 self.popup.render(area, surface, cx);
382
382
383 // if we have a selection, render a markdown popup on top/below with info
383 // if we have a selection, render a markdown popup on top/below with info
384− if let Some(option) = self.popup.contents().selection() {
384+ let option = match self.popup.contents().selection() {
385+ Some(option) => option,
386+ None => return,
387+ };
385− // need to render:
388+ // need to render:
386− // option.detail
389+ // option.detail
387− // ---
390+ // ---
388− // option.documentation
391+ // option.documentation
389−
392+
390− let (view, doc) = current!(cx.editor);
393+ let (view, doc) = current!(cx.editor);
391− let language = doc.language_name().unwrap_or("");
394+ let language = doc.language_name().unwrap_or("");
392− let text = doc.text().slice(..);
395+ let text = doc.text().slice(..);
393− let cursor_pos = doc.selection(view.id).primary().cursor(text);
396+ let cursor_pos = doc.selection(view.id).primary().cursor(text);
394− let coords = view
397+ let coords = view
395− .screen_coords_at_pos(doc, text, cursor_pos)
398+ .screen_coords_at_pos(doc, text, cursor_pos)
396− .expect("cursor must be in view");
399+ .expect("cursor must be in view");
397− let cursor_pos = coords.row as u16;
400+ let cursor_pos = coords.row as u16;
398−
401+
399− let mut markdown_doc = match &option.documentation {
402+ let mut markdown_doc = match &option.documentation {
400− Some(lsp::Documentation::String(contents))
403+ Some(lsp::Documentation::String(contents))
401− | Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
404+ | Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
402− kind: lsp::MarkupKind::PlainText,
405+ kind: lsp::MarkupKind::PlainText,
403− value: contents,
406+ value: contents,
404− })) => {
407+ })) => {
405− // TODO: convert to wrapped text
408+ // TODO: convert to wrapped text
406− Markdown::new(
409+ Markdown::new(
407− format!(
410+ format!(
408− "```{}\n{}\n```\n{}",
411+ "```{}\n{}\n```\n{}",
409− language,
412+ language,
410− option.detail.as_deref().unwrap_or_default(),
413+ option.detail.as_deref().unwrap_or_default(),
411− contents
414+ contents
412− ),
415+ ),
413− cx.editor.syn_loader.clone(),
416+ cx.editor.syn_loader.clone(),
414− )
417+ )
415− }
418+ }
416− Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
419+ Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {
417− kind: lsp::MarkupKind::Markdown,
420+ kind: lsp::MarkupKind::Markdown,
418− value: contents,
421+ value: contents,
419− })) => {
422+ })) => {
420− // TODO: set language based on doc scope
423+ // TODO: set language based on doc scope
421− if let Some(detail) = &option.detail.as_deref() {
424+ if let Some(detail) = &option.detail.as_deref() {
422− Markdown::new(
423− format!("```{}\n{}\n```\n{}", language, detail, contents),
424− cx.editor.syn_loader.clone(),
425− )
426− } else {
427− Markdown::new(contents.to_string(), cx.editor.syn_loader.clone())
428− }
429− }
430− None if option.detail.is_some() => {
431− // TODO: copied from above
432−
433− // TODO: set language based on doc scope
434 Markdown::new(
425 Markdown::new(
435− format!(
436− "```{}\n{}\n```",
437− language,
426+ format!("```{}\n{}\n```\n{}", language, detail, contents),
438− option.detail.as_deref().unwrap_or_default(),
439− ),
440 cx.editor.syn_loader.clone(),
427 cx.editor.syn_loader.clone(),
441 )
428 )
429+ } else {
430+ Markdown::new(contents.to_string(), cx.editor.syn_loader.clone())
442 }
431 }
432+ }
433+ None if option.detail.is_some() => {
434+ // TODO: copied from above
435+
436+ // TODO: set language based on doc scope
437+ Markdown::new(
438+ format!(
439+ "```{}\n{}\n```",
440+ language,
441+ option.detail.as_deref().unwrap_or_default(),
442+ ),
443+ cx.editor.syn_loader.clone(),
444+ )
445+ }
443− None => return,
446+ None => return,
444− };
447+ };
445
448
446− let (popup_x, popup_y) = self.popup.get_rel_position(area, cx);
449+ let (popup_x, popup_y) = self.popup.get_rel_position(area, cx);
447− let (popup_width, _popup_height) = self.popup.get_size();
450+ let (popup_width, _popup_height) = self.popup.get_size();
448− let mut width = area
451+ let mut width = area
449− .width
452+ .width
450− .saturating_sub(popup_x)
453+ .saturating_sub(popup_x)
451− .saturating_sub(popup_width);
454+ .saturating_sub(popup_width);
452− let area = if width > 30 {
455+ let area = if width > 30 {
453− let mut height = area.height.saturating_sub(popup_y);
456+ let mut height = area.height.saturating_sub(popup_y);
454− let x = popup_x + popup_width;
457+ let x = popup_x + popup_width;
455− let y = popup_y;
458+ let y = popup_y;
456−
459+
457− if let Some((rel_width, rel_height)) = markdown_doc.required_size((width, height)) {
460+ if let Some((rel_width, rel_height)) = markdown_doc.required_size((width, height)) {
458− width = rel_width.min(width);
461+ width = rel_width.min(width);
459− height = rel_height.min(height);
462+ height = rel_height.min(height);
460− }
463+ }
461− Rect::new(x, y, width, height)
464+ Rect::new(x, y, width, height)
465+ } else {
466+ let half = area.height / 2;
467+ let height = 15.min(half);
468+ // we want to make sure the cursor is visible (not hidden behind the documentation)
469+ let y = if cursor_pos + area.y
470+ >= (cx.editor.tree.area().height - height - 2/* statusline + commandline */)
471+ {
472+ 0
462 } else {
473 } else {
463− let half = area.height / 2;
464− let height = 15.min(half);
465− // we want to make sure the cursor is visible (not hidden behind the documentation)
466− let y = if cursor_pos + area.y
467− >= (cx.editor.tree.area().height - height - 2/* statusline + commandline */)
468− {
469− 0
470− } else {
471− // -2 to subtract command line + statusline. a bit of a hack, because of splits.
474+ // -2 to subtract command line + statusline. a bit of a hack, because of splits.
472− area.height.saturating_sub(height).saturating_sub(2)
475+ area.height.saturating_sub(height).saturating_sub(2)
473− };
474−
475− Rect::new(0, y, area.width, height)
476 };
476 };
477
477
478+ Rect::new(0, y, area.width, height)
479+ };
480+
478− // clear area
481+ // clear area
479− let background = cx.editor.theme.get("ui.popup");
482+ let background = cx.editor.theme.get("ui.popup");
480− surface.clear_with(area, background);
483+ surface.clear_with(area, background);
481− markdown_doc.render(area, surface, cx);
484+ markdown_doc.render(area, surface, cx);
482− }
483 }
485 }
484}
486}