mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Add function Editor::language_server_by_id
and refactor/simplify related code, also don't 'crash' in completion menu if language_server somehow disappeared
This commit is contained in:
parent
521cdec5a1
commit
39b9a4bba2
@ -665,7 +665,7 @@ pub async fn handle_language_server_message(
|
||||
|
||||
macro_rules! language_server {
|
||||
() => {
|
||||
match self.editor.language_servers.get_by_id(server_id) {
|
||||
match self.editor.language_server_by_id(server_id) {
|
||||
Some(language_server) => language_server,
|
||||
None => {
|
||||
warn!("can't find language server with id `{}`", server_id);
|
||||
|
@ -301,7 +301,7 @@ fn diag_picker(
|
||||
flat_diag.reserve(diags.len());
|
||||
|
||||
for (diag, ls) in diags {
|
||||
if let Some(ls) = cx.editor.language_servers.get_by_id(ls) {
|
||||
if let Some(ls) = cx.editor.language_server_by_id(ls) {
|
||||
flat_diag.push(PickerDiagnostic {
|
||||
url: url.clone(),
|
||||
diag,
|
||||
@ -725,7 +725,7 @@ pub fn code_action(cx: &mut Context) {
|
||||
|
||||
// always present here
|
||||
let action = action.unwrap();
|
||||
let Some(language_server) = editor.language_servers.get_by_id(action.language_server_id) else {
|
||||
let Some(language_server) = editor.language_server_by_id(action.language_server_id) else {
|
||||
editor.set_error("Language Server disappeared");
|
||||
return;
|
||||
};
|
||||
@ -772,8 +772,7 @@ pub fn execute_lsp_command(editor: &mut Editor, language_server_id: usize, cmd:
|
||||
// the command is executed on the server and communicated back
|
||||
// to the client asynchronously using workspace edits
|
||||
let future = match editor
|
||||
.language_servers
|
||||
.get_by_id(language_server_id)
|
||||
.language_server_by_id(language_server_id)
|
||||
.and_then(|language_server| language_server.command(cmd))
|
||||
{
|
||||
Some(future) => future,
|
||||
|
@ -212,6 +212,23 @@ fn completion_changes(transaction: &Transaction, trigger_offset: usize) -> Vec<C
|
||||
|
||||
let (view, doc) = current!(editor);
|
||||
|
||||
macro_rules! language_server {
|
||||
($item:expr) => {
|
||||
match editor
|
||||
.language_servers
|
||||
.get_by_id($item.language_server_id)
|
||||
{
|
||||
Some(ls) => ls,
|
||||
None => {
|
||||
editor.set_error("language server disappeared between completion request and application");
|
||||
// TODO close the completion menu somehow,
|
||||
// currently there is no trivial way to access the EditorView to close the completion menu
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
match event {
|
||||
PromptEvent::Abort => {}
|
||||
PromptEvent::Update => {
|
||||
@ -236,17 +253,11 @@ fn completion_changes(transaction: &Transaction, trigger_offset: usize) -> Vec<C
|
||||
// always present here
|
||||
let item = item.unwrap();
|
||||
|
||||
let offset_encoding = editor
|
||||
.language_servers
|
||||
.get_by_id(item.language_server_id)
|
||||
.expect("language server disappeared between completion request and application")
|
||||
.offset_encoding();
|
||||
|
||||
let transaction = item_to_transaction(
|
||||
doc,
|
||||
view.id,
|
||||
item,
|
||||
offset_encoding,
|
||||
language_server!(item).offset_encoding(),
|
||||
trigger_offset,
|
||||
true,
|
||||
replace_mode,
|
||||
@ -262,11 +273,8 @@ fn completion_changes(transaction: &Transaction, trigger_offset: usize) -> Vec<C
|
||||
// always present here
|
||||
let mut item = item.unwrap().clone();
|
||||
|
||||
let offset_encoding = editor
|
||||
.language_servers
|
||||
.get_by_id(item.language_server_id)
|
||||
.expect("language server disappeared between completion request and application")
|
||||
.offset_encoding();
|
||||
let language_server = language_server!(item);
|
||||
let offset_encoding = language_server.offset_encoding();
|
||||
|
||||
let language_server = editor
|
||||
.language_servers
|
||||
@ -401,20 +409,11 @@ pub fn ensure_item_resolved(&mut self, cx: &mut commands::Context) -> bool {
|
||||
Some(item) if !item.resolved => item.clone(),
|
||||
_ => return false,
|
||||
};
|
||||
let language_server = match cx
|
||||
.editor
|
||||
.language_servers
|
||||
.get_by_id(current_item.language_server_id)
|
||||
{
|
||||
Some(language_server) => language_server,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let Some(language_server) = cx.editor.language_server_by_id(current_item.language_server_id) else { return false; };
|
||||
|
||||
// This method should not block the compositor so we handle the response asynchronously.
|
||||
let future = match language_server.resolve_completion_item(current_item.item.clone()) {
|
||||
Some(future) => future,
|
||||
None => return false,
|
||||
};
|
||||
let Some(future) = language_server.resolve_completion_item(current_item.item.clone()) else { return false; };
|
||||
|
||||
cx.callback(
|
||||
future,
|
||||
|
@ -874,7 +874,7 @@ pub struct Editor {
|
||||
/// times during rendering and should not be set by other functions.
|
||||
pub cursor_cache: Cell<Option<Option<Position>>>,
|
||||
/// When a new completion request is sent to the server old
|
||||
/// unifinished request must be dropped. Each completion
|
||||
/// unfinished request must be dropped. Each completion
|
||||
/// request is associated with a channel that cancels
|
||||
/// when the channel is dropped. That channel is stored
|
||||
/// here. When a new completion request is sent this
|
||||
@ -1093,6 +1093,11 @@ fn set_theme_impl(&mut self, theme: Theme, preview: ThemeAction) {
|
||||
self._refresh();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn language_server_by_id(&self, language_server_id: usize) -> Option<&helix_lsp::Client> {
|
||||
self.language_servers.get_by_id(language_server_id)
|
||||
}
|
||||
|
||||
/// Refreshes the language server for a given document
|
||||
pub fn refresh_language_servers(&mut self, doc_id: DocumentId) -> Option<()> {
|
||||
self.launch_language_servers(doc_id)
|
||||
|
Loading…
Reference in New Issue
Block a user