Skip to main content

yapi_types/
autocomplete.rs

1//! pi-tui's autocomplete shapes, as extensions' providers and command
2//! argument completions exchange them; `packages/tui/src/autocomplete.ts` in
3//! pi `v1.0.0`.
4
5use serde::{Deserialize, Serialize};
6
7/// pi-tui's `AutocompleteItem`. An item without a label shows its value.
8#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(from = "ItemJson")]
10pub struct AutocompleteItem {
11    /// What the item inserts.
12    pub value: String,
13    /// What the list shows.
14    pub label: String,
15    /// Shown next to the label.
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub description: Option<String>,
18}
19
20impl AutocompleteItem {
21    /// An item that shows its value.
22    pub fn new(value: impl Into<String>) -> AutocompleteItem {
23        let value = value.into();
24        AutocompleteItem {
25            label: value.clone(),
26            value,
27            description: None,
28        }
29    }
30}
31
32#[derive(Deserialize)]
33struct ItemJson {
34    value: String,
35    label: Option<String>,
36    description: Option<String>,
37}
38
39impl From<ItemJson> for AutocompleteItem {
40    fn from(item: ItemJson) -> AutocompleteItem {
41        AutocompleteItem {
42            label: item.label.unwrap_or_else(|| item.value.clone()),
43            value: item.value,
44            description: item.description,
45        }
46    }
47}
48
49/// What completing a command's argument offers: pi awaits
50/// `getArgumentCompletions`, which may still be computing.
51#[derive(Clone, Debug, PartialEq, Eq)]
52pub enum ArgumentCompletions {
53    /// Completions; `None` or empty offers none.
54    Ready(Option<Vec<AutocompleteItem>>),
55    /// Still being computed; the editor asks again once they are ready.
56    Pending,
57}
58
59impl From<Option<Vec<AutocompleteItem>>> for ArgumentCompletions {
60    fn from(items: Option<Vec<AutocompleteItem>>) -> ArgumentCompletions {
61        ArgumentCompletions::Ready(items)
62    }
63}
64
65/// pi-tui's `AutocompleteSuggestions`.
66#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
67pub struct AutocompleteSuggestions {
68    /// The candidates, best first.
69    pub items: Vec<AutocompleteItem>,
70    /// The text they complete, which ends at the cursor.
71    pub prefix: String,
72}
73
74/// Editor lines and a cursor whose column counts UTF-16 code units: what
75/// pi-tui's autocomplete providers receive and `applyCompletion` returns.
76#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct EditorState {
79    /// The lines.
80    pub lines: Vec<String>,
81    /// The cursor's line.
82    pub cursor_line: usize,
83    /// The cursor's column.
84    pub cursor_col: usize,
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn an_item_without_a_label_shows_its_value() {
93        let item: AutocompleteItem = serde_json::from_str(r#"{"value": "a"}"#).unwrap();
94        assert_eq!(item.label, "a");
95        assert_eq!(
96            crate::json::to_string(&item).unwrap(),
97            r#"{"value":"a","label":"a"}"#
98        );
99    }
100}