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

feat(auto-completion) #129

Merged
merged 74 commits into from May 26, 2020
Merged

feat(auto-completion) #129

merged 74 commits into from May 26, 2020

Conversation

carmenberndt
Copy link
Contributor

@carmenberndt carmenberndt commented May 8, 2020

closes #107

Context-aware auto-completion features:

  • Gets suggestions for available type, block, and field names and also supported functions and attributes.
  • Suggest semantically correct attributes / types (i.e. don't display attributes that would be invalid in this context)

@carmenberndt carmenberndt changed the title feat(Autocompletion) feat(auto-completion) May 8, 2020
@carmenberndt
Copy link
Contributor Author

carmenberndt commented May 8, 2020

TODO

  • The auto-completion should also show inline docs (similar to JSDoc for Prisma Client JS)
  • write tests

@carmenberndt carmenberndt added this to the Beta 5 milestone May 8, 2020
@carmenberndt carmenberndt marked this pull request as ready for review May 8, 2020 15:14
Copy link

@divyenduz divyenduz left a comment

Choose a reason for hiding this comment

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

Awesome work again, I think everything reported in the last review is fixed. We are getting closer and closer to this being super awesome 🎉

New observations:

  1. There is only one model Post in the schema that I am using, is it intentional that it lists two options for it on cmd+click as if there are multiple model Posts? IMO unambiguous jumps should just happen, without the selection dialog

https://www.loom.com/share/735a7d62baf74c80bb7640ee5d9b87b9

  1. Probably nitpick but this suggestion shouldn't come here

image

  1. Probably a bug, cmd+clicking on an unambiguous User model also lists enum UserType in jump targets, I think this happens with models that start with another model name too

https://www.loom.com/share/a25242046ce24d9996f3d11c9e88bfbe

Co-authored-by: Tim Suchanek <Tim.Suchanek@gmail.com>
@carmenberndt
Copy link
Contributor Author

  1. There is only one model Post in the schema that I am using, is it intentional that it lists two options for it on cmd+click as if there are multiple model Posts? IMO unambiguous jumps should just happen, without the selection dialog

I can't reproduce this using this schema:

generator db {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "windows"]
}

datasource db {
  provider = "postgresql"
  url      = env("AZURE_FUNCTIONS_WINDOWS_PG_URL")
}

enum UserType {
  CUSTOMER
  ADMIN
}

model User {
  email String   @unique
  name  String?
  posts  Post[]
  type  UserType

  @@id([email])
}

model Post {
  id        String   @default(cuid()) @id
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  published Boolean  @default(true)
  title     String
  content   String?
  authorId  String?
  User      User?    @relation(fields: [userEmail], references: [email])
  userEmail String?
}

@carmenberndt
Copy link
Contributor Author

  1. Probably a bug, cmd+clicking on an unambiguous User model also lists enum UserType in jump targets, I think this happens with models that start with another model name too

Should be fixed now

@carmenberndt
Copy link
Contributor Author

carmenberndt commented May 22, 2020

  1. Probably nitpick but this suggestion shouldn't come here

image

this is fixed now too 🙂

Copy link

@divyenduz divyenduz left a comment

Choose a reason for hiding this comment

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

Awesome work again, looks really stable this time:

  1. Nitpick - @@id when already used should not be in the suggestions

image

  1. Nitpick - Bug - cmd + hover yields an error message, if the schema is invalid (note the @@ in the schema). This should probably just work (error tolerant parser) or be a no-op.

https://www.loom.com/share/478c186e7e044f56aab0b34217ae83df

  1. Nitpick - Bug (or feature) - cmd + click on the model yields two jump to options, one for itself and one for the usage

https://www.loom.com/share/70a40f5443be41a0a51eea52ea7a6ec9

  1. Bug - jump to type definition has two fields even though it is not ambiguous. I am aware that you were not able to reproduce this, here is a video of what I observe though

https://www.loom.com/share/051510147592480f9bb84eaf3ada64f8

  1. Bug - starting a directive autocompletion with a wrong character forbids future autocompletions

https://www.loom.com/share/5529ccdd80fd4f2ebf71440e8bea55b2


Besides these, added some comments to review the code. There are some deep-copies (probably okay as none of them probably is on a variable array greater than a few items) but you can probably consider getting rid of the klona dependency altogether by using const array + map, filter reduce vs deep-copy + mutable variable. I repeat that doing this is not that important as the deep-copies are on small arrays.

if (end < 0) {
return ''
}
return currentLine.slice(beginning, end + position.character)
}

