2024-02-15 13:56:31 -08:00
|
|
|
//! The copilot lsp server for ghost text.
|
2024-11-20 15:19:25 +13:00
|
|
|
#![allow(dead_code)]
|
2024-02-15 13:56:31 -08:00
|
|
|
|
|
|
|
pub mod cache;
|
|
|
|
pub mod types;
|
|
|
|
|
|
|
|
use std::{
|
|
|
|
borrow::Cow,
|
|
|
|
fmt::Debug,
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
};
|
|
|
|
|
2024-06-27 15:43:49 -07:00
|
|
|
use dashmap::DashMap;
|
2024-02-15 13:56:31 -08:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use tower_lsp::{
|
2025-06-26 17:02:54 -05:00
|
|
|
LanguageServer,
|
2024-02-15 13:56:31 -08:00
|
|
|
jsonrpc::{Error, Result},
|
|
|
|
lsp_types::{
|
2024-06-27 15:43:49 -07:00
|
|
|
CreateFilesParams, DeleteFilesParams, Diagnostic, DidChangeConfigurationParams, DidChangeTextDocumentParams,
|
2024-02-15 13:56:31 -08:00
|
|
|
DidChangeWatchedFilesParams, DidChangeWorkspaceFoldersParams, DidCloseTextDocumentParams,
|
2024-06-27 15:43:49 -07:00
|
|
|
DidOpenTextDocumentParams, DidSaveTextDocumentParams, InitializeParams, InitializeResult, InitializedParams,
|
|
|
|
MessageType, OneOf, RenameFilesParams, ServerCapabilities, TextDocumentItem, TextDocumentSyncCapability,
|
|
|
|
TextDocumentSyncKind, TextDocumentSyncOptions, WorkspaceFolder, WorkspaceFoldersServerCapabilities,
|
|
|
|
WorkspaceServerCapabilities,
|
2024-02-15 13:56:31 -08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2024-02-19 12:33:16 -08:00
|
|
|
use crate::lsp::{
|
2024-02-15 13:56:31 -08:00
|
|
|
backend::Backend as _,
|
2024-12-03 16:39:51 +13:00
|
|
|
copilot::{
|
|
|
|
cache::CopilotCache,
|
|
|
|
types::{
|
|
|
|
CopilotAcceptCompletionParams, CopilotCompletionResponse, CopilotCompletionTelemetry, CopilotEditorInfo,
|
|
|
|
CopilotLspCompletionParams, CopilotRejectCompletionParams, DocParams,
|
|
|
|
},
|
2024-04-15 17:18:32 -07:00
|
|
|
},
|
2024-02-15 13:56:31 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
|
|
pub struct Success {
|
|
|
|
success: bool,
|
|
|
|
}
|
|
|
|
impl Success {
|
|
|
|
pub fn new(success: bool) -> Self {
|
|
|
|
Self { success }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
#[derive(Clone)]
|
2024-02-15 13:56:31 -08:00
|
|
|
pub struct Backend {
|
|
|
|
/// The client is used to send notifications and requests to the client.
|
|
|
|
pub client: tower_lsp::Client,
|
2024-02-19 12:33:16 -08:00
|
|
|
/// The file system client to use.
|
2024-04-15 17:18:32 -07:00
|
|
|
pub fs: Arc<crate::fs::FileManager>,
|
2024-03-11 17:50:31 -07:00
|
|
|
/// The workspace folders.
|
2024-06-27 15:43:49 -07:00
|
|
|
pub workspace_folders: DashMap<String, WorkspaceFolder>,
|
2024-02-15 13:56:31 -08:00
|
|
|
/// Current code.
|
2024-06-27 15:43:49 -07:00
|
|
|
pub code_map: DashMap<String, Vec<u8>>,
|
2024-03-12 13:37:47 -07:00
|
|
|
/// The Zoo API client.
|
|
|
|
pub zoo_client: kittycad::Client,
|
2024-02-15 13:56:31 -08:00
|
|
|
/// The editor info is used to store information about the editor.
|
|
|
|
pub editor_info: Arc<RwLock<CopilotEditorInfo>>,
|
|
|
|
/// The cache is used to store the results of previous requests.
|
2024-03-12 23:57:43 -07:00
|
|
|
pub cache: Arc<cache::CopilotCache>,
|
|
|
|
/// Storage so we can send telemetry data back out.
|
2024-06-27 15:43:49 -07:00
|
|
|
pub telemetry: DashMap<uuid::Uuid, CopilotCompletionTelemetry>,
|
2024-06-26 14:51:47 -07:00
|
|
|
/// Diagnostics.
|
2024-06-27 15:43:49 -07:00
|
|
|
pub diagnostics_map: DashMap<String, Vec<Diagnostic>>,
|
2024-04-15 17:18:32 -07:00
|
|
|
|
|
|
|
pub is_initialized: Arc<tokio::sync::RwLock<bool>>,
|
2024-06-30 18:26:16 -07:00
|
|
|
|
|
|
|
/// Are we running in dev mode.
|
|
|
|
pub dev_mode: bool,
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Implement the shared backend trait for the language server.
|
|
|
|
#[async_trait::async_trait]
|
2024-02-19 12:33:16 -08:00
|
|
|
impl crate::lsp::backend::Backend for Backend {
|
2024-06-26 14:51:47 -07:00
|
|
|
fn client(&self) -> &tower_lsp::Client {
|
|
|
|
&self.client
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
|
2024-06-26 14:51:47 -07:00
|
|
|
fn fs(&self) -> &Arc<crate::fs::FileManager> {
|
|
|
|
&self.fs
|
2024-02-19 12:33:16 -08:00
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
async fn is_initialized(&self) -> bool {
|
|
|
|
*self.is_initialized.read().await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn set_is_initialized(&self, is_initialized: bool) {
|
|
|
|
*self.is_initialized.write().await = is_initialized;
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn workspace_folders(&self) -> Vec<WorkspaceFolder> {
|
2024-06-27 15:43:49 -07:00
|
|
|
// TODO: fix clone
|
|
|
|
self.workspace_folders.iter().map(|i| i.clone()).collect()
|
2024-04-15 17:18:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn add_workspace_folders(&self, folders: Vec<WorkspaceFolder>) {
|
2024-03-11 17:50:31 -07:00
|
|
|
for folder in folders {
|
2024-06-27 15:43:49 -07:00
|
|
|
self.workspace_folders.insert(folder.name.to_string(), folder);
|
2024-03-11 17:50:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
async fn remove_workspace_folders(&self, folders: Vec<WorkspaceFolder>) {
|
2024-03-11 17:50:31 -07:00
|
|
|
for folder in folders {
|
2024-06-27 15:43:49 -07:00
|
|
|
self.workspace_folders.remove(&folder.name);
|
2024-03-11 17:50:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-27 15:43:49 -07:00
|
|
|
fn code_map(&self) -> &DashMap<String, Vec<u8>> {
|
2024-06-26 14:51:47 -07:00
|
|
|
&self.code_map
|
2024-04-15 17:18:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn insert_code_map(&self, uri: String, text: Vec<u8>) {
|
2024-06-27 15:43:49 -07:00
|
|
|
self.code_map.insert(uri, text);
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
async fn remove_from_code_map(&self, uri: String) -> Option<Vec<u8>> {
|
2024-06-27 15:43:49 -07:00
|
|
|
self.code_map.remove(&uri).map(|(_, v)| v)
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
async fn clear_code_state(&self) {
|
2024-06-27 15:43:49 -07:00
|
|
|
self.code_map.clear();
|
2024-03-12 13:37:47 -07:00
|
|
|
}
|
|
|
|
|
2024-06-27 15:43:49 -07:00
|
|
|
fn current_diagnostics_map(&self) -> &DashMap<String, Vec<Diagnostic>> {
|
2024-06-26 14:51:47 -07:00
|
|
|
&self.diagnostics_map
|
2024-03-11 17:50:31 -07:00
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
async fn inner_on_change(&self, _params: TextDocumentItem, _force: bool) {
|
2024-02-15 13:56:31 -08:00
|
|
|
// We don't need to do anything here.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Backend {
|
2024-11-20 15:19:25 +13:00
|
|
|
#[cfg(target_arch = "wasm32")]
|
|
|
|
pub fn new_wasm(
|
|
|
|
client: tower_lsp::Client,
|
|
|
|
fs: crate::fs::wasm::FileSystemManager,
|
|
|
|
zoo_client: kittycad::Client,
|
|
|
|
dev_mode: bool,
|
|
|
|
) -> Self {
|
|
|
|
Self::new(client, crate::fs::FileManager::new(fs), zoo_client, dev_mode)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new(
|
|
|
|
client: tower_lsp::Client,
|
|
|
|
fs: crate::fs::FileManager,
|
|
|
|
zoo_client: kittycad::Client,
|
|
|
|
dev_mode: bool,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
client,
|
|
|
|
fs: Arc::new(fs),
|
|
|
|
workspace_folders: Default::default(),
|
|
|
|
code_map: Default::default(),
|
|
|
|
editor_info: Arc::new(RwLock::new(CopilotEditorInfo::default())),
|
|
|
|
cache: Arc::new(CopilotCache::new()),
|
|
|
|
telemetry: Default::default(),
|
|
|
|
zoo_client,
|
|
|
|
|
|
|
|
is_initialized: Default::default(),
|
|
|
|
diagnostics_map: Default::default(),
|
|
|
|
dev_mode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-15 13:56:31 -08:00
|
|
|
/// Get completions from the kittycad api.
|
|
|
|
pub async fn get_completions(&self, language: String, prompt: String, suffix: String) -> Result<Vec<String>> {
|
|
|
|
let body = kittycad::types::KclCodeCompletionRequest {
|
2024-06-27 15:43:49 -07:00
|
|
|
extra: Some(kittycad::types::KclCodeCompletionParams {
|
|
|
|
language: Some(language.to_string()),
|
|
|
|
next_indent: None,
|
|
|
|
trim_by_indentation: true,
|
|
|
|
prompt_tokens: Some(prompt.len() as u32),
|
|
|
|
suffix_tokens: Some(suffix.len() as u32),
|
|
|
|
}),
|
|
|
|
prompt: Some(prompt),
|
|
|
|
suffix: Some(suffix),
|
2024-02-15 13:56:31 -08:00
|
|
|
max_tokens: Some(500),
|
|
|
|
temperature: Some(1.0),
|
|
|
|
top_p: Some(1.0),
|
|
|
|
// We only handle one completion at a time, for now so don't even waste the tokens.
|
|
|
|
n: Some(1),
|
|
|
|
stop: Some(["unset".to_string()].to_vec()),
|
|
|
|
nwo: None,
|
|
|
|
// We haven't implemented streaming yet.
|
2024-04-12 12:41:20 -07:00
|
|
|
stream: false,
|
2024-02-15 13:56:31 -08:00
|
|
|
};
|
|
|
|
|
2024-03-12 13:37:47 -07:00
|
|
|
let resp = self
|
|
|
|
.zoo_client
|
2024-08-12 13:06:30 -07:00
|
|
|
.ml()
|
2024-02-15 13:56:31 -08:00
|
|
|
.create_kcl_code_completions(&body)
|
|
|
|
.await
|
|
|
|
.map_err(|err| Error {
|
|
|
|
code: tower_lsp::jsonrpc::ErrorCode::from(69),
|
|
|
|
data: None,
|
2025-06-26 17:02:54 -05:00
|
|
|
message: Cow::from(format!("Failed to get completions from zoo api: {err}")),
|
2024-02-15 13:56:31 -08:00
|
|
|
})?;
|
|
|
|
Ok(resp.completions)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn set_editor_info(&self, params: CopilotEditorInfo) -> Result<Success> {
|
|
|
|
self.client.log_message(MessageType::INFO, "setEditorInfo").await;
|
|
|
|
let copy = Arc::clone(&self.editor_info);
|
|
|
|
let mut lock = copy.write().map_err(|err| Error {
|
|
|
|
code: tower_lsp::jsonrpc::ErrorCode::from(69),
|
|
|
|
data: None,
|
2025-06-26 17:02:54 -05:00
|
|
|
message: Cow::from(format!("Failed lock: {err}")),
|
2024-02-15 13:56:31 -08:00
|
|
|
})?;
|
|
|
|
*lock = params;
|
|
|
|
Ok(Success::new(true))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_doc_params(&self, params: &CopilotLspCompletionParams) -> Result<DocParams> {
|
|
|
|
let pos = params.doc.position;
|
|
|
|
let uri = params.doc.uri.to_string();
|
|
|
|
let rope = ropey::Rope::from_str(¶ms.doc.source);
|
2024-03-12 23:57:43 -07:00
|
|
|
let offset = crate::lsp::util::position_to_offset(pos.into(), &rope).unwrap_or_default();
|
2024-02-15 13:56:31 -08:00
|
|
|
|
|
|
|
Ok(DocParams {
|
|
|
|
uri: uri.to_string(),
|
|
|
|
pos,
|
|
|
|
language: params.doc.language_id.to_string(),
|
2024-02-19 12:33:16 -08:00
|
|
|
prefix: crate::lsp::util::get_text_before(offset, &rope).unwrap_or_default(),
|
|
|
|
suffix: crate::lsp::util::get_text_after(offset, &rope).unwrap_or_default(),
|
2024-03-12 23:57:43 -07:00
|
|
|
line_before: crate::lsp::util::get_line_before(pos.into(), &rope).unwrap_or_default(),
|
2024-02-15 13:56:31 -08:00
|
|
|
rope,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_completions_cycling(
|
|
|
|
&self,
|
|
|
|
params: CopilotLspCompletionParams,
|
|
|
|
) -> Result<CopilotCompletionResponse> {
|
|
|
|
let doc_params = self.get_doc_params(¶ms)?;
|
|
|
|
let cached_result = self.cache.get_cached_result(&doc_params.uri, doc_params.pos.line);
|
|
|
|
if let Some(cached_result) = cached_result {
|
|
|
|
return Ok(cached_result);
|
|
|
|
}
|
|
|
|
|
|
|
|
let doc_params = self.get_doc_params(¶ms)?;
|
|
|
|
let line_before = doc_params.line_before.to_string();
|
|
|
|
|
|
|
|
// Let's not call it yet since it's not our model.
|
2024-03-12 23:57:43 -07:00
|
|
|
// We will need to wrap in spawn_local like we do in kcl/mod.rs for wasm only.
|
|
|
|
#[cfg(test)]
|
2024-06-30 18:26:16 -07:00
|
|
|
let mut completion_list = self
|
2024-03-12 23:57:43 -07:00
|
|
|
.get_completions(doc_params.language, doc_params.prefix, doc_params.suffix)
|
|
|
|
.await
|
|
|
|
.map_err(|err| Error {
|
|
|
|
code: tower_lsp::jsonrpc::ErrorCode::from(69),
|
|
|
|
data: None,
|
2025-06-26 17:02:54 -05:00
|
|
|
message: Cow::from(format!("Failed to get completions: {err}")),
|
2024-03-12 23:57:43 -07:00
|
|
|
})?;
|
|
|
|
#[cfg(not(test))]
|
2024-06-30 18:26:16 -07:00
|
|
|
let mut completion_list = vec![];
|
|
|
|
|
2024-07-24 16:11:56 -04:00
|
|
|
// if self.dev_mode
|
|
|
|
if false {
|
2024-06-30 18:26:16 -07:00
|
|
|
completion_list.push(
|
2025-04-30 13:12:40 +12:00
|
|
|
r#"fn cube(pos, scale) {
|
|
|
|
sg = startSketchOn(XY)
|
2025-04-25 16:01:35 -05:00
|
|
|
|> startProfile(at = pos)
|
2025-05-02 21:07:31 -04:00
|
|
|
|> line(end = [0, scale])
|
|
|
|
|> line(end = [scale, 0])
|
|
|
|
|> line(end = [0, -scale])
|
2024-06-30 18:26:16 -07:00
|
|
|
return sg
|
|
|
|
}
|
2025-05-02 21:07:31 -04:00
|
|
|
part001 = cube(pos = [0,0], scale = 20)
|
|
|
|
|> close()
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
|> extrude(length=20)"#
|
2024-06-30 18:26:16 -07:00
|
|
|
.to_string(),
|
|
|
|
);
|
|
|
|
}
|
2024-02-15 13:56:31 -08:00
|
|
|
|
|
|
|
let response = CopilotCompletionResponse::from_str_vec(completion_list, line_before, doc_params.pos);
|
2024-03-12 23:57:43 -07:00
|
|
|
// Set the telemetry data for each completion.
|
|
|
|
for completion in response.completions.iter() {
|
|
|
|
let telemetry = CopilotCompletionTelemetry {
|
|
|
|
completion: completion.clone(),
|
|
|
|
params: params.clone(),
|
|
|
|
};
|
2024-06-27 15:43:49 -07:00
|
|
|
self.telemetry.insert(completion.uuid, telemetry);
|
2024-03-12 23:57:43 -07:00
|
|
|
}
|
2024-02-15 13:56:31 -08:00
|
|
|
self.cache
|
|
|
|
.set_cached_result(&doc_params.uri, &doc_params.pos.line, &response);
|
|
|
|
|
|
|
|
Ok(response)
|
|
|
|
}
|
|
|
|
|
2024-03-12 23:57:43 -07:00
|
|
|
pub async fn accept_completion(&self, params: CopilotAcceptCompletionParams) {
|
2024-02-15 13:56:31 -08:00
|
|
|
self.client
|
2025-06-26 17:02:54 -05:00
|
|
|
.log_message(MessageType::INFO, format!("Accepted completions: {params:?}"))
|
2024-02-15 13:56:31 -08:00
|
|
|
.await;
|
|
|
|
|
2024-03-12 23:57:43 -07:00
|
|
|
// Get the original telemetry data.
|
2024-06-27 15:43:49 -07:00
|
|
|
let Some(original) = self.telemetry.remove(¶ms.uuid) else {
|
2024-03-12 23:57:43 -07:00
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
self.client
|
2025-06-26 17:02:54 -05:00
|
|
|
.log_message(MessageType::INFO, format!("Original telemetry: {original:?}"))
|
2024-03-12 23:57:43 -07:00
|
|
|
.await;
|
|
|
|
|
|
|
|
// TODO: Send the telemetry data to the zoo api.
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
|
2024-03-12 23:57:43 -07:00
|
|
|
pub async fn reject_completions(&self, params: CopilotRejectCompletionParams) {
|
2024-02-15 13:56:31 -08:00
|
|
|
self.client
|
2025-06-26 17:02:54 -05:00
|
|
|
.log_message(MessageType::INFO, format!("Rejected completions: {params:?}"))
|
2024-02-15 13:56:31 -08:00
|
|
|
.await;
|
|
|
|
|
2024-03-12 23:57:43 -07:00
|
|
|
// Get the original telemetry data.
|
|
|
|
let mut originals: Vec<CopilotCompletionTelemetry> = Default::default();
|
|
|
|
for uuid in params.uuids {
|
2024-06-27 15:43:49 -07:00
|
|
|
if let Some(original) = self.telemetry.remove(&uuid).map(|(_, v)| v) {
|
2024-03-12 23:57:43 -07:00
|
|
|
originals.push(original);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.client
|
2025-06-26 17:02:54 -05:00
|
|
|
.log_message(MessageType::INFO, format!("Original telemetry: {originals:?}"))
|
2024-03-12 23:57:43 -07:00
|
|
|
.await;
|
|
|
|
|
|
|
|
// TODO: Send the telemetry data to the zoo api.
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tower_lsp::async_trait]
|
|
|
|
impl LanguageServer for Backend {
|
|
|
|
async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
|
|
|
|
Ok(InitializeResult {
|
|
|
|
capabilities: ServerCapabilities {
|
|
|
|
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
|
|
|
|
open_close: Some(true),
|
|
|
|
change: Some(TextDocumentSyncKind::FULL),
|
|
|
|
..Default::default()
|
|
|
|
})),
|
|
|
|
workspace: Some(WorkspaceServerCapabilities {
|
|
|
|
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
|
|
|
|
supported: Some(true),
|
|
|
|
change_notifications: Some(OneOf::Left(true)),
|
|
|
|
}),
|
|
|
|
file_operations: None,
|
|
|
|
}),
|
|
|
|
..ServerCapabilities::default()
|
|
|
|
},
|
|
|
|
..Default::default()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn initialized(&self, params: InitializedParams) {
|
|
|
|
self.do_initialized(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn shutdown(&self) -> tower_lsp::jsonrpc::Result<()> {
|
|
|
|
self.do_shutdown().await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_change_workspace_folders(&self, params: DidChangeWorkspaceFoldersParams) {
|
|
|
|
self.do_did_change_workspace_folders(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
|
|
|
|
self.do_did_change_configuration(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) {
|
|
|
|
self.do_did_change_watched_files(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_create_files(&self, params: CreateFilesParams) {
|
|
|
|
self.do_did_create_files(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_rename_files(&self, params: RenameFilesParams) {
|
|
|
|
self.do_did_rename_files(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_delete_files(&self, params: DeleteFilesParams) {
|
|
|
|
self.do_did_delete_files(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_open(&self, params: DidOpenTextDocumentParams) {
|
|
|
|
self.do_did_open(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_change(&self, params: DidChangeTextDocumentParams) {
|
2024-06-27 15:43:49 -07:00
|
|
|
self.do_did_change(params).await;
|
2024-02-15 13:56:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_save(&self, params: DidSaveTextDocumentParams) {
|
|
|
|
self.do_did_save(params).await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn did_close(&self, params: DidCloseTextDocumentParams) {
|
|
|
|
self.do_did_close(params).await
|
|
|
|
}
|
|
|
|
}
|