Skip to main content

grug_ls/server/
text_sync.rs

1use std::{
2    path::{Path, PathBuf},
3    str::FromStr,
4};
5
6use lsp_types::{DidChangeTextDocumentParams, DidOpenTextDocumentParams};
7use tree_sitter::Parser;
8use vfs::FileSystem;
9
10use crate::server::{Server, document::Document};
11
12use log::error;
13use log::info;
14
15impl Server {
16    pub fn handle_did_open(
17        &mut self,
18        params: DidOpenTextDocumentParams,
19        parser: &mut Parser,
20    ) {
21        let uri = params.text_document.uri.as_str();
22        // We probably wont need to use this server on TCP
23        assert!(uri.starts_with("file://"));
24
25        let path = &uri["file.//".len()..];
26        let path = PathBuf::from_str(path).unwrap();
27        let file_name = path.file_name().unwrap().to_str().unwrap().to_string();
28
29        info!("Opened the file: {:?}", path.to_str().unwrap());
30
31        let paths: Vec<&Path> = path.ancestors().collect();
32        let piece_amt = paths.len();
33
34        for (idx, path) in paths.into_iter().rev().enumerate() {
35            let is_file = idx == piece_amt - 1;
36            let path = path.to_str().unwrap();
37
38            if is_file {
39                if self.file_system.exists(path).unwrap() {
40                    error!("Trying to create file that already exists: {}", path);
41                    break;
42                }
43
44                let mut file = self.file_system.create_file(path).unwrap();
45                file.write(path.as_bytes()).unwrap();
46
47                let document = Document::new(
48                    parser,
49                    params.text_document.text.as_bytes().to_vec(),
50                    file_name,
51                );
52                info!("New document: {:?}", document);
53                self.document_map.insert(path.to_string(), document);
54                break;
55            }
56
57            if !self.file_system.exists(path).unwrap() {
58                self.file_system.create_dir(path).unwrap();
59            }
60        }
61    }
62
63    pub fn handle_did_change(
64        &mut self,
65        params: DidChangeTextDocumentParams,
66        parser: &mut Parser,
67    ) {
68        let uri = params.text_document.uri.as_str();
69        assert!(uri.starts_with("file://"));
70
71        let path = &uri["file.//".len()..];
72        let file_name = path.split("/").last().unwrap().to_string();
73
74        info!("Updated file: {:?}", path);
75
76        let document = self.document_map.get_mut(path).unwrap();
77        *document = Document::new(
78            parser,
79            params.content_changes[0].text.as_bytes().to_vec(),
80            file_name
81        );
82    }
83}