grug_ls/server/
completion.rs1use lsp_server::{Connection, Message, RequestId, Response};
2use lsp_types::{CompletionItem, CompletionItemKind, CompletionParams, Documentation};
3
4use crate::server::{
5 Server,
6 document::Document,
7 utils::{get_nearest_node, get_spot_info},
8};
9
10use log::info;
11
12impl Server {
13 pub fn get_completion(
14 &self,
15 document: &Document,
16 node: &tree_sitter::Node<'_>,
17 ) -> Vec<CompletionItem> {
18 let mut items: Vec<CompletionItem> = Vec::new();
19
20 let spot_info = get_spot_info(document, node);
21
22 for var in spot_info.variables.iter() {
23 items.push(CompletionItem {
24 label: var.name.clone(),
25 detail: Some(var.format()),
26 documentation: None,
27 kind: Some(CompletionItemKind::VARIABLE),
28
29 ..Default::default()
30 });
31 }
32 for helper in document.helpers.iter() {
33 items.push(CompletionItem {
34 label: helper.name.clone(),
35 detail: Some(helper.format().clone()),
36 documentation: None,
37 kind: Some(CompletionItemKind::VARIABLE),
38
39 ..Default::default()
40 });
41 }
42
43 for (name, game_func) in self.mod_api.game_functions.iter() {
44 items.push(CompletionItem {
45 label: name.clone(),
46 detail: Some(format!("{}\n", game_func.format(name))),
47 documentation: Some(Documentation::String(game_func.description.clone())),
48 kind: Some(CompletionItemKind::FUNCTION),
49
50 ..Default::default()
51 });
52 }
53
54 if "source_file"
55 == node
56 .parent()
57 .map(|node| node.kind())
58 .unwrap_or("source_file")
59 {
60 info!("on root");
61 if let Some(entity) = self.mod_api.entities.get(&document.entity_type) {
62 info!("on entity");
63 for (func_name, func) in entity.on_functions.iter() {
64 if !document
65 .on_functions
66 .iter()
67 .any(|func| func.name == *func_name)
68 {
69 items.push(CompletionItem {
70 label: func_name.clone(),
71 detail: Some(func_name.clone()),
72 documentation: Some(Documentation::String(func.description.clone())),
73 kind: Some(CompletionItemKind::FUNCTION),
74
75 ..Default::default()
76 })
77 }
78 }
79 }
80 }
81
82 items
83 }
84
85 pub fn handle_completion(
86 &self,
87 params: CompletionParams,
88 connection: &mut Connection,
89 id: RequestId,
90 ) {
91 let uri = params.text_document_position.text_document.uri.as_str();
92 let path = &uri["file.//".len()..];
93 let document = self.document_map.get(path).unwrap();
94
95 let node = get_nearest_node(document, params.text_document_position.position);
96
97 info!("{}", node.kind());
98
99 let completion = self.get_completion(document, &node);
100
101 info!("Sending this completion: {:?}", completion);
102 let response = Response::new_ok(id, completion);
103
104 connection.sender.send(Message::Response(response)).unwrap();
105 }
106}