mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:34:57 +00:00
[ty] Add signature help provider to playground (#19276)
This commit is contained in:
parent
b0b65c24ff
commit
426fa4bb12
2 changed files with 138 additions and 1 deletions
|
@ -14,6 +14,7 @@ use ruff_notebook::Notebook;
|
||||||
use ruff_python_formatter::formatted_file;
|
use ruff_python_formatter::formatted_file;
|
||||||
use ruff_source_file::{LineIndex, OneIndexed, SourceLocation};
|
use ruff_source_file::{LineIndex, OneIndexed, SourceLocation};
|
||||||
use ruff_text_size::{Ranged, TextSize};
|
use ruff_text_size::{Ranged, TextSize};
|
||||||
|
use ty_ide::signature_help;
|
||||||
use ty_ide::{MarkupKind, goto_type_definition, hover, inlay_hints};
|
use ty_ide::{MarkupKind, goto_type_definition, hover, inlay_hints};
|
||||||
use ty_project::ProjectMetadata;
|
use ty_project::ProjectMetadata;
|
||||||
use ty_project::metadata::options::Options;
|
use ty_project::metadata::options::Options;
|
||||||
|
@ -385,6 +386,51 @@ impl Workspace {
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = "signatureHelp")]
|
||||||
|
pub fn signature_help(
|
||||||
|
&self,
|
||||||
|
file_id: &FileHandle,
|
||||||
|
position: Position,
|
||||||
|
) -> Result<Option<SignatureHelp>, Error> {
|
||||||
|
let source = source_text(&self.db, file_id.file);
|
||||||
|
let index = line_index(&self.db, file_id.file);
|
||||||
|
|
||||||
|
let offset = position.to_text_size(&source, &index, self.position_encoding)?;
|
||||||
|
|
||||||
|
let Some(signature_help_info) = signature_help(&self.db, file_id.file, offset) else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let signatures = signature_help_info
|
||||||
|
.signatures
|
||||||
|
.into_iter()
|
||||||
|
.map(|sig| {
|
||||||
|
let parameters = sig
|
||||||
|
.parameters
|
||||||
|
.into_iter()
|
||||||
|
.map(|param| ParameterInformation {
|
||||||
|
label: param.label,
|
||||||
|
documentation: param.documentation,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
SignatureInformation {
|
||||||
|
label: sig.label,
|
||||||
|
documentation: sig.documentation,
|
||||||
|
parameters,
|
||||||
|
active_parameter: sig.active_parameter.and_then(|p| u32::try_from(p).ok()),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(Some(SignatureHelp {
|
||||||
|
signatures,
|
||||||
|
active_signature: signature_help_info
|
||||||
|
.active_signature
|
||||||
|
.and_then(|s| u32::try_from(s).ok()),
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_error<E: std::fmt::Display>(err: E) -> Error {
|
pub(crate) fn into_error<E: std::fmt::Display>(err: E) -> Error {
|
||||||
|
@ -749,6 +795,35 @@ pub struct SemanticToken {
|
||||||
pub range: Range,
|
pub range: Range,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SignatureHelp {
|
||||||
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
|
pub signatures: Vec<SignatureInformation>,
|
||||||
|
pub active_signature: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SignatureInformation {
|
||||||
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
|
pub label: String,
|
||||||
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
|
pub documentation: Option<String>,
|
||||||
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
|
pub parameters: Vec<ParameterInformation>,
|
||||||
|
pub active_parameter: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ParameterInformation {
|
||||||
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
|
pub label: String,
|
||||||
|
#[wasm_bindgen(getter_with_clone)]
|
||||||
|
pub documentation: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl SemanticToken {
|
impl SemanticToken {
|
||||||
pub fn kinds() -> Vec<String> {
|
pub fn kinds() -> Vec<String> {
|
||||||
|
|
|
@ -152,7 +152,8 @@ class PlaygroundServer
|
||||||
languages.DocumentFormattingEditProvider,
|
languages.DocumentFormattingEditProvider,
|
||||||
languages.CompletionItemProvider,
|
languages.CompletionItemProvider,
|
||||||
languages.DocumentSemanticTokensProvider,
|
languages.DocumentSemanticTokensProvider,
|
||||||
languages.DocumentRangeSemanticTokensProvider
|
languages.DocumentRangeSemanticTokensProvider,
|
||||||
|
languages.SignatureHelpProvider
|
||||||
{
|
{
|
||||||
private typeDefinitionProviderDisposable: IDisposable;
|
private typeDefinitionProviderDisposable: IDisposable;
|
||||||
private editorOpenerDisposable: IDisposable;
|
private editorOpenerDisposable: IDisposable;
|
||||||
|
@ -162,6 +163,7 @@ class PlaygroundServer
|
||||||
private completionDisposable: IDisposable;
|
private completionDisposable: IDisposable;
|
||||||
private semanticTokensDisposable: IDisposable;
|
private semanticTokensDisposable: IDisposable;
|
||||||
private rangeSemanticTokensDisposable: IDisposable;
|
private rangeSemanticTokensDisposable: IDisposable;
|
||||||
|
private signatureHelpDisposable: IDisposable;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private monaco: Monaco,
|
private monaco: Monaco,
|
||||||
|
@ -191,9 +193,13 @@ class PlaygroundServer
|
||||||
this.editorOpenerDisposable = monaco.editor.registerEditorOpener(this);
|
this.editorOpenerDisposable = monaco.editor.registerEditorOpener(this);
|
||||||
this.formatDisposable =
|
this.formatDisposable =
|
||||||
monaco.languages.registerDocumentFormattingEditProvider("python", this);
|
monaco.languages.registerDocumentFormattingEditProvider("python", this);
|
||||||
|
this.signatureHelpDisposable =
|
||||||
|
monaco.languages.registerSignatureHelpProvider("python", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerCharacters: string[] = ["."];
|
triggerCharacters: string[] = ["."];
|
||||||
|
signatureHelpTriggerCharacters: string[] = ["(", ","];
|
||||||
|
signatureHelpRetriggerCharacters: string[] = [")"];
|
||||||
|
|
||||||
getLegend(): languages.SemanticTokensLegend {
|
getLegend(): languages.SemanticTokensLegend {
|
||||||
return {
|
return {
|
||||||
|
@ -292,6 +298,61 @@ class PlaygroundServer
|
||||||
|
|
||||||
resolveCompletionItem: undefined;
|
resolveCompletionItem: undefined;
|
||||||
|
|
||||||
|
provideSignatureHelp(
|
||||||
|
model: editor.ITextModel,
|
||||||
|
position: Position,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
_token: CancellationToken,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
_context: languages.SignatureHelpContext,
|
||||||
|
): languages.ProviderResult<languages.SignatureHelpResult> {
|
||||||
|
const selectedFile = this.props.files.selected;
|
||||||
|
|
||||||
|
if (selectedFile == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedHandle = this.props.files.handles[selectedFile];
|
||||||
|
|
||||||
|
if (selectedHandle == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const signatureHelp = this.props.workspace.signatureHelp(
|
||||||
|
selectedHandle,
|
||||||
|
new TyPosition(position.lineNumber, position.column),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (signatureHelp == null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
dispose() {},
|
||||||
|
value: {
|
||||||
|
signatures: signatureHelp.signatures.map((sig) => ({
|
||||||
|
label: sig.label,
|
||||||
|
documentation: sig.documentation
|
||||||
|
? { value: sig.documentation }
|
||||||
|
: undefined,
|
||||||
|
parameters: sig.parameters.map((param) => ({
|
||||||
|
label: param.label,
|
||||||
|
documentation: param.documentation
|
||||||
|
? { value: param.documentation }
|
||||||
|
: undefined,
|
||||||
|
})),
|
||||||
|
activeParameter: sig.active_parameter,
|
||||||
|
})),
|
||||||
|
activeSignature: signatureHelp.active_signature ?? 0,
|
||||||
|
activeParameter:
|
||||||
|
signatureHelp.active_signature != null
|
||||||
|
? (signatureHelp.signatures[signatureHelp.active_signature]
|
||||||
|
?.active_parameter ?? 0)
|
||||||
|
: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
provideInlayHints(
|
provideInlayHints(
|
||||||
_model: editor.ITextModel,
|
_model: editor.ITextModel,
|
||||||
range: Range,
|
range: Range,
|
||||||
|
@ -569,6 +630,7 @@ class PlaygroundServer
|
||||||
this.rangeSemanticTokensDisposable.dispose();
|
this.rangeSemanticTokensDisposable.dispose();
|
||||||
this.semanticTokensDisposable.dispose();
|
this.semanticTokensDisposable.dispose();
|
||||||
this.completionDisposable.dispose();
|
this.completionDisposable.dispose();
|
||||||
|
this.signatureHelpDisposable.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue