aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r--helix-term/src/ui/completion.rs85
-rw-r--r--helix-term/src/ui/editor.rs17
-rw-r--r--helix-term/src/ui/mod.rs21
-rw-r--r--helix-term/src/ui/statusline.rs12
4 files changed, 62 insertions, 73 deletions
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index c5c40580..859403a7 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -15,7 +15,7 @@ use helix_view::{graphics::Rect, Document, Editor};
use crate::commands;
use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent};
-use helix_lsp::{lsp, util};
+use helix_lsp::{lsp, util, OffsetEncoding};
impl menu::Item for CompletionItem {
type Data = ();
@@ -38,6 +38,7 @@ impl menu::Item for CompletionItem {
|| self.item.tags.as_ref().map_or(false, |tags| {
tags.contains(&lsp::CompletionItemTag::DEPRECATED)
});
+
menu::Row::new(vec![
menu::Cell::from(Span::styled(
self.item.label.as_str(),
@@ -79,19 +80,16 @@ impl menu::Item for CompletionItem {
}
None => "",
}),
- // self.detail.as_deref().unwrap_or("")
- // self.label_details
- // .as_ref()
- // .or(self.detail())
- // .as_str(),
])
}
}
#[derive(Debug, PartialEq, Default, Clone)]
-struct CompletionItem {
- item: lsp::CompletionItem,
- resolved: bool,
+pub struct CompletionItem {
+ pub item: lsp::CompletionItem,
+ pub language_server_id: usize,
+ pub offset_encoding: OffsetEncoding,
+ pub resolved: bool,
}
/// Wraps a Menu.
@@ -109,21 +107,13 @@ impl Completion {
pub fn new(
editor: &Editor,
savepoint: Arc<SavePoint>,
- mut items: Vec<lsp::CompletionItem>,
- offset_encoding: helix_lsp::OffsetEncoding,
+ mut items: Vec<CompletionItem>,
start_offset: usize,
trigger_offset: usize,
) -> Self {
let replace_mode = editor.config().completion_replace;
// Sort completion items according to their preselect status (given by the LSP server)
- items.sort_by_key(|item| !item.preselect.unwrap_or(false));
- let items = items
- .into_iter()
- .map(|item| CompletionItem {
- item,
- resolved: false,
- })
- .collect();
+ items.sort_by_key(|item| !item.item.preselect.unwrap_or(false));
// Then create the menu
let menu = Menu::new(items, (), move |editor: &mut Editor, item, event| {
@@ -131,7 +121,6 @@ impl Completion {
doc: &Document,
view_id: ViewId,
item: &CompletionItem,
- offset_encoding: helix_lsp::OffsetEncoding,
trigger_offset: usize,
include_placeholder: bool,
replace_mode: bool,
@@ -154,6 +143,8 @@ impl Completion {
}
};
+ let offset_encoding = item.offset_encoding;
+
let Some(range) = util::lsp_range_to_range(doc.text(), edit.range, offset_encoding) else{
return Transaction::new(doc.text());
};
@@ -247,15 +238,8 @@ impl Completion {
// always present here
let item = item.unwrap();
- let transaction = item_to_transaction(
- doc,
- view.id,
- item,
- offset_encoding,
- trigger_offset,
- true,
- replace_mode,
- );
+ let transaction =
+ item_to_transaction(doc, view.id, item, trigger_offset, true, replace_mode);
doc.apply_temporary(&transaction, view.id);
}
PromptEvent::Validate => {
@@ -267,10 +251,15 @@ impl Completion {
// always present here
let mut item = item.unwrap().clone();
+ let language_server = editor
+ .language_servers
+ .get_by_id(item.language_server_id)
+ .unwrap();
+
// resolve item if not yet resolved
if !item.resolved {
if let Some(resolved) =
- Self::resolve_completion_item(doc, item.item.clone())
+ Self::resolve_completion_item(language_server, item.item.clone())
{
item.item = resolved;
}
@@ -281,7 +270,6 @@ impl Completion {
doc,
view.id,
&item,
- offset_encoding,
trigger_offset,
false,
replace_mode,
@@ -299,7 +287,7 @@ impl Completion {
let transaction = util::generate_transaction_from_edits(
doc.text(),
additional_edits,
- offset_encoding, // TODO: should probably transcode in Client
+ item.offset_encoding, // TODO: should probably transcode in Client
);
doc.apply(&transaction, view.id);
}
@@ -323,10 +311,17 @@ impl Completion {
}
fn resolve_completion_item(
- doc: &Document,
+ language_server: &helix_lsp::Client,
completion_item: lsp::CompletionItem,
) -> Option<lsp::CompletionItem> {
- let language_server = doc.language_server()?;
+ let completion_resolve_provider = language_server
+ .capabilities()
+ .completion_provider
+ .as_ref()?
+ .resolve_provider;
+ if completion_resolve_provider != Some(true) {
+ return None;
+ }
let future = language_server.resolve_completion_item(completion_item)?;
let response = helix_lsp::block_on(future);
@@ -397,8 +392,11 @@ impl Completion {
Some(item) if !item.resolved => item.clone(),
_ => return false,
};
-
- let language_server = match doc!(cx.editor).language_server() {
+ let language_server = match cx
+ .editor
+ .language_servers
+ .get_by_id(current_item.language_server_id)
+ {
Some(language_server) => language_server,
None => return false,
};
@@ -422,13 +420,14 @@ impl Completion {
.unwrap()
.completion
{
- completion.replace_item(
- current_item,
- CompletionItem {
- item: resolved_item,
- resolved: true,
- },
- );
+ let resolved_item = CompletionItem {
+ item: resolved_item,
+ language_server_id: current_item.language_server_id,
+ offset_encoding: current_item.offset_encoding,
+ resolved: true,
+ };
+
+ completion.replace_item(current_item, resolved_item);
}
},
);
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index f0989fa8..43b5d1af 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -33,7 +33,7 @@ use std::{mem::take, num::NonZeroUsize, path::PathBuf, rc::Rc, sync::Arc};
use tui::{buffer::Buffer as Surface, text::Span};
-use super::statusline;
+use super::{completion::CompletionItem, statusline};
use super::{document::LineDecoration, lsp::SignatureHelp};
pub struct EditorView {
@@ -650,7 +650,7 @@ impl EditorView {
.primary()
.cursor(doc.text().slice(..));
- let diagnostics = doc.diagnostics().iter().filter(|diagnostic| {
+ let diagnostics = doc.shown_diagnostics().filter(|diagnostic| {
diagnostic.range.start <= cursor && diagnostic.range.end >= cursor
});
@@ -953,20 +953,13 @@ impl EditorView {
&mut self,
editor: &mut Editor,
savepoint: Arc<SavePoint>,
- items: Vec<helix_lsp::lsp::CompletionItem>,
- offset_encoding: helix_lsp::OffsetEncoding,
+ items: Vec<CompletionItem>,
start_offset: usize,
trigger_offset: usize,
size: Rect,
) -> Option<Rect> {
- let mut completion = Completion::new(
- editor,
- savepoint,
- items,
- offset_encoding,
- start_offset,
- trigger_offset,
- );
+ let mut completion =
+ Completion::new(editor, savepoint, items, start_offset, trigger_offset);
if completion.is_empty() {
// skip if we got no completion results
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index 3e9a14b0..118836c0 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -17,7 +17,7 @@ mod text;
use crate::compositor::{Component, Compositor};
use crate::filter_picker_entry;
use crate::job::{self, Callback};
-pub use completion::Completion;
+pub use completion::{Completion, CompletionItem};
pub use editor::EditorView;
pub use markdown::Markdown;
pub use menu::Menu;
@@ -238,6 +238,7 @@ pub mod completers {
use crate::ui::prompt::Completion;
use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
use fuzzy_matcher::FuzzyMatcher;
+ use helix_core::syntax::LanguageServerFeature;
use helix_view::document::SCRATCH_BUFFER_NAME;
use helix_view::theme;
use helix_view::{editor::Config, Editor};
@@ -393,17 +394,13 @@ pub mod completers {
pub fn lsp_workspace_command(editor: &Editor, input: &str) -> Vec<Completion> {
let matcher = Matcher::default();
- let (_, doc) = current_ref!(editor);
-
- let language_server = match doc.language_server() {
- Some(language_server) => language_server,
- None => {
- return vec![];
- }
- };
-
- let options = match &language_server.capabilities().execute_command_provider {
- Some(options) => options,
+ let language_servers =
+ doc!(editor).language_servers_with_feature(LanguageServerFeature::WorkspaceCommand);
+ let options = match language_servers
+ .into_iter()
+ .find_map(|ls| ls.capabilities().execute_command_provider.as_ref())
+ {
+ Some(id_options) => id_options,
None => {
return vec![];
}
diff --git a/helix-term/src/ui/statusline.rs b/helix-term/src/ui/statusline.rs
index 88786351..b10e8076 100644
--- a/helix-term/src/ui/statusline.rs
+++ b/helix-term/src/ui/statusline.rs
@@ -197,15 +197,16 @@ where
);
}
+// TODO think about handling multiple language servers
fn render_lsp_spinner<F>(context: &mut RenderContext, write: F)
where
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
{
+ let language_servers = context.doc.language_servers();
write(
context,
- context
- .doc
- .language_server()
+ language_servers
+ .first()
.and_then(|srv| {
context
.spinners
@@ -225,8 +226,7 @@ where
{
let (warnings, errors) = context
.doc
- .diagnostics()
- .iter()
+ .shown_diagnostics()
.fold((0, 0), |mut counts, diag| {
use helix_core::diagnostic::Severity;
match diag.severity {
@@ -266,7 +266,7 @@ where
.diagnostics
.values()
.flatten()
- .fold((0, 0), |mut counts, diag| {
+ .fold((0, 0), |mut counts, (diag, _, _)| {
match diag.severity {
Some(DiagnosticSeverity::WARNING) => counts.0 += 1,
Some(DiagnosticSeverity::ERROR) | None => counts.1 += 1,