1use crate::selection::Position;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum CompletionKind {
6 #[default]
7 Text,
8 Keyword,
9 Variable,
10 Function,
11 Field,
12 Property,
13 Method,
14 Module,
15 Snippet,
16 Other,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct CompletionItem {
22 pub label: String,
23 pub insert_text: Option<String>,
24 pub detail: Option<String>,
25 pub sort_order: i32,
26 pub kind: CompletionKind,
27}
28
29impl Default for CompletionItem {
30 fn default() -> Self {
31 Self {
32 label: String::new(),
33 insert_text: None,
34 detail: None,
35 sort_order: 0,
36 kind: CompletionKind::Text,
37 }
38 }
39}
40
41#[derive(Debug, Clone)]
43pub struct CompletionContext {
44 pub text: String,
45 pub cursor: Position,
46 pub version: u64,
47 pub trigger: CompletionTrigger,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum CompletionTrigger {
53 Invoke,
54 TriggerCharacter(char),
55 Typing,
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn completion_item_all_fields() {
64 let item = CompletionItem {
65 label: "my_func".to_string(),
66 insert_text: Some("my_func()".to_string()),
67 detail: Some("fn my_func()".to_string()),
68 sort_order: 5,
69 kind: CompletionKind::Function,
70 };
71 assert_eq!(item.label, "my_func");
72 assert_eq!(item.insert_text.as_deref(), Some("my_func()"));
73 assert_eq!(item.detail.as_deref(), Some("fn my_func()"));
74 assert_eq!(item.sort_order, 5);
75 assert_eq!(item.kind, CompletionKind::Function);
76 }
77
78 #[test]
79 fn completion_item_default() {
80 let item = CompletionItem::default();
81 assert_eq!(item.label, "");
82 assert!(item.insert_text.is_none());
83 assert!(item.detail.is_none());
84 assert_eq!(item.sort_order, 0);
85 assert_eq!(item.kind, CompletionKind::Text);
86 }
87
88 #[test]
89 fn completion_context_holds_position_and_version() {
90 let ctx = CompletionContext {
91 text: "hello world".to_string(),
92 cursor: Position::new(0, 5),
93 version: 42,
94 trigger: CompletionTrigger::Typing,
95 };
96 assert_eq!(ctx.cursor, Position::new(0, 5));
97 assert_eq!(ctx.version, 42);
98 assert_eq!(ctx.text, "hello world");
99 assert_eq!(ctx.trigger, CompletionTrigger::Typing);
100 }
101
102 #[test]
103 fn completion_kind_variants_compare_equal() {
104 let variants = [
105 CompletionKind::Text,
106 CompletionKind::Keyword,
107 CompletionKind::Variable,
108 CompletionKind::Function,
109 CompletionKind::Field,
110 CompletionKind::Property,
111 CompletionKind::Method,
112 CompletionKind::Module,
113 CompletionKind::Snippet,
114 CompletionKind::Other,
115 ];
116 for (i, a) in variants.iter().enumerate() {
117 for (j, b) in variants.iter().enumerate() {
118 if i == j {
119 assert_eq!(a, b);
120 } else {
121 assert_ne!(a, b);
122 }
123 }
124 }
125 }
126}