editor: Refactor the LSP config.
This commit is contained in:
parent
3fe9bc8de0
commit
a942c57627
4 changed files with 41 additions and 94 deletions
|
|
@ -489,9 +489,9 @@ impl Example {
|
||||||
.default_value(default_language.1)
|
.default_value(default_language.1)
|
||||||
.placeholder("Enter your code here...");
|
.placeholder("Enter your code here...");
|
||||||
|
|
||||||
editor.set_completion_provider(Some(Rc::new(lsp_store.clone())), cx);
|
editor.lsp.completion_provider = Some(Rc::new(lsp_store.clone()));
|
||||||
editor.add_code_action_provider(Rc::new(lsp_store.clone()), cx);
|
editor.lsp.code_action_providers =
|
||||||
editor.add_code_action_provider(Rc::new(TextConvertor), cx);
|
vec![Rc::new(lsp_store.clone()), Rc::new(TextConvertor)];
|
||||||
|
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,21 @@ use crate::input::{
|
||||||
InputState, RopeExt,
|
InputState, RopeExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// LSP ServerCapabilities
|
||||||
|
///
|
||||||
|
/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#serverCapabilities
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct Lsp {
|
||||||
|
/// The completion provider.
|
||||||
|
pub completion_provider: Option<Rc<dyn CompletionProvider>>,
|
||||||
|
/// The code action providers.
|
||||||
|
pub code_action_providers: Vec<Rc<dyn CodeActionProvider>>,
|
||||||
|
/// The hover provider.
|
||||||
|
pub hover_provider: Option<Rc<dyn HoverProvider>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lsp {}
|
||||||
|
|
||||||
/// A trait for providing code completions based on the current input state and context.
|
/// A trait for providing code completions based on the current input state and context.
|
||||||
pub trait CompletionProvider {
|
pub trait CompletionProvider {
|
||||||
/// Fetches completions based on the given byte offset.
|
/// Fetches completions based on the given byte offset.
|
||||||
|
|
@ -68,6 +83,21 @@ pub trait CodeActionProvider {
|
||||||
) -> Task<Result<()>>;
|
) -> Task<Result<()>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait HoverProvider {
|
||||||
|
/// Hover provider
|
||||||
|
///
|
||||||
|
/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_hover
|
||||||
|
fn hover(
|
||||||
|
&self,
|
||||||
|
_text: &Rope,
|
||||||
|
_offset: usize,
|
||||||
|
_window: &mut Window,
|
||||||
|
_cx: &mut App,
|
||||||
|
) -> Task<Result<Option<lsp_types::Hover>>> {
|
||||||
|
Task::ready(Ok(None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl InputState {
|
impl InputState {
|
||||||
pub(crate) fn hide_context_menu(&mut self, cx: &mut Context<Self>) {
|
pub(crate) fn hide_context_menu(&mut self, cx: &mut Context<Self>) {
|
||||||
self.context_menu = None;
|
self.context_menu = None;
|
||||||
|
|
@ -125,7 +155,7 @@ impl InputState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(provider) = self.mode.completion_provider().cloned() else {
|
let Some(provider) = self.lsp.completion_provider.clone() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -220,7 +250,7 @@ impl InputState {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let providers = self.mode.code_action_providers();
|
let providers = self.lsp.code_action_providers.clone();
|
||||||
let menu = match self.context_menu.as_ref() {
|
let menu = match self.context_menu.as_ref() {
|
||||||
Some(ContextMenu::CodeAction(menu)) => Some(menu),
|
Some(ContextMenu::CodeAction(menu)) => Some(menu),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
@ -289,7 +319,7 @@ impl InputState {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let providers = self.mode.code_action_providers();
|
let providers = self.lsp.code_action_providers.clone();
|
||||||
let Some(provider) = providers
|
let Some(provider) = providers
|
||||||
.iter()
|
.iter()
|
||||||
.find(|provider| provider.id() == item.provider_id)
|
.find(|provider| provider.id() == item.provider_id)
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,9 @@ use gpui::{App, SharedString};
|
||||||
use rope::Rope;
|
use rope::Rope;
|
||||||
use tree_sitter::{InputEdit, Point};
|
use tree_sitter::{InputEdit, Point};
|
||||||
|
|
||||||
|
use super::text_wrapper::TextWrapper;
|
||||||
use crate::highlighter::DiagnosticSet;
|
use crate::highlighter::DiagnosticSet;
|
||||||
use crate::highlighter::SyntaxHighlighter;
|
use crate::highlighter::SyntaxHighlighter;
|
||||||
use crate::input::{CodeActionProvider, CompletionProvider};
|
|
||||||
|
|
||||||
use super::text_wrapper::TextWrapper;
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct TabSize {
|
pub struct TabSize {
|
||||||
|
|
@ -59,8 +57,6 @@ pub enum InputMode {
|
||||||
language: SharedString,
|
language: SharedString,
|
||||||
highlighter: Rc<RefCell<Option<SyntaxHighlighter>>>,
|
highlighter: Rc<RefCell<Option<SyntaxHighlighter>>>,
|
||||||
diagnostics: DiagnosticSet,
|
diagnostics: DiagnosticSet,
|
||||||
completion_provider: Option<Rc<dyn CompletionProvider>>,
|
|
||||||
code_action_providers: Vec<Rc<dyn CodeActionProvider>>,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,26 +237,6 @@ impl InputMode {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn completion_provider(&self) -> Option<&Rc<dyn CompletionProvider>> {
|
|
||||||
match self {
|
|
||||||
InputMode::CodeEditor {
|
|
||||||
completion_provider,
|
|
||||||
..
|
|
||||||
} => completion_provider.as_ref(),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn code_action_providers(&self) -> Vec<Rc<dyn CodeActionProvider>> {
|
|
||||||
match self {
|
|
||||||
InputMode::CodeEditor {
|
|
||||||
code_action_providers,
|
|
||||||
..
|
|
||||||
} => code_action_providers.clone(),
|
|
||||||
_ => vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ use super::{
|
||||||
use crate::input::{
|
use crate::input::{
|
||||||
popovers::{ContextMenu, DiagnosticPopover},
|
popovers::{ContextMenu, DiagnosticPopover},
|
||||||
search::{self, SearchPanel},
|
search::{self, SearchPanel},
|
||||||
Position,
|
Lsp, Position,
|
||||||
};
|
};
|
||||||
use crate::input::{RopeExt as _, Selection};
|
use crate::input::{RopeExt as _, Selection};
|
||||||
use crate::{highlighter::DiagnosticSet, input::text_wrapper::LineItem};
|
use crate::{highlighter::DiagnosticSet, input::text_wrapper::LineItem};
|
||||||
|
|
@ -299,6 +299,8 @@ pub struct InputState {
|
||||||
/// A flag to indicate if we are currently inserting a completion item.
|
/// A flag to indicate if we are currently inserting a completion item.
|
||||||
pub(super) completion_inserting: bool,
|
pub(super) completion_inserting: bool,
|
||||||
|
|
||||||
|
pub lsp: Lsp,
|
||||||
|
|
||||||
/// To remember the horizontal column (x-coordinate) of the cursor position for keep column for move up/down.
|
/// To remember the horizontal column (x-coordinate) of the cursor position for keep column for move up/down.
|
||||||
///
|
///
|
||||||
/// The first element is the x-coordinate (Pixels), preferred to use this.
|
/// The first element is the x-coordinate (Pixels), preferred to use this.
|
||||||
|
|
@ -376,6 +378,7 @@ impl InputState {
|
||||||
preferred_column: None,
|
preferred_column: None,
|
||||||
placeholder: SharedString::default(),
|
placeholder: SharedString::default(),
|
||||||
mask_pattern: MaskPattern::default(),
|
mask_pattern: MaskPattern::default(),
|
||||||
|
lsp: Lsp::default(),
|
||||||
diagnostic_popover: None,
|
diagnostic_popover: None,
|
||||||
context_menu: None,
|
context_menu: None,
|
||||||
completion_inserting: false,
|
completion_inserting: false,
|
||||||
|
|
@ -433,8 +436,6 @@ impl InputState {
|
||||||
highlighter: Rc::new(RefCell::new(None)),
|
highlighter: Rc::new(RefCell::new(None)),
|
||||||
line_number: true,
|
line_number: true,
|
||||||
diagnostics: DiagnosticSet::default(),
|
diagnostics: DiagnosticSet::default(),
|
||||||
code_action_providers: vec![],
|
|
||||||
completion_provider: None,
|
|
||||||
};
|
};
|
||||||
self.searchable = true;
|
self.searchable = true;
|
||||||
self
|
self
|
||||||
|
|
@ -446,66 +447,6 @@ impl InputState {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a code action provider for the code editor mode.
|
|
||||||
///
|
|
||||||
/// Only for `InputMode::CodeEditor`.
|
|
||||||
pub fn add_code_action_provider(
|
|
||||||
&mut self,
|
|
||||||
provider: Rc<dyn super::CodeActionProvider>,
|
|
||||||
cx: &mut Context<Self>,
|
|
||||||
) {
|
|
||||||
if let InputMode::CodeEditor {
|
|
||||||
code_action_providers,
|
|
||||||
..
|
|
||||||
} = &mut self.mode
|
|
||||||
{
|
|
||||||
code_action_providers.push(provider);
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove a code action provider for the code editor mode.
|
|
||||||
pub fn remove_code_action_provider(&mut self, id: &str, cx: &mut Context<Self>) {
|
|
||||||
if let InputMode::CodeEditor {
|
|
||||||
code_action_providers,
|
|
||||||
..
|
|
||||||
} = &mut self.mode
|
|
||||||
{
|
|
||||||
code_action_providers.retain(|p| p.id().as_str() != id);
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear all code action providers for the code editor mode.
|
|
||||||
pub fn clear_code_action_providers(&mut self, cx: &mut Context<Self>) {
|
|
||||||
if let InputMode::CodeEditor {
|
|
||||||
code_action_providers,
|
|
||||||
..
|
|
||||||
} = &mut self.mode
|
|
||||||
{
|
|
||||||
code_action_providers.clear();
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the completion provider for the code editor mode.
|
|
||||||
///
|
|
||||||
/// Only for `InputMode::CodeEditor`.
|
|
||||||
pub fn set_completion_provider(
|
|
||||||
&mut self,
|
|
||||||
provider: Option<Rc<dyn super::CompletionProvider>>,
|
|
||||||
cx: &mut Context<Self>,
|
|
||||||
) {
|
|
||||||
if let InputMode::CodeEditor {
|
|
||||||
completion_provider,
|
|
||||||
..
|
|
||||||
} = &mut self.mode
|
|
||||||
{
|
|
||||||
*completion_provider = provider;
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set placeholder
|
/// Set placeholder
|
||||||
pub fn placeholder(mut self, placeholder: impl Into<SharedString>) -> Self {
|
pub fn placeholder(mut self, placeholder: impl Into<SharedString>) -> Self {
|
||||||
self.placeholder = placeholder.into();
|
self.placeholder = placeholder.into();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue