Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: auto completions (relation stop, name, more docs) #840

Merged
merged 8 commits into from Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/language-server/src/completion/completionUtil.ts
Expand Up @@ -44,7 +44,9 @@ function convertAttributesToCompletionItems(
itemKind: CompletionItemKind,
insertTextFunc: (label: string) => string,
): CompletionItem[] {
// https://code.visualstudio.com/api/references/vscode-api#CompletionItem
const result: CompletionItem[] = []

for (const item of completionItems) {
const docComment = [
'```prisma',
Expand Down
62 changes: 55 additions & 7 deletions packages/language-server/src/completion/completions.json
Expand Up @@ -240,19 +240,67 @@
},
{
"label": "onDelete: ",
"fullSignature": "onDelete: ",
"documentation": "Specifies the action to perform when a referenced entry in the referenced model is being deleted.",
"params": []
"fullSignature": "onDelete: Cascade | Restrict | NoAction | SetNull | SetDefault",
"documentation": "Specifies the action to perform when a referenced entry in the referenced model is being deleted, [learn more](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions).",
"params": [
{
"label": "Cascade",
"documentation": "Deleting a referenced record will trigger the deletion of referencing record."
},
{
"label": "Restrict",
"documentation": "Prevents the deletion if any referencing records exist."
},
{
"label": "NoAction",
"documentation": "Is similar to Restrict, the difference between the two is dependant on the database being used, [learn more](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions)."
},
{
"label": "SetNull",
"documentation": "The scalar field of the referenced object will be set to NULL."
},
{
"label": "SetDefault",
"documentation": "The scalar field of the referencing object will be set to the fields default value."
}
]
},
{
"label": "onUpdate: ",
"fullSignature": "onUpdate: ",
"documentation": "Specifies the action to perform when a referenced field in the referenced model is being updated to a new value.",
"params": []
"fullSignature": "onUpdate: Cascade | Restrict | NoAction | SetNull | SetDefault",
"documentation": "Specifies the action to perform when a referenced field in the referenced model is being updated to a new value, [learn more](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions).",
"params": [
{
"label": "Cascade",
"documentation": "Updates the relation scalar fields if the referenced scalar fields of the dependant record are updated."
},
{
"label": "Restrict",
"documentation": "Prevents the identifier of a referenced record from being changed."
},
{
"label": "NoAction",
"documentation": "Is similar to Restrict, the difference between the two is dependant on the database being used, [learn more](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions)."
},
{
"label": "SetNull",
"documentation": "When updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL."
},
{
"label": "SetDefault",
"documentation": "The scalar field of the referencing object will be set to the fields default value."
}
]
},
{
"label": "\"\"",
"fullSignature": "\"\"",
"fullSignature": "String",
"documentation": "Defines the name of the relationship. In an m-n-relation, it also determines the name of the underlying relation table.",
"params": []
},
{
"label": "name: ",
"fullSignature": "name: String",
"documentation": "Defines the name of the relationship. In an m-n-relation, it also determines the name of the underlying relation table.",
"params": []
}
Expand Down
61 changes: 46 additions & 15 deletions packages/language-server/src/completion/completions.ts
Expand Up @@ -933,25 +933,56 @@ function getSuggestionsForRelationDirective(
isIncomplete: false,
}
}

if (stringTilPosition.endsWith(',')) {
const referencesExist = wordsBeforePosition.some((a) =>
a.includes('references'),
// Check which attributes are already present
// so we can filter them out from the suggestions
const attributesFound: Set<string> = new Set()

for (const word of wordsBeforePosition) {
if (word.includes('references')) {
attributesFound.add('references')
}
if (word.includes('fields')) {
attributesFound.add('fields')
}
if (word.includes('onUpdate')) {
attributesFound.add('onUpdate')
}
if (word.includes('onDelete')) {
attributesFound.add('onDelete')
}
if (word.includes('name') || /".*"/.exec(word)) {
attributesFound.add('name')
attributesFound.add('""')
}
}

const filteredSuggestions: CompletionItem[] = suggestions.reduce(
Jolg42 marked this conversation as resolved.
Show resolved Hide resolved
(accumulator: CompletionItem[] & unknown[], sugg) => {
let suggestionMatch = false
for (const attribute of attributesFound) {
if (sugg.label.includes(attribute)) {
suggestionMatch = true
}
}

if (!suggestionMatch) {
accumulator.push(sugg)
}

return accumulator
},
[],
)
const fieldsExist = wordsBeforePosition.some((a) => a.includes('fields'))
if (referencesExist && fieldsExist) {

if (filteredSuggestions.length === 0) {
Jolg42 marked this conversation as resolved.
Show resolved Hide resolved
return
}
if (referencesExist) {
return {
items: suggestions.filter((sugg) => !sugg.label.includes('references')),
isIncomplete: false,
}
}
if (fieldsExist) {
return {
items: suggestions.filter((sugg) => !sugg.label.includes('fields')),
isIncomplete: false,
}

return {
items: filteredSuggestions,
isIncomplete: false,
}
}
}
Expand Down