export async function handleDefinitionRequest(
export class MyBlock {

Choose a reason for hiding this comment

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

Is the name MyBlock intentional? What does this represent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When using the prismafile parser, there already as an object Block, but since I can't use this anymore, I called this MyBlock to not get confused with the other Object. Since I am not using the other dependency anmore, I guess I'll just rename this to Block again. This data structure is used to store all Blocks in a schema so I don't have parse every line in a string multiple times.

Comment on lines +129 to +130
(item.includes('model') || item.includes('enum')) &&
item.includes('{')

Choose a reason for hiding this comment

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

This relies on Prisma fmt to work and being used. It won't support this variant:

model User 
{

We might want to use a parser for this one (prismafile?). There could be multiple reasons why a team don't use Prisma fmt (like conventions, failure to know that format on save is an option etc).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Prismafile is not able to parse error-tolerant, also this will soon be unsupported as well, since this functionality will be replaced soon for the SDK.

It's not supposed to work on this variant, because then we would need to define what's possible. E.g. allow writing the whole schema in one line, or having mulitple new lines in between the modelName and {, ... . Not sure if this is worth putting the time into. @janpio?

Copy link
Member

Choose a reason for hiding this comment

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

Difficult question. Auto completion should of course already work before formatting was applied, but if I read your comment right this would be a lot more complicated and complex right now @carmenberndt, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, this would be quite easy to implement once we have a solution for the error-tolerant-parser. Then I can simply check where a model begins and ends and so on, right now this is quite complex since I am only working with strings here.

Comment on lines 167 to 190
function removeInvalidFieldSuggestions(
supportedFields: Array<string>,
block: MyBlock,
lines: Array<string>,
position: Position,
): Array<string> {
let reachedStartLine = false
for (const [key, item] of lines.entries()) {
if (key === block.start.line + 1) {
reachedStartLine = true
}
if (!reachedStartLine || key === position.line) {
continue
}
if (key === block.end.line) {
break
}
const fieldName = item.replace(/ .*/, '')
if (supportedFields.includes(fieldName)) {
supportedFields.filter((field) => field !== fieldName)
}
}
return supportedFields
}

Choose a reason for hiding this comment

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

Probably a code comment to specify what this functions does. I didn't understand this at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a comment.

position: Position,
): CompletionItem[] {
// create deep copy
const suggestions: CompletionItem[] = klona(supportedDataSourceFields)

Choose a reason for hiding this comment

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

Is this deep-copy needed? The variable is not modified. I like this pattern of using filter over deep-copy + mutable variable like in other places.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem of using filter is it modifies the object, which leads to problems when using the object again later in a different context. Therefore this deep-copy is needed here.

position: Position,
): CompletionItem[] {
// create deep copy
const suggestions: CompletionItem[] = klona(supportedGeneratorFields)

Choose a reason for hiding this comment

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

Is this deep-copy needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes it is, since both .map() and .filter() operations change the data inside supportedGeneratorFields

@carmenberndt
Copy link
Contributor Author

  1. Nitpick - @@id when already used should not be in the suggestions

this is fixed now

@carmenberndt
Copy link
Contributor Author

carmenberndt commented May 25, 2020

  1. Nitpick - @@id when already used should not be in the suggestions

image

done

  1. Nitpick - Bug - cmd + hover yields an error message, if the schema is invalid (note the @@ in the schema). This should probably just work (error tolerant parser) or be a no-op.

https://www.loom.com/share/478c186e7e044f56aab0b34217ae83df

can not reproduce this (both on windows and ubuntu)

  1. Nitpick - Bug (or feature) - cmd + click on the model yields two jump to options, one for itself and one for the usage

https://www.loom.com/share/70a40f5443be41a0a51eea52ea7a6ec9

can not reproduce this (both on windows and ubuntu)

  1. Bug - jump to type definition has two fields even though it is not ambiguous. I am aware that you were not able to reproduce this, here is a video of what I observe though

https://www.loom.com/share/051510147592480f9bb84eaf3ada64f8

can not reproduce this (both on windows and ubuntu)

  1. Bug - starting a directive autocompletion with a wrong character forbids future autocompletions

https://www.loom.com/share/5529ccdd80fd4f2ebf71440e8bea55b2

done

@@ -22,5 +22,6 @@
["[", "]"],
["(", ")"],
["\"", "\""]
]
],
"wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)"
Copy link
Member

Choose a reason for hiding this comment

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

what a beautiful pattern 💩

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@matthewmueller
Copy link
Contributor

matthewmueller commented May 25, 2020

Based on: #129 (review)

2. Nitpick - Bug - cmd + hover yields an error message, if the schema is invalid (note the @@ in the schema). This should probably just work (error tolerant parser) or be a no-op.

I can confirm this behavior as well on OSX. I'm holding alt while hovering over User.

https://www.loom.com/share/c3415ec6d19f4d1d9672585aef5f7fa5

3. Nitpick - Bug (or feature) - cmd + click on the model yields two jump to options, one for itself and one for the usage

I see 2 options too, but they're both the definition (not the caller). I'm not sure if this is expected or not (I don't use this peak feature).

CleanShot 2020-05-25 at 17 24 47@2x

4. Bug - jump to type definition has two fields even though it is not ambiguous. I am aware that you were not able to reproduce this, here is a video of what I observe though

@divyenduz do you have an example schema? I'm not able to reproduce this either.

@janpio
Copy link
Member

janpio commented May 25, 2020

Re 2) Can confirm this on windows, Ctrl + Hover while schema is invalid:
image

Re 3) Can confirm on Windows with valid schema:
image
(Also interpret it the way Matt does though)
This is already visible on Ctrl + hover only:
image

Re 4) This is actually 3 as well I think.

@carmenberndt
Copy link
Contributor Author

carmenberndt commented May 26, 2020

I think the issue does not lie in the current branch. I could reproduce all of your issues only in case there is another Prisma extension installed at the same time. Re 2) this is a bug currently in Prisma Dev. Re 3) and Re 4) this happens because go to definition is defined slightly different here and in Prisma Dev/Prisma Extension. Therefore this suggests two options.

@carmenberndt carmenberndt merged commit 4d6dbfd into master May 26, 2020
@carmenberndt carmenberndt deleted the autoCompletionResearch branch May 26, 2020 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Autocompletion in Prisma schema
6 participants