sync_lsp/text_document/
completion.rs1use crate::workspace::execute_command::{serialize_opt_command, deserialize_opt_command};
13use crate::{Server, TypeProvider};
14use crate::connection::{Callback, Endpoint};
15use serde::{Serialize, Deserialize};
16use serde_repr::{Serialize_repr, Deserialize_repr};
17use super::{TextDocumentIdentifer, TextDocumentPositionParams, Position, TextEdit};
18
19#[derive(Serialize, Clone, Debug)]
20#[serde(rename_all = "camelCase")]
21pub(crate) struct CompletionOptions {
22 resolve_provider: bool,
23 #[serde(skip_serializing_if = "Vec::is_empty")]
24 trigger_characters: Vec<String>
25}
26
27#[derive(Deserialize, Default)]
28#[serde(default, rename_all = "camelCase")]
29pub(super) struct CompletionCapabilities {
30 dynamic_registration: bool,
31 completion_item: ItemCapabilities,
32}
33
34#[derive(Deserialize, Default)]
35#[serde(default, rename_all = "camelCase")]
36struct ItemCapabilities {
37 snippet_support: bool
38}
39
40
41#[derive(Clone, Default)]
42pub(crate) struct ResolveCompletionOptions;
43
44#[derive(Serialize)]
46#[serde(rename_all = "camelCase")]
47#[serde(bound = "")]
48pub struct CompletionList<T: TypeProvider> {
49 pub is_incomplete: bool,
51 pub items: Vec<CompletionItem<T>>,
53}
54
55#[repr(i32)]
58#[derive(Serialize_repr, Deserialize_repr, Debug)]
59pub enum CompletionItemKind {
60 Text = 1,
61 Method = 2,
62 Function = 3,
63 Constructor = 4,
64 Field = 5,
65 Variable = 6,
66 Class = 7,
67 Interface = 8,
68 Module = 9,
69 Property = 10,
70 Unit = 11,
71 Value = 12,
72 Enum = 13,
73 Keyword = 14,
74 Snippet = 15,
75 Color = 16,
76 File = 17,
77 Reference = 18
78}
79
80#[repr(i32)]
82#[derive(Serialize_repr, Deserialize_repr, Debug)]
83pub enum InsertTextFormat {
84 PlainText = 1,
86 Snippet = 2
93}
94
95#[derive(Serialize, Deserialize, Debug)]
97#[serde(rename_all = "camelCase")]
98pub struct CompletionItem<T: TypeProvider> {
99 pub label: String,
102 #[serde(default)]
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub kind: Option<CompletionItemKind>,
106 #[serde(default)]
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub detail: Option<String>,
110 #[serde(default)]
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub documentation: Option<String>,
114 #[serde(default)]
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub sort_text: Option<String>,
118 #[serde(default)]
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub filter_text: Option<String>,
122 #[serde(default)]
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub insert_text: Option<String>,
126 #[serde(default)]
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub insert_text_format: Option<InsertTextFormat>,
130 #[serde(default)]
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub text_edit: Option<TextEdit>,
134 #[serde(default)]
136 #[serde(skip_serializing_if = "Vec::is_empty")]
137 pub additional_text_edits: Vec<TextEdit>,
138 #[serde(default)]
140 #[serde(skip_serializing_if = "Option::is_none")]
141 #[serde(serialize_with = "serialize_opt_command")]
142 #[serde(deserialize_with = "deserialize_opt_command")]
143 pub command: Option<T::Command>,
144 pub data: T::CompletionData
146}
147
148impl CompletionOptions {
149 pub(crate) const METHOD: &'static str = "textDocument/completion";
150
151 pub(super) fn endpoint<T: TypeProvider>() -> Endpoint<T, CompletionOptions> {
152 Endpoint::new(Callback::request(|_, _: TextDocumentPositionParams| CompletionList::<T>::default()))
153 }
154}
155
156impl ResolveCompletionOptions {
157 pub(crate) const METHOD: &'static str = "completionItem/resolve";
158
159 pub(super) fn endpoint<T: TypeProvider>() -> Endpoint<T, ResolveCompletionOptions> {
160 Endpoint::new(Callback::request(|_, item: CompletionItem<T>| item))
161 }
162}
163
164impl<T: TypeProvider> Server<T> {
165
166 pub fn on_completion(&mut self, callback: fn(&mut Server<T>, TextDocumentIdentifer, Position) -> CompletionList<T>) {
176 self.text_document.completion.set_callback(Callback::request(move |server, params: TextDocumentPositionParams| {
177 callback(server, params.text_document, params.position)
178 }));
179 }
180
181 pub fn on_resolve_completion(&mut self, callback: fn(&mut Server<T>, CompletionItem<T>) -> CompletionItem<T>) {
190 self.text_document.resolve_completion.set_callback(Callback::request(move |server, item| {
191 callback(server, item)
192 }));
193 }
194
195 pub fn set_completion_trigger_character(&mut self, trigger_characters: Vec<String>) {
201 self.text_document.completion.options_mut().trigger_characters = trigger_characters;
202 }
203
204 pub fn snippet_support(&self) -> bool {
210 self.capabilities.text_document.completion.completion_item.snippet_support
211 }
212}
213
214impl Default for CompletionOptions {
215 fn default() -> Self {
216 CompletionOptions {
217 resolve_provider: true,
218 trigger_characters: Vec::new()
219 }
220 }
221}
222
223
224impl<T: TypeProvider> Default for CompletionList<T> {
225 fn default() -> Self {
226 CompletionList {
227 is_incomplete: false,
228 items: Vec::new()
229 }
230 }
231}