Skip to main content

gpui_base/input/editor/lsp/
mod.rs

1use anyhow::Result;
2use gpui::{App, Context, Hsla, SharedString, Task, Window};
3use ropey::Rope;
4use std::rc::Rc;
5
6use crate::input::{EditorMode, InputBaseState, RopeExt};
7
8mod code_actions;
9mod completions;
10mod definitions;
11mod document_colors;
12mod hover;
13mod overlay;
14mod semantic_tokens;
15
16pub use code_actions::*;
17pub use completions::*;
18pub use definitions::*;
19pub use document_colors::*;
20pub use hover::*;
21pub use overlay::*;
22pub use semantic_tokens::*;
23
24/// Host hook to show a document when following an LSP location
25/// (Go to Definition), modeled after the `window/showDocument` request.
26///
27/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_showDocument
28///
29/// Called before the built-in behavior. Return `true` if the host has shown
30/// the document (e.g. opened a docs window for a virtual/external URI);
31/// return `false` to fall through to the default handling (`external` URIs
32/// open in the browser, anything else jumps within the current document).
33pub type ShowDocumentHandler =
34    Rc<dyn Fn(&lsp_types::ShowDocumentParams, &mut Window, &mut App) -> bool>;
35
36/// LSP ServerCapabilities
37///
38/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#serverCapabilities
39pub struct Lsp {
40    /// The completion provider.
41    pub completion_provider: Option<Rc<dyn CompletionProvider>>,
42    /// The code action providers.
43    pub code_action_providers: Vec<Rc<dyn CodeActionProvider>>,
44    /// The hover provider.
45    pub hover_provider: Option<Rc<dyn HoverProvider>>,
46    /// The definition provider.
47    pub definition_provider: Option<Rc<dyn DefinitionProvider>>,
48    /// The document color provider.
49    pub document_color_provider: Option<Rc<dyn DocumentColorProvider>>,
50    /// The range semantic tokens provider.
51    pub semantic_tokens_provider: Option<Rc<dyn DocumentRangeSemanticTokensProvider>>,
52    /// Optional host hook to show documents for Go to Definition locations,
53    /// following the `window/showDocument` request (see [`ShowDocumentHandler`]).
54    ///
55    /// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_showDocument
56    pub show_document: Option<ShowDocumentHandler>,
57
58    /// Display options for the completion popover.
59    pub completion_menu: CompletionMenuOptions,
60
61    pub(crate) document_colors: Vec<(lsp_types::Range, Hsla)>,
62    /// Cached semantic tokens as absolute position ranges + theme token-type
63    /// names. Color is resolved from the name at paint time so theme switches
64    /// take effect without a refetch.
65    pub(crate) semantic_tokens: Vec<(lsp_types::Range, SharedString)>,
66    pub(crate) _hover_task: Task<Result<()>>,
67    pub(crate) _definition_task: Task<Result<()>>,
68    pub(crate) _document_color_task: Task<()>,
69    pub(crate) _semantic_tokens_task: Task<()>,
70}
71
72impl Default for Lsp {
73    fn default() -> Self {
74        Self {
75            completion_provider: None,
76            code_action_providers: vec![],
77            hover_provider: None,
78            definition_provider: None,
79            document_color_provider: None,
80            completion_menu: CompletionMenuOptions::default(),
81            semantic_tokens_provider: None,
82            show_document: None,
83            document_colors: vec![],
84            semantic_tokens: vec![],
85            _hover_task: Task::ready(Ok(())),
86            _definition_task: Task::ready(Ok(())),
87            _document_color_task: Task::ready(()),
88            _semantic_tokens_task: Task::ready(()),
89        }
90    }
91}
92
93impl Lsp {
94    /// Update the LSP when the text changes.
95    pub(crate) fn update(
96        &mut self,
97        text: &Rope,
98        window: &mut Window,
99        cx: &mut Context<InputBaseState<EditorMode>>,
100    ) {
101        self.update_document_colors(text, window, cx);
102        self.update_semantic_tokens(text, window, cx);
103    }
104
105    /// Reset all LSP states.
106    pub(crate) fn reset(&mut self) {
107        self.document_colors.clear();
108        self.semantic_tokens.clear();
109        self._hover_task = Task::ready(Ok(()));
110        self._definition_task = Task::ready(Ok(()));
111        self._document_color_task = Task::ready(());
112        self._semantic_tokens_task = Task::ready(());
113    }
114}
115
116impl InputBaseState<EditorMode> {
117    /// Apply a list of [`lsp_types::TextEdit`] to mutate the text.
118    pub fn apply_lsp_edits(
119        &mut self,
120        text_edits: &Vec<lsp_types::TextEdit>,
121        window: &mut Window,
122        cx: &mut Context<Self>,
123    ) {
124        for edit in text_edits {
125            let start = self.text.position_to_offset(&edit.range.start);
126            let end = self.text.position_to_offset(&edit.range.end);
127
128            let range_utf16 = self.range_to_utf16(&(start..end));
129            self.replace_text_in_range_silent(Some(range_utf16), &edit.new_text, window, cx);
130        }
131    }
132}