sync_lsp/text_document/
document_link.rs

1//! implementation of the `textDocument/documentLink` request
2//! 
3//! # Usage
4//! When a file is opened, the client may ask the server to provide links to other files via [`Server::on_document_link`].
5//! These links can then be used to navigate to related files. Additionally, the server can choose not to
6//! include the target of the link immediately. Instead [`Server::on_document_link_resolve`] can be used to
7//! compute it separately.
8
9use crate::TypeProvider;
10use crate::{Server, connection::Endpoint};
11use crate::connection::Callback;
12use serde::{Deserialize, Serialize};
13use super::{TextDocumentIdentifer, Range, DocumentUri};
14
15#[derive(Serialize, Clone)]
16#[serde(rename_all = "camelCase")]
17pub(crate) struct DocumentLinkOptions {
18    resolve_provider: bool
19}
20
21#[derive(Serialize, Clone, Default)]
22#[serde(rename_all = "camelCase")]
23pub(crate) struct DocumentLinkResolveOptions;
24
25#[derive(Deserialize)]
26#[serde(rename_all = "camelCase")]
27struct DocumentLinkParams {
28    text_document: TextDocumentIdentifer,
29}
30
31/// Specifies a link to another file.
32#[derive(Serialize, Deserialize, Debug)]
33pub struct DocumentLink {
34    /// The range inside the current document, that will redirect to the target.
35    pub range: Range,
36    /// The uri of the file to link to.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub target: Option<DocumentUri>
39}
40
41impl DocumentLinkOptions {
42    pub(crate) const METHOD: &'static str = "textDocument/documentLink";
43    
44    pub(super) fn endpoint<T: TypeProvider>() -> Endpoint<T, DocumentLinkOptions> {
45        Endpoint::new(Callback::request(|_, _: DocumentLinkParams| Vec::<DocumentLink>::new()))
46    }
47}
48
49impl DocumentLinkResolveOptions {
50    pub(crate) const METHOD: &'static str = "documentLink/resolve";
51        
52    pub(super) fn endpoint<T: TypeProvider>() -> Endpoint<T, DocumentLinkResolveOptions> {
53        Endpoint::new(Callback::request(|_, lens: DocumentLink| lens))
54    }
55}
56
57impl<T: TypeProvider> Server<T> {
58
59    /// Sets the callback that will be called to [compute document links](self).
60    /// 
61    /// # Argument
62    /// * `callback` - A callback which is called with the following parameters as soon as links is requested:
63    ///     * The server instance receiving the response.
64    ///     * The [`TextDocumentIdentifer`] of the document that has been opened.
65    ///     * `return` - A list of links to display.
66
67    pub fn on_document_link(&mut self, callback: fn(&mut Server<T>, TextDocumentIdentifer) -> Vec<DocumentLink>) {
68        self.text_document.document_link.set_callback(Callback::request(move |server, params: DocumentLinkParams| {
69            callback(server, params.text_document)
70        }));
71    }
72
73    /// Sets the callback that will be called to compute missing information on [document links](self), which were previously returned by [`Server::on_document_link`].
74    /// 
75    /// # Argument
76    /// * `callback` - A callback which is called with the following parameters as soon a link can be resolved:
77    ///     * The server instance receiving the response.
78    ///     * The [`DocumentLink`] to resolve.
79    ///     * `return` - The resolved link.
80
81    pub fn on_document_link_resolve(&mut self, callback: fn(&mut Server<T>, DocumentLink) -> DocumentLink) {
82        self.text_document.resolve_document_link.set_callback(Callback::request(move |server, params| {
83            callback(server, params)
84        }));
85    }
86}
87
88impl Default for DocumentLinkOptions {
89    fn default() -> Self {
90        Self {
91            resolve_provider: false
92        }
93    }
94}