tinymist_query/completion/
proto.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
use ecow::EcoString;
use lsp_types::InsertTextFormat;
use serde::{Deserialize, Serialize};

use crate::StrRef;

use super::LspRange;

/// A kind of item that can be completed.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum CompletionKind {
    /// A syntactical structure.
    Syntax,
    /// A function.
    Func,
    /// A type.
    Type,
    /// A function parameter.
    Param,
    /// A field.
    Field,
    /// A constant.
    #[default]
    Constant,
    /// A reference.
    Reference,
    /// A symbol.
    Symbol(char),
    /// A variable.
    Variable,
    /// A module.
    Module,
    /// A file.
    File,
    /// A folder.
    Folder,
}

impl From<CompletionKind> for lsp_types::CompletionItemKind {
    fn from(value: CompletionKind) -> Self {
        match value {
            CompletionKind::Syntax => Self::SNIPPET,
            CompletionKind::Func => Self::FUNCTION,
            CompletionKind::Param => Self::VARIABLE,
            CompletionKind::Field => Self::FIELD,
            CompletionKind::Variable => Self::VARIABLE,
            CompletionKind::Constant => Self::CONSTANT,
            CompletionKind::Reference => Self::REFERENCE,
            CompletionKind::Symbol(_) => Self::FIELD,
            CompletionKind::Type => Self::CLASS,
            CompletionKind::Module => Self::MODULE,
            CompletionKind::File => Self::FILE,
            CompletionKind::Folder => Self::FOLDER,
        }
    }
}

impl serde::Serialize for CompletionKind {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        <Self as Into<lsp_types::CompletionItemKind>>::into(*self).serialize(serializer)
    }
}

impl<'de> serde::Deserialize<'de> for CompletionKind {
    fn deserialize<D>(deserializer: D) -> Result<CompletionKind, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let kind = lsp_types::CompletionItemKind::deserialize(deserializer)?;
        Ok(match kind {
            lsp_types::CompletionItemKind::SNIPPET => CompletionKind::Syntax,
            lsp_types::CompletionItemKind::FUNCTION => CompletionKind::Func,
            lsp_types::CompletionItemKind::VARIABLE => CompletionKind::Param,
            lsp_types::CompletionItemKind::FIELD => CompletionKind::Field,
            lsp_types::CompletionItemKind::CONSTANT => CompletionKind::Constant,
            lsp_types::CompletionItemKind::REFERENCE => CompletionKind::Reference,
            lsp_types::CompletionItemKind::CLASS => CompletionKind::Type,
            lsp_types::CompletionItemKind::MODULE => CompletionKind::Module,
            lsp_types::CompletionItemKind::FILE => CompletionKind::File,
            lsp_types::CompletionItemKind::FOLDER => CompletionKind::Folder,
            _ => CompletionKind::Variable,
        })
    }
}

/// An autocompletion option.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Completion {
    /// The kind of item this completes to.
    pub kind: CompletionKind,
    /// The label the completion is shown with.
    pub label: EcoString,
    /// The label the completion is shown with.
    pub label_details: Option<EcoString>,
    /// The label the completion is shown with.
    pub sort_text: Option<EcoString>,
    /// The composed text used for filtering.
    pub filter_text: Option<EcoString>,
    /// The completed version of the input, possibly described with snippet
    /// syntax like `${lhs} + ${rhs}`.
    ///
    /// Should default to the `label` if `None`.
    pub apply: Option<EcoString>,
    /// An optional short description, at most one sentence.
    pub detail: Option<EcoString>,
    /// An optional array of additional text edits that are applied when
    /// selecting this completion. Edits must not overlap with the main edit
    /// nor with themselves.
    pub additional_text_edits: Option<Vec<EcoTextEdit>>,
    /// An optional command to run when the completion is selected.
    pub command: Option<LspCompletionCommand>,
}

/// Represents a collection of [completion items](#CompletionItem) to be
/// presented in the editor.
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionList {
    /// This list it not complete. Further typing should result in recomputing
    /// this list.
    pub is_incomplete: bool,

    /// The completion items.
    pub items: Vec<CompletionItem>,
}

/// Additional details for a completion item label.
///
/// @since 3.17.0
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemLabelDetails {
    /// An optional string which is rendered less prominently directly after
    /// {@link CompletionItemLabel.label label}, without any spacing. Should be
    /// used for function signatures or type annotations.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub detail: Option<EcoString>,

    /// An optional string which is rendered less prominently after
    /// {@link CompletionItemLabel.detail}. Should be used for fully qualified
    /// names or file path.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<EcoString>,
}

