Skip to content

Commit 389c3f0

Browse files
yangdanny97meta-codesync[bot]
authored andcommitted
notebook LSP spec
Summary: This diff includes AI-generated notebook LSP structs based on the LSP spec. They are very similar to what's in lsp-types 0.97.0, but we aren't able to upgrade ATM since there were major breaking changes w/ URI representation & there are quite a few other dependencies that use it internally that need to be migrated. Therefore, we'll use our own for now, and migrate later. In order to add a new field to the server capabilities, we make a new struct that has the old one from lsp-types inlined. Reviewed By: kinto0 Differential Revision: D85404733 fbshipit-source-id: 83a32b139d77943d8671ef544b45f5bea4709dce
1 parent b9d8669 commit 389c3f0

File tree

4 files changed

+579
-75
lines changed

4 files changed

+579
-75
lines changed

pyrefly/lib/lsp/non_wasm/server.rs

Lines changed: 95 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ use lsp_types::SemanticTokensRangeParams;
9090
use lsp_types::SemanticTokensRangeResult;
9191
use lsp_types::SemanticTokensResult;
9292
use lsp_types::SemanticTokensServerCapabilities;
93-
use lsp_types::ServerCapabilities;
9493
use lsp_types::SignatureHelp;
9594
use lsp_types::SignatureHelpOptions;
9695
use lsp_types::SignatureHelpParams;
@@ -161,6 +160,7 @@ use pyrefly_util::prelude::VecExt;
161160
use pyrefly_util::task_heap::CancellationHandle;
162161
use pyrefly_util::task_heap::Cancelled;
163162
use pyrefly_util::watch_pattern::WatchPattern;
163+
use serde::Deserialize;
164164
use serde::Serialize;
165165
use serde::de::DeserializeOwned;
166166
use serde_json::Value;
@@ -191,6 +191,8 @@ use crate::lsp::non_wasm::workspace::LspAnalysisConfig;
191191
use crate::lsp::non_wasm::workspace::Workspace;
192192
use crate::lsp::non_wasm::workspace::Workspaces;
193193
use crate::lsp::wasm::hover::get_hover;
194+
use crate::lsp::wasm::notebook::NotebookDocumentSyncOptions;
195+
use crate::lsp::wasm::notebook::NotebookDocumentSyncRegistrationOptions;
194196
use crate::lsp::wasm::provide_type::ProvideType;
195197
use crate::lsp::wasm::provide_type::ProvideTypeResponse;
196198
use crate::lsp::wasm::provide_type::provide_type;
@@ -247,6 +249,22 @@ pub trait TspInterface {
247249
) -> anyhow::Result<ProcessEvent>;
248250
}
249251

252+
/// Until we upgrade lsp-types to 0.96 or newer, we'll need to patch in the notebook document
253+
/// sync capabilities
254+
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
255+
#[serde(rename_all = "camelCase")]
256+
pub struct ServerCapabilities {
257+
#[serde(flatten)]
258+
capabilities: lsp_types::ServerCapabilities,
259+
260+
/// Defines how notebook documents are synced.
261+
///
262+
/// @since 3.17.0
263+
#[serde(skip_serializing_if = "Option::is_none")]
264+
pub notebook_document_sync:
265+
Option<OneOf<NotebookDocumentSyncOptions, NotebookDocumentSyncRegistrationOptions>>,
266+
}
267+
250268
#[derive(Clone, Dupe)]
251269
struct ServerConnection(Arc<Connection>);
252270

