Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions crates/ty_ide/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use ruff_text_size::{Ranged, TextRange, TextSize};
use ty_python_semantic::{Completion, NameKind, SemanticModel};

use crate::Db;
use crate::docstring::Docstring;
use crate::find_node::covering_node;
use crate::goto::DefinitionsOrTargets;

pub fn completion(db: &dyn Db, file: File, offset: TextSize) -> Vec<Completion<'_>> {
pub fn completion(db: &dyn Db, file: File, offset: TextSize) -> Vec<DetailedCompletion<'_>> {
let parsed = parsed_module(db, file).load(db);

let Some(target_token) = CompletionTargetTokens::find(&parsed, offset) else {
Expand Down Expand Up @@ -40,6 +42,27 @@ pub fn completion(db: &dyn Db, file: File, offset: TextSize) -> Vec<Completion<'
completions.sort_by(compare_suggestions);
completions.dedup_by(|c1, c2| c1.name == c2.name);
completions
.into_iter()
.map(|completion| {
let definition = DefinitionsOrTargets::from_ty(db, completion.ty);
let documentation = definition.and_then(|def| def.docstring(db));
DetailedCompletion {
inner: completion,
documentation,
}
})
.collect()
}

pub struct DetailedCompletion<'db> {
pub inner: Completion<'db>,
pub documentation: Option<Docstring>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make this a field on Completion instead that defaults to None: Given that completion is the only method constructing the completions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently that doesn't work out because Docstring is defined in ty_ide and Completion is defined in ty_python_semantic. The crate boundaries have gotten quite wobbly 😅

}
impl<'db> std::ops::Deref for DetailedCompletion<'db> {
type Target = Completion<'db>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}

/// The kind of tokens identified under the cursor.
Expand Down Expand Up @@ -478,9 +501,8 @@ fn compare_suggestions(c1: &Completion, c2: &Completion) -> Ordering {
mod tests {
use insta::assert_snapshot;
use ruff_python_parser::{Mode, ParseOptions, TokenKind, Tokens};
use ty_python_semantic::Completion;

use crate::completion;
use crate::completion::{DetailedCompletion, completion};
use crate::tests::{CursorTest, cursor_test};

use super::token_suffix_by_kinds;
Expand Down Expand Up @@ -3022,14 +3044,14 @@ from os.<CURSOR>
)
}

fn completions_if(&self, predicate: impl Fn(&Completion) -> bool) -> String {
fn completions_if(&self, predicate: impl Fn(&DetailedCompletion) -> bool) -> String {
self.completions_if_snapshot(predicate, |c| c.name.as_str().to_string())
}

fn completions_if_snapshot(
&self,
predicate: impl Fn(&Completion) -> bool,
snapshot: impl Fn(&Completion) -> String,
predicate: impl Fn(&DetailedCompletion) -> bool,
snapshot: impl Fn(&DetailedCompletion) -> String,
) -> String {
let completions = completion(&self.db, self.cursor.file, self.cursor.offset);
if completions.is_empty() {
Expand Down
22 changes: 22 additions & 0 deletions crates/ty_ide/src/goto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,28 @@ pub(crate) enum DefinitionsOrTargets<'db> {
}

impl<'db> DefinitionsOrTargets<'db> {
pub(crate) fn from_ty(db: &'db dyn crate::Db, ty: Type<'db>) -> Option<Self> {
let ty_def = ty.definition(db)?;
let resolved = match ty_def {
ty_python_semantic::types::TypeDefinition::Module(module) => {
ResolvedDefinition::Module(module.file(db)?)
}
ty_python_semantic::types::TypeDefinition::Class(definition) => {
ResolvedDefinition::Definition(definition)
}
ty_python_semantic::types::TypeDefinition::Function(definition) => {
ResolvedDefinition::Definition(definition)
}
ty_python_semantic::types::TypeDefinition::TypeVar(definition) => {
ResolvedDefinition::Definition(definition)
}
ty_python_semantic::types::TypeDefinition::TypeAlias(definition) => {
ResolvedDefinition::Definition(definition)
}
};
Some(DefinitionsOrTargets::Definitions(vec![resolved]))
}

/// Get the "goto-declaration" interpretation of this definition
///
/// In this case it basically returns exactly what was found.
Expand Down
9 changes: 7 additions & 2 deletions crates/ty_server/src/server/api/requests/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::borrow::Cow;
use std::time::Instant;

use lsp_types::request::Completion;
use lsp_types::{CompletionItem, CompletionItemKind, CompletionParams, CompletionResponse, Url};
use lsp_types::{
CompletionItem, CompletionItemKind, CompletionParams, CompletionResponse, Documentation, Url,
};
use ruff_db::source::{line_index, source_text};
use ty_ide::completion;
use ty_project::ProjectDatabase;
Expand Down Expand Up @@ -64,9 +66,12 @@ impl BackgroundDocumentRequestHandler for CompletionRequestHandler {
.map(|(i, comp)| {
let kind = comp.kind(db).map(ty_kind_to_lsp_kind);
CompletionItem {
label: comp.name.into(),
label: comp.inner.name.into(),
kind,
sort_text: Some(format!("{i:-max_index_len$}")),
documentation: comp
.documentation
.map(|docstring| Documentation::String(docstring.render_plaintext())),
..Default::default()
}
})
Expand Down
2 changes: 1 addition & 1 deletion crates/ty_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ impl Workspace {
.into_iter()
.map(|completion| Completion {
kind: completion.kind(&self.db).map(CompletionKind::from),
name: completion.name.into(),
name: completion.inner.name.into(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to also hook up documentation in the playground. You have to add a new documentation field to Completion, then propagate the field here

insertText: completion.name,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think done? Never tested the playground.

})
.collect())
}
Expand Down
Loading