impl From<EcoString> for CompletionItemLabelDetails {
    fn from(description: EcoString) -> Self {
        Self {
            detail: None,
            description: Some(description),
        }
    }
}

/// A textual edit applicable to a text document.
///
/// If n `EcoTextEdit`s are applied to a text document all text edits describe
/// changes to the initial document version. Execution wise text edits should
/// applied from the bottom to the top of the text document. Overlapping text
/// edits are not supported.
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EcoTextEdit {
    /// The range of the text document to be manipulated. To insert
    /// text into a document create a range where start === end.
    pub range: LspRange,
    /// The string to be inserted. For delete operations use an
    /// empty string.
    pub new_text: EcoString,
}

impl EcoTextEdit {
    pub fn new(range: LspRange, new_text: EcoString) -> EcoTextEdit {
        EcoTextEdit { range, new_text }
    }
}

/// Represents a completion item.
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItem {
    /// The label of this completion item. By default
    /// also the text that is inserted when selecting
    /// this completion.
    pub label: EcoString,

    /// Additional details for the label
    ///
    /// @since 3.17.0
    #[serde(skip_serializing_if = "Option::is_none")]
    pub label_details: Option<CompletionItemLabelDetails>,

    /// The kind of this completion item. Based of the kind
    /// an icon is chosen by the editor.
    pub kind: CompletionKind,

    /// A human-readable string with additional information
    /// about this item, like type or symbol information.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub detail: Option<EcoString>,

    /// A string that should be used when comparing this item
    /// with other items. When `falsy` the label is used
    /// as the sort text for this item.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sort_text: Option<EcoString>,

    /// A string that should be used when filtering a set of
    /// completion items. When `falsy` the label is used as the
    /// filter text for this item.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub filter_text: Option<EcoString>,

    /// A string that should be inserted into a document when selecting
    /// this completion. When `falsy` the label is used as the insert text
    /// for this item.
    ///
    /// The `insertText` is subject to interpretation by the client side.
    /// Some tools might not take the string literally. For example
    /// VS Code when code complete is requested in this example
    /// `con<cursor position>` and a completion item with an `insertText` of
    /// `console` is provided it will only insert `sole`. Therefore it is
    /// recommended to use `textEdit` instead since it avoids additional client
    /// side interpretation.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub insert_text: Option<EcoString>,

    /// The format of the insert text. The format applies to both the
    /// `insertText` property and the `newText` property of a provided
    /// `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.
    ///
    /// @since 3.16.0
    #[serde(skip_serializing_if = "Option::is_none")]
    pub insert_text_format: Option<InsertTextFormat>,

    /// An edit which is applied to a document when selecting
    /// this completion. When an edit is provided the value of
    /// insertText is ignored.
    ///
    /// Most editors support two different operation when accepting a completion
    /// item. One is to insert a completion text and the other is to replace an
    /// existing text with a completion text. Since this can usually not
    /// predetermined by a server it can report both ranges. Clients need to
    /// signal support for `InsertReplaceEdits` via the
    /// `textDocument.completion.insertReplaceSupport` client capability
    /// property.
    ///
    /// *Note 1:* The text edit's range as well as both ranges from a insert
    /// replace edit must be a [single line] and they must contain the
    /// position at which completion has been requested. *Note 2:* If an
    /// `InsertReplaceEdit` is returned the edit's insert range must be a prefix
    /// of the edit's replace range, that means it must be contained and
    /// starting at the same position.
    ///
    /// @since 3.16.0 additional type `InsertReplaceEdit`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub text_edit: Option<EcoTextEdit>,

    /// An optional array of additional text edits that are applied when
    /// selecting this completion. Edits must not overlap with the main edit
    /// nor with themselves.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub additional_text_edits: Option<Vec<EcoTextEdit>>,

    /// An optional command that is executed *after* inserting this completion.
    /// *Note* that additional modifications to the current document should
    /// be described with the additionalTextEdits-property.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub command: Option<LspCompletionCommand>,
}

/// Represents a reference to a command. Provides a title which will be used to
/// represent a command in the UI. Commands are identified by a string
/// identifier. The recommended way to handle commands is to implement
/// their execution on the server side if the client and server provides the
/// corresponding capabilities. Alternatively the tool extension code could
/// handle the command. The protocol currently doesn’t specify a set of
/// well-known commands.
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct LspCompletionCommand {
    /// The title of command.
    pub title: EcoString,
    /// The identifier of the actual command handler.
    pub command: StrRef,
}

impl From<StrRef> for LspCompletionCommand {
    fn from(command: StrRef) -> Self {
        Self {
            title: EcoString::default(),
            command,
        }
    }
}