@@ -390,82 +408,85 @@ pub fn capabilities(
390408
.and_then(|c| c.augments_syntax_tokens)
391409
.unwrap_or(false);
392410
ServerCapabilities {
393-
position_encoding: Some(PositionEncodingKind::UTF16),
394-
text_document_sync: Some(TextDocumentSyncCapability::Kind(
395-
TextDocumentSyncKind::INCREMENTAL,
396-
)),
397-
definition_provider: Some(OneOf::Left(true)),
398-
type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
399-
code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
400-
code_action_kinds: Some(vec![CodeActionKind::QUICKFIX]),
401-
..Default::default()
402-
})),
403-
completion_provider: Some(CompletionOptions {
404-
trigger_characters: Some(vec![".".to_owned()]),
405-
..Default::default()
406-
}),
407-
document_highlight_provider: Some(OneOf::Left(true)),
408-
// Find references won't work properly if we don't know all the files.
409-
references_provider: match indexing_mode {
410-
IndexingMode::None => None,
411-
IndexingMode::LazyNonBlockingBackground | IndexingMode::LazyBlocking => {
412-
Some(OneOf::Left(true))
413-
}
414-
},
415-
rename_provider: match indexing_mode {
416-
IndexingMode::None => None,
417-
IndexingMode::LazyNonBlockingBackground | IndexingMode::LazyBlocking => {
418-
Some(OneOf::Right(RenameOptions {
419-
prepare_provider: Some(true),
420-
work_done_progress_options: Default::default(),
421-
}))
422-
}
423-
},
424-
signature_help_provider: Some(SignatureHelpOptions {
425-
trigger_characters: Some(vec!["(".to_owned(), ",".to_owned()]),
426-
..Default::default()
427-
}),
428-
hover_provider: Some(HoverProviderCapability::Simple(true)),
429-
inlay_hint_provider: Some(OneOf::Left(true)),
430-
document_symbol_provider: Some(OneOf::Left(true)),
431-
workspace_symbol_provider: Some(OneOf::Left(true)),
432-
semantic_tokens_provider: if augments_syntax_tokens {
433-
// We currently only return partial tokens (e.g. no tokens for keywords right now).
434-
// If the client doesn't support `augments_syntax_tokens` to fallback baseline
435-
// syntax highlighting for tokens we don't provide, it will be a regression
436-
// (e.g. users might lose keyword highlighting).
437-
// Therefore, we should not produce semantic tokens if the client doesn't support `augments_syntax_tokens`.
438-
Some(SemanticTokensServerCapabilities::SemanticTokensOptions(
439-
SemanticTokensOptions {
440-
legend: SemanticTokensLegends::lsp_semantic_token_legends(),
441-
full: Some(SemanticTokensFullOptions::Bool(true)),
442-
range: Some(true),
443-
..Default::default()
444-
},
445-
))
446-
} else {
447-
None
448-
},
449-
workspace: Some(WorkspaceServerCapabilities {
450-
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
451-
supported: Some(true),
452-
change_notifications: Some(OneOf::Left(true)),
411+
capabilities: lsp_types::ServerCapabilities {
412+
position_encoding: Some(PositionEncodingKind::UTF16),
413+
text_document_sync: Some(TextDocumentSyncCapability::Kind(
414+
TextDocumentSyncKind::INCREMENTAL,
415+
)),
416+
definition_provider: Some(OneOf::Left(true)),
417+
type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
418+
code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
419+
code_action_kinds: Some(vec![CodeActionKind::QUICKFIX]),
420+
..Default::default()
421+
})),
422+
completion_provider: Some(CompletionOptions {
423+
trigger_characters: Some(vec![".".to_owned()]),
424+
..Default::default()
453425
}),
454-
file_operations: Some(lsp_types::WorkspaceFileOperationsServerCapabilities {
455-
will_rename: Some(lsp_types::FileOperationRegistrationOptions {
456-
filters: vec![lsp_types::FileOperationFilter {
457-
pattern: lsp_types::FileOperationPattern {
458-
glob: "**/*.{py,pyi}".to_owned(),
459-
460-
matches: Some(lsp_types::FileOperationPatternKind::File),
461-
options: None,
462-
},
463-
scheme: Some("file".to_owned()),
464-
}],
465-
}),
426+
document_highlight_provider: Some(OneOf::Left(true)),
427+
// Find references won't work properly if we don't know all the files.
428+
references_provider: match indexing_mode {
429+
IndexingMode::None => None,
430+
IndexingMode::LazyNonBlockingBackground | IndexingMode::LazyBlocking => {
431+
Some(OneOf::Left(true))
432+
}
433+
},
434+
rename_provider: match indexing_mode {
435+
IndexingMode::None => None,
436+
IndexingMode::LazyNonBlockingBackground | IndexingMode::LazyBlocking => {
437+
Some(OneOf::Right(RenameOptions {
438+
prepare_provider: Some(true),
439+
work_done_progress_options: Default::default(),
440+
}))
441+
}
442+
},
443+
signature_help_provider: Some(SignatureHelpOptions {
444+
trigger_characters: Some(vec!["(".to_owned(), ",".to_owned()]),
466445
..Default::default()
467446
}),
468-
}),
447+
hover_provider: Some(HoverProviderCapability::Simple(true)),
448+
inlay_hint_provider: Some(OneOf::Left(true)),
449+
document_symbol_provider: Some(OneOf::Left(true)),
450+
workspace_symbol_provider: Some(OneOf::Left(true)),
451+
semantic_tokens_provider: if augments_syntax_tokens {
452+
// We currently only return partial tokens (e.g. no tokens for keywords right now).
453+
// If the client doesn't support `augments_syntax_tokens` to fallback baseline
454+
// syntax highlighting for tokens we don't provide, it will be a regression
455+
// (e.g. users might lose keyword highlighting).
456+
// Therefore, we should not produce semantic tokens if the client doesn't support `augments_syntax_tokens`.
457+
Some(SemanticTokensServerCapabilities::SemanticTokensOptions(
458+
SemanticTokensOptions {
459+
legend: SemanticTokensLegends::lsp_semantic_token_legends(),
460+
full: Some(SemanticTokensFullOptions::Bool(true)),
461+
range: Some(true),
462+
..Default::default()
463+
},
464+
))
465+
} else {
466+
None
467+
},
468+
workspace: Some(WorkspaceServerCapabilities {
469+
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
470+
supported: Some(true),
471+
change_notifications: Some(OneOf::Left(true)),
472+
}),
473+
file_operations: Some(lsp_types::WorkspaceFileOperationsServerCapabilities {
474+
will_rename: Some(lsp_types::FileOperationRegistrationOptions {
475+
filters: vec![lsp_types::FileOperationFilter {
476+
pattern: lsp_types::FileOperationPattern {
477+
glob: "**/*.{py,pyi}".to_owned(),
478+
479+
matches: Some(lsp_types::FileOperationPatternKind::File),
480+
options: None,
481+
},
482+
scheme: Some("file".to_owned()),
483+
}],
484+
}),
485+
..Default::default()
486+
}),
487+
}),
488+
..Default::default()
489+
},
469490
..Default::default()
470491
}
471492
}

pyrefly/lib/lsp/wasm/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
pub mod hover;
9+
pub mod notebook;
910
pub mod provide_type;
1011
#[cfg(not(target_arch = "wasm32"))]
1112
pub mod will_rename_files;

0 commit comments

Comments
 (0)