lsp_types/
completion.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    Command, Documentation, MarkupKind, PartialResultParams, TagSupport,
5    TextDocumentPositionParams, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,
6    WorkDoneProgressParams,
7};
8
9use crate::Range;
10use serde_json::Value;
11use std::fmt::Debug;
12
13/// Defines how to interpret the insert text in a completion item
14#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
15#[serde(transparent)]
16pub struct InsertTextFormat(i32);
17lsp_enum! {
18impl InsertTextFormat {
19    pub const PLAIN_TEXT: InsertTextFormat = InsertTextFormat(1);
20    pub const SNIPPET: InsertTextFormat = InsertTextFormat(2);
21}
22}
23
24/// The kind of a completion entry.
25#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
26#[serde(transparent)]
27pub struct CompletionItemKind(i32);
28lsp_enum! {
29impl CompletionItemKind {
30    pub const TEXT: CompletionItemKind = CompletionItemKind(1);
31    pub const METHOD: CompletionItemKind = CompletionItemKind(2);
32    pub const FUNCTION: CompletionItemKind = CompletionItemKind(3);
33    pub const CONSTRUCTOR: CompletionItemKind = CompletionItemKind(4);
34    pub const FIELD: CompletionItemKind = CompletionItemKind(5);
35    pub const VARIABLE: CompletionItemKind = CompletionItemKind(6);
36    pub const CLASS: CompletionItemKind = CompletionItemKind(7);
37    pub const INTERFACE: CompletionItemKind = CompletionItemKind(8);
38    pub const MODULE: CompletionItemKind = CompletionItemKind(9);
39    pub const PROPERTY: CompletionItemKind = CompletionItemKind(10);
40    pub const UNIT: CompletionItemKind = CompletionItemKind(11);
41    pub const VALUE: CompletionItemKind = CompletionItemKind(12);
42    pub const ENUM: CompletionItemKind = CompletionItemKind(13);
43    pub const KEYWORD: CompletionItemKind = CompletionItemKind(14);
44    pub const SNIPPET: CompletionItemKind = CompletionItemKind(15);
45    pub const COLOR: CompletionItemKind = CompletionItemKind(16);
46    pub const FILE: CompletionItemKind = CompletionItemKind(17);
47    pub const REFERENCE: CompletionItemKind = CompletionItemKind(18);
48    pub const FOLDER: CompletionItemKind = CompletionItemKind(19);
49    pub const ENUM_MEMBER: CompletionItemKind = CompletionItemKind(20);
50    pub const CONSTANT: CompletionItemKind = CompletionItemKind(21);
51    pub const STRUCT: CompletionItemKind = CompletionItemKind(22);
52    pub const EVENT: CompletionItemKind = CompletionItemKind(23);
53    pub const OPERATOR: CompletionItemKind = CompletionItemKind(24);
54    pub const TYPE_PARAMETER: CompletionItemKind = CompletionItemKind(25);
55}
56}
57
58#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
59#[serde(rename_all = "camelCase")]
60pub struct CompletionItemCapability {
61    /// Client supports snippets as insert text.
62    ///
63    /// A snippet can define tab stops and placeholders with `$1`, `$2`
64    /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to
65    /// the end of the snippet. Placeholders with equal identifiers are linked,
66    /// that is typing in one will update others too.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub snippet_support: Option<bool>,
69
70    /// Client supports commit characters on a completion item.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub commit_characters_support: Option<bool>,
73
74    /// Client supports the follow content formats for the documentation
75    /// property. The order describes the preferred format of the client.
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub documentation_format: Option<Vec<MarkupKind>>,
78
79    /// Client supports the deprecated property on a completion item.
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub deprecated_support: Option<bool>,
82
83    /// Client supports the preselect property on a completion item.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub preselect_support: Option<bool>,
86
87    /// Client supports the tag property on a completion item. Clients supporting
88    /// tags have to handle unknown tags gracefully. Clients especially need to
89    /// preserve unknown tags when sending a completion item back to the server in
90    /// a resolve call.
91    #[serde(
92        default,
93        skip_serializing_if = "Option::is_none",
94        deserialize_with = "TagSupport::deserialize_compat"
95    )]
96    pub tag_support: Option<TagSupport<CompletionItemTag>>,
97
98    /// Client support insert replace edit to control different behavior if a
99    /// completion item is inserted in the text or should replace text.
100    ///
101    /// @since 3.16.0
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub insert_replace_support: Option<bool>,
104
105    /// Indicates which properties a client can resolve lazily on a completion
106    /// item. Before version 3.16.0 only the predefined properties `documentation`
107    /// and `details` could be resolved lazily.
108    ///
109    /// @since 3.16.0
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub resolve_support: Option<CompletionItemCapabilityResolveSupport>,
112
113    /// The client supports the `insertTextMode` property on
114    /// a completion item to override the whitespace handling mode
115    /// as defined by the client.
116    ///
117    /// @since 3.16.0
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub insert_text_mode_support: Option<InsertTextModeSupport>,
120
121    /// The client has support for completion item label
122    /// details (see also `CompletionItemLabelDetails`).
123    ///
124    /// @since 3.17.0
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub label_details_support: Option<bool>,
127}
128
129#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
130#[serde(rename_all = "camelCase")]
131pub struct CompletionItemCapabilityResolveSupport {
132    /// The properties that a client can resolve lazily.
133    pub properties: Vec<String>,
134}
135
136#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
137#[serde(rename_all = "camelCase")]
138pub struct InsertTextModeSupport {
139    pub value_set: Vec<InsertTextMode>,
140}
141
142/// How whitespace and indentation is handled during completion
143/// item insertion.
144///
145/// @since 3.16.0
146#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
147#[serde(transparent)]
148pub struct InsertTextMode(i32);
149lsp_enum! {
150impl InsertTextMode {
151    /// The insertion or replace strings is taken as it is. If the
152    /// value is multi line the lines below the cursor will be
153    /// inserted using the indentation defined in the string value.
154    /// The client will not apply any kind of adjustments to the
155    /// string.
156    pub const AS_IS: InsertTextMode = InsertTextMode(1);
157
158    /// The editor adjusts leading whitespace of new lines so that
159    /// they match the indentation up to the cursor of the line for
160    /// which the item is accepted.
161    ///
162    /// Consider a line like this: <2tabs><cursor><3tabs>foo. Accepting a
163    /// multi line completion item is indented using 2 tabs all
164    /// following lines inserted will be indented using 2 tabs as well.
165    pub const ADJUST_INDENTATION: InsertTextMode = InsertTextMode(2);
166}
167}
168
169#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]
170#[serde(transparent)]
171pub struct CompletionItemTag(i32);
172lsp_enum! {
173impl CompletionItemTag {
174    pub const DEPRECATED: CompletionItemTag = CompletionItemTag(1);
175}
176}
177
178#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
179#[serde(rename_all = "camelCase")]
180pub struct CompletionItemKindCapability {
181    /// The completion item kind values the client supports. When this
182    /// property exists the client also guarantees that it will
183    /// handle values outside its set gracefully and falls back
184    /// to a default value when unknown.
185    ///
186    /// If this property is not present the client only supports
187    /// the completion items kinds from `Text` to `Reference` as defined in
188    /// the initial version of the protocol.
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub value_set: Option<Vec<CompletionItemKind>>,
191}
192
193#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
194#[serde(rename_all = "camelCase")]
195pub struct CompletionListCapability {
196    /// The client supports the following itemDefaults on
197    /// a completion list.
198    ///
199    /// The value lists the supported property names of the
200    /// `CompletionList.itemDefaults` object. If omitted
201    /// no properties are supported.
202    ///
203    /// @since 3.17.0
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub item_defaults: Option<Vec<String>>,
206}
207
208#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
209#[serde(rename_all = "camelCase")]
210pub struct CompletionClientCapabilities {
211    /// Whether completion supports dynamic registration.
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub dynamic_registration: Option<bool>,
214
215    /// The client supports the following `CompletionItem` specific
216    /// capabilities.
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub completion_item: Option<CompletionItemCapability>,
219
220    #[serde(skip_serializing_if = "Option::is_none")]
221    pub completion_item_kind: Option<CompletionItemKindCapability>,
222
223    /// The client supports to send additional context information for a
224    /// `textDocument/completion` request.
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub context_support: Option<bool>,
227
228    /// The client's default when the completion item doesn't provide a
229    /// `insertTextMode` property.
230    ///
231    /// @since 3.17.0
232    #[serde(skip_serializing_if = "Option::is_none")]
233    pub insert_text_mode: Option<InsertTextMode>,
234
235    /// The client supports the following `CompletionList` specific
236    /// capabilities.
237    ///
238    /// @since 3.17.0
239    #[serde(skip_serializing_if = "Option::is_none")]
240    pub completion_list: Option<CompletionListCapability>,
241}
242
243/// A special text edit to provide an insert and a replace operation.
244///
245/// @since 3.16.0
246#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
247#[serde(rename_all = "camelCase")]
248pub struct InsertReplaceEdit {
249    /// The string to be inserted.
250    pub new_text: String,
251
252    /// The range if the insert is requested
253    pub insert: Range,
254
255    /// The range if the replace is requested.
256    pub replace: Range,
257}
258
259#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
260#[serde(untagged)]
261pub enum CompletionTextEdit {
262    Edit(TextEdit),
263    InsertAndReplace(InsertReplaceEdit),
264}
265
266impl From<TextEdit> for CompletionTextEdit {
267    fn from(edit: TextEdit) -> Self {
268        CompletionTextEdit::Edit(edit)
269    }
270}
271
272impl From<InsertReplaceEdit> for CompletionTextEdit {
273    fn from(edit: InsertReplaceEdit) -> Self {
274        CompletionTextEdit::InsertAndReplace(edit)
275    }
276}
277
278/// Completion options.
279#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
280#[serde(rename_all = "camelCase")]
281pub struct CompletionOptions {
282    /// The server provides support to resolve additional information for a completion item.
283    #[serde(skip_serializing_if = "Option::is_none")]
284    pub resolve_provider: Option<bool>,
285
286    /// Most tools trigger completion request automatically without explicitly
287    /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they
288    /// do so when the user starts to type an identifier. For example if the user
289    /// types `c` in a JavaScript file code complete will automatically pop up
290    /// present `console` besides others as a completion item. Characters that
291    /// make up identifiers don't need to be listed here.
292    ///
293    /// If code complete should automatically be trigger on characters not being
294    /// valid inside an identifier (for example `.` in JavaScript) list them in
295    /// `triggerCharacters`.
296    #[serde(skip_serializing_if = "Option::is_none")]
297    pub trigger_characters: Option<Vec<String>>,
298
299    /// The list of all possible characters that commit a completion. This field
300    /// can be used if clients don't support individual commit characters per
301    /// completion item. See client capability
302    /// `completion.completionItem.commitCharactersSupport`.
303    ///
304    /// If a server provides both `allCommitCharacters` and commit characters on
305    /// an individual completion item the ones on the completion item win.
306    ///
307    /// @since 3.2.0
308    #[serde(skip_serializing_if = "Option::is_none")]
309    pub all_commit_characters: Option<Vec<String>>,
310
311    #[serde(flatten)]
312    pub work_done_progress_options: WorkDoneProgressOptions,
313
314    /// The server supports the following `CompletionItem` specific
315    /// capabilities.
316    ///
317    /// @since 3.17.0
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub completion_item: Option<CompletionOptionsCompletionItem>,
320}
321
322#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
323#[serde(rename_all = "camelCase")]
324pub struct CompletionOptionsCompletionItem {
325    /// The server has support for completion item label
326    /// details (see also `CompletionItemLabelDetails`) when receiving
327    /// a completion item in a resolve call.
328    ///
329    /// @since 3.17.0
330    #[serde(skip_serializing_if = "Option::is_none")]
331    pub label_details_support: Option<bool>,
332}
333
334#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
335pub struct CompletionRegistrationOptions {
336    #[serde(flatten)]
337    pub text_document_registration_options: TextDocumentRegistrationOptions,
338
339    #[serde(flatten)]
340    pub completion_options: CompletionOptions,
341}
342
343#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
344#[serde(untagged)]
345pub enum CompletionResponse {
346    Array(Vec<CompletionItem>),
347    List(CompletionList),
348}
349
350impl From<Vec<CompletionItem>> for CompletionResponse {
351    fn from(items: Vec<CompletionItem>) -> Self {
352        CompletionResponse::Array(items)
353    }
354}
355
356impl From<CompletionList> for CompletionResponse {
357    fn from(list: CompletionList) -> Self {
358        CompletionResponse::List(list)
359    }
360}
361
362#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
363#[serde(rename_all = "camelCase")]
364pub struct CompletionParams {
365    // This field was "mixed-in" from TextDocumentPositionParams
366    #[serde(flatten)]
367    pub text_document_position: TextDocumentPositionParams,
368
369    #[serde(flatten)]
370    pub work_done_progress_params: WorkDoneProgressParams,
371
372    #[serde(flatten)]
373    pub partial_result_params: PartialResultParams,
374
375    // CompletionParams properties:
376    #[serde(skip_serializing_if = "Option::is_none")]
377    pub context: Option<CompletionContext>,
378}
379
380#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
381#[serde(rename_all = "camelCase")]
382pub struct CompletionContext {
383    /// How the completion was triggered.
384    pub trigger_kind: CompletionTriggerKind,
385
386    /// The trigger character (a single character) that has trigger code complete.
387    /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
388    #[serde(skip_serializing_if = "Option::is_none")]
389    pub trigger_character: Option<String>,
390}
391
392/// How a completion was triggered.
393#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]
394#[serde(transparent)]
395pub struct CompletionTriggerKind(i32);
396lsp_enum! {
397impl CompletionTriggerKind {
398    pub const INVOKED: CompletionTriggerKind = CompletionTriggerKind(1);
399    pub const TRIGGER_CHARACTER: CompletionTriggerKind = CompletionTriggerKind(2);
400    pub const TRIGGER_FOR_INCOMPLETE_COMPLETIONS: CompletionTriggerKind = CompletionTriggerKind(3);
401}
402}
403
404/// Represents a collection of [completion items](#CompletionItem) to be presented
405/// in the editor.
406#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
407#[serde(rename_all = "camelCase")]
408pub struct CompletionList {
409    /// This list it not complete. Further typing should result in recomputing
410    /// this list.
411    pub is_incomplete: bool,
412
413    /// The completion items.
414    pub items: Vec<CompletionItem>,
415}
416
417#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
418#[serde(rename_all = "camelCase")]
419pub struct CompletionItem {
420    /// The label of this completion item. By default
421    /// also the text that is inserted when selecting
422    /// this completion.
423    pub label: String,
424
425    /// Additional details for the label
426    ///
427    /// @since 3.17.0
428    #[serde(skip_serializing_if = "Option::is_none")]
429    pub label_details: Option<CompletionItemLabelDetails>,
430
431    /// The kind of this completion item. Based of the kind
432    /// an icon is chosen by the editor.
433    #[serde(skip_serializing_if = "Option::is_none")]
434    pub kind: Option<CompletionItemKind>,
435
436    /// A human-readable string with additional information
437    /// about this item, like type or symbol information.
438    #[serde(skip_serializing_if = "Option::is_none")]
439    pub detail: Option<String>,
440
441    /// A human-readable string that represents a doc-comment.
442    #[serde(skip_serializing_if = "Option::is_none")]
443    pub documentation: Option<Documentation>,
444
445    /// Indicates if this item is deprecated.
446    #[serde(skip_serializing_if = "Option::is_none")]
447    pub deprecated: Option<bool>,
448
449    /// Select this item when showing.
450    #[serde(skip_serializing_if = "Option::is_none")]
451    pub preselect: Option<bool>,
452
453    /// A string that should be used when comparing this item
454    /// with other items. When `falsy` the label is used
455    /// as the sort text for this item.
456    #[serde(skip_serializing_if = "Option::is_none")]
457    pub sort_text: Option<String>,
458
459    /// A string that should be used when filtering a set of
460    /// completion items. When `falsy` the label is used as the
461    /// filter text for this item.
462    #[serde(skip_serializing_if = "Option::is_none")]
463    pub filter_text: Option<String>,
464
465    /// A string that should be inserted into a document when selecting
466    /// this completion. When `falsy` the label is used as the insert text
467    /// for this item.
468    ///
469    /// The `insertText` is subject to interpretation by the client side.
470    /// Some tools might not take the string literally. For example
471    /// VS Code when code complete is requested in this example
472    /// `con<cursor position>` and a completion item with an `insertText` of
473    /// `console` is provided it will only insert `sole`. Therefore it is
474    /// recommended to use `textEdit` instead since it avoids additional client
475    /// side interpretation.
476    #[serde(skip_serializing_if = "Option::is_none")]
477    pub insert_text: Option<String>,
478
479    /// The format of the insert text. The format applies to both the `insertText` property
480    /// and the `newText` property of a provided `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.
481    ///
482    /// @since 3.16.0
483    #[serde(skip_serializing_if = "Option::is_none")]
484    pub insert_text_format: Option<InsertTextFormat>,
485
486    /// How whitespace and indentation is handled during completion
487    /// item insertion. If not provided the client's default value depends on
488    /// the `textDocument.completion.insertTextMode` client capability.
489    ///
490    /// @since 3.16.0
491    /// @since 3.17.0 - support for `textDocument.completion.insertTextMode`
492    #[serde(skip_serializing_if = "Option::is_none")]
493    pub insert_text_mode: Option<InsertTextMode>,
494
495    /// An edit which is applied to a document when selecting
496    /// this completion. When an edit is provided the value of
497    /// insertText is ignored.
498    ///
499    /// Most editors support two different operation when accepting a completion item. One is to insert a
500
501    /// completion text and the other is to replace an existing text with a completion text. Since this can
502    /// usually not predetermined by a server it can report both ranges. Clients need to signal support for
503    /// `InsertReplaceEdits` via the `textDocument.completion.insertReplaceSupport` client capability
504    /// property.
505    ///
506    /// *Note 1:* The text edit's range as well as both ranges from a insert replace edit must be a
507    /// [single line] and they must contain the position at which completion has been requested.
508    /// *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range must be a prefix of
509    /// the edit's replace range, that means it must be contained and starting at the same position.
510    ///
511    /// @since 3.16.0 additional type `InsertReplaceEdit`
512    #[serde(skip_serializing_if = "Option::is_none")]
513    pub text_edit: Option<CompletionTextEdit>,
514
515    /// An optional array of additional text edits that are applied when
516    /// selecting this completion. Edits must not overlap with the main edit
517    /// nor with themselves.
518    #[serde(skip_serializing_if = "Option::is_none")]
519    pub additional_text_edits: Option<Vec<TextEdit>>,
520
521    /// An optional command that is executed *after* inserting this completion. *Note* that
522    /// additional modifications to the current document should be described with the
523    /// additionalTextEdits-property.
524    #[serde(skip_serializing_if = "Option::is_none")]
525    pub command: Option<Command>,
526
527    /// An optional set of characters that when pressed while this completion is
528    /// active will accept it first and then type that character. *Note* that all
529    /// commit characters should have `length=1` and that superfluous characters
530    /// will be ignored.
531    #[serde(skip_serializing_if = "Option::is_none")]
532    pub commit_characters: Option<Vec<String>>,
533
534    /// An data entry field that is preserved on a completion item between
535    /// a completion and a completion resolve request.
536    #[serde(skip_serializing_if = "Option::is_none")]
537    pub data: Option<Value>,
538
539    /// Tags for this completion item.
540    #[serde(skip_serializing_if = "Option::is_none")]
541    pub tags: Option<Vec<CompletionItemTag>>,
542}
543
544impl CompletionItem {
545    /// Create a CompletionItem with the minimum possible info (label and detail).
546    pub fn new_simple(label: String, detail: String) -> CompletionItem {
547        CompletionItem {
548            label,
549            detail: Some(detail),
550            ..Self::default()
551        }
552    }
553}
554
555/// Additional details for a completion item label.
556///
557/// @since 3.17.0
558#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
559#[serde(rename_all = "camelCase")]
560pub struct CompletionItemLabelDetails {
561    /// An optional string which is rendered less prominently directly after
562    /// {@link CompletionItemLabel.label label}, without any spacing. Should be
563    /// used for function signatures or type annotations.
564    #[serde(skip_serializing_if = "Option::is_none")]
565    pub detail: Option<String>,
566
567    /// An optional string which is rendered less prominently after
568    /// {@link CompletionItemLabel.detail}. Should be used for fully qualified
569    /// names or file path.
570    #[serde(skip_serializing_if = "Option::is_none")]
571    pub description: Option<String>,
572}
573
574#[cfg(test)]
575mod tests {
576    use super::*;
577    use crate::tests::test_deserialization;
578
579    #[test]
580    fn test_tag_support_deserialization() {
581        let mut empty = CompletionItemCapability::default();
582        empty.tag_support = None;
583
584        test_deserialization(r#"{}"#, &empty);
585        test_deserialization(r#"{"tagSupport": false}"#, &empty);
586
587        let mut t = CompletionItemCapability::default();
588        t.tag_support = Some(TagSupport { value_set: vec![] });
589        test_deserialization(r#"{"tagSupport": true}"#, &t);
590
591        let mut t = CompletionItemCapability::default();
592        t.tag_support = Some(TagSupport {
593            value_set: vec![CompletionItemTag::DEPRECATED],
594        });
595        test_deserialization(r#"{"tagSupport": {"valueSet": [1]}}"#, &t);
596    }
597
598    #[test]
599    fn test_debug_enum() {
600        assert_eq!(format!("{:?}", CompletionItemKind::TEXT), "Text");
601        assert_eq!(
602            format!("{:?}", CompletionItemKind::TYPE_PARAMETER),
603            "TypeParameter"
604        );
605    }
606
607    #[test]
608    fn test_try_from_enum() {
609        use std::convert::TryInto;
610        assert_eq!("Text".try_into(), Ok(CompletionItemKind::TEXT));
611        assert_eq!(
612            "TypeParameter".try_into(),
613            Ok(CompletionItemKind::TYPE_PARAMETER)
614        );
615    }
616}