Vscode: [json] Provide a way to stop built-in JSON language server auto completion item

Created on 16 Nov 2018  路  17Comments  路  Source: microsoft/vscode

I'm writing a JSON-LD language server extension. JSON-LD has its own context for auto completion item, and built-in JSON language server sometimes makes JSON-LD auto completion mess.

0

I understand that we should treat all extensions, including built-in extensions, equally, and it doesn't make sense to disable part feature of one extension for another.

To my case, I suggest such solution:

  1. Make document selector score fine. Currently, the score has max value of 10. It doesn't make sense that to specific language id and file path has the same score with to only specific language id.

For example:

{
  language: 'json',
  scheme: 'file',
  pattern: '**/*.{interface,template}.json'
}

has the same score with

{
  language: 'json'
}
  1. Provide an option to allow extension monopolize auto completion item list for specific document. Thus the completion item list shouldn't merge all extensions completion items. The highest score should be applied.
json under-discussion

Most helpful comment

The usage-analysis proposals only show up if we don't have a schema configured for that file. The idea is that they are a fallback if there is no understanding of structure. IMO it would be nice if we could signal that to the completion processor. They are like the textual proposals which are also special.

What you can do right now is:

  • register a schema for your file patterns **/*.{interface,template}.json. That schema can be empty or minimal (e.g. just scecify that the top level elemnt must be an object)
    See the jsonValidation contribution point on how you to register a schema from an extension
  • life with the usage proposals and just give your proposals a higher sort order

In the longer term, if JSON-LD is well established, we can also look into integrating JSON-LD into the language service

All 17 comments

(Experimental duplicate detection)
Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:

That's the old discussion of whether we allow language service to override existing ones. I'm curious to hear how this turns out. I don't think we have ever seen two completion providers working nicely together.

I don't think we have ever seen two completion providers working nicely together.

Open your eyes, there are many complementing providers, the obvious sample is plain word completion but there are many other, like path completions, emoji completions, UUID completions etc, etc. What doesn't make sense is to propose the same things another completion provider does..

The design is to be cooperative and we don't want to allow that one extension mutes another extension. Your language seems to be non cooperative, e.g you say that it's JSON but then you says it shouldn't behave like JSON. That's questionable. Then, looking at your screen shot, you might just wanna tweak the sorting so that your items come first.

and it doesn't make sense to disable part feature of one extension for another.

It does make sense to have a setting, e.g that's what we are doing for formatting. In this case you should get JSON to make the fallback completion (Interface and Property are suggested based on usage-analysis and based on a schema) configurable.

path completions

It's inside the HTML/CSS completion's providers. So not two providers.
Let's say I add one path completion extension that parses HTML/CSS/JS/TS for path completions. Suddenly user gets 2 re-parsing happening on each stroke they type in these languages.

emoji completions

That's because Markdown extension doesn't register a completion provider. https://marketplace.visualstudio.com/items?itemName=bierner.emojisense does.

Let's say now I want to do PostCSS support. There's no way it can play nicely together with the CSS extension's completion provider. It does not understand PostCSS so completions will not trigger correctly 100% of time, and it shows a bunch of unhelpful diagnostics.

The design is to be cooperative and we don't want to allow that one extension mutes another extension.

But what's their options? If someone is building a PostCSS language server, should he carefully avoid whatever completion items that are already sent by the CSS language server, and try to send a giant PR to the CSS extension that makes it not fail for PostCSS?

Muting isn't really the problem here. There are two common situations:

  • I want to add a small completion participation like path completion. I can play nicely with the existing completion provider, but I don't want to re-parse the file all the time to get info intrinsic to the existing completion provider.
  • I want to take over the language. Like flow/postcss. People are now resorting to files.assoaciations (which is fine). Maybe that's the way to go, including *.css: 'postcss' in local settings.json?

Maybe that's the way to go, including *.css: 'postcss' in local settings.json?

Yep, people are already doing that: https://github.com/MhMadHamster/vscode-postcss-language#features and https://github.com/flowtype/flow-for-vscode#setup.

@jrieken I do agree with you that the design is to be cooperative, and the extensions should work together. In my opinion, the key is what does JSON behavior mean.

As we know, JSON-Schema describes what a JSON file looks like, it provides a way to make JSON match a specific structure. However, JSON-Schema is not the only way to do such work, JSON-LD is another one.

Usage-analysis is very useful, and it works well in most of time. However, here, in JSON-LD, it does a disservice. Its suggestion makes a JSON file invalid (just like an invalid JSON file which has conflict with JSON-Schema). Does JSON-LD behave like JSON? Absolutely! It's just JSON.

Summary: JSON-Schema is not the only standard for JSON, we should treat JSON-LD equally, just like we treat all extensions equally. JSON-LD isn't compatible with JSON-Schema or Usage-analysis, but it really behaves like JSON.

It's inside the HTML/CSS completion's providers. So not two providers.

@octref Please tame you excitement - I was not referring to HTML/CSS. For multiple years, while TypeScript/JavaScript had no support for this, there was an extension do this work and that's what extensions are for.

Summary: JSON-Schema is not the only standard for JSON, we should treat JSON-LD equally, just like we treat all extensions equally. JSON-LD isn't compatible with JSON-Schema or Usage-analysis, but it really behaves like JSON.

@Sneezry Thanks for clarifying. Is there a way for our JSON service to know when JSON-LD is used? Is the leading @type-property an indication or anything else inside the file expressing this?

@jrieken similar with $schema for JSON-Schema, JSON-LD has @context property.

Hi, everyone. Any update? Is it okay to stop the built-in JSON language server showing auto completion item when a JSON file contains @context property? If the solution has been accepted, I'm glad to make a PR. Thanks.

@context is a valid key for JSON files. I don't think it's reasonable to stop the whole JSON Language Service when such a key is seen.

Can you declare JSON-LD under another filetype, and map your local JSONs to it with files.associations?

@context is a valid key for JSON files.

Yes. However, general property doesn't start with @, @context most probably certify the documentation is JSON-LD file.

stop the whole JSON Language Service when such a key is seen.

Not stop the whole JSON Language Service, just stop auto completion item. Usage-analysis does a disservice in such case.

can you declare JSON-LD under another filetype

I do not think it makes sense. JSON-LD is a data structure of JSON, but not a unique file type. It is similar with JSON schema.

When seeing @context key, stop providing auto completion sounds like a very arbitrary rule to me. This makes JSON LS dependent on a third-party extension from marketplace for JSON-LD support. Meanwhile, the OOTB experience for VS Code would be bad if someone opens a JSON-LD file, or a file that resembles JSON-LD (I'm sure some API would return keys starting with @).

Maybe you should try @jrieken's suggestion:

you might just wanna tweak the sorting so that your items come first.

When seeing @context key, stop providing auto completion sounds like a very arbitrary rule to me.

I agree. The final solution to make it not arbitrary, is to add support for JSON-LD in the built-in JSON LS. Stop providing auto completion is a workround. However, does vscode team have any plan to support JSON-LD in short or long time? If the answer is positive, it's the best news.

you might just wanna tweak the sorting so that your items come first.

Please let me underline it again, usage-analysis does a disservice here. Shouldn't we stop the mistake before we can fix it?

The usage-analysis proposals only show up if we don't have a schema configured for that file. The idea is that they are a fallback if there is no understanding of structure. IMO it would be nice if we could signal that to the completion processor. They are like the textual proposals which are also special.

What you can do right now is:

  • register a schema for your file patterns **/*.{interface,template}.json. That schema can be empty or minimal (e.g. just scecify that the top level elemnt must be an object)
    See the jsonValidation contribution point on how you to register a schema from an extension
  • life with the usage proposals and just give your proposals a higher sort order

In the longer term, if JSON-LD is well established, we can also look into integrating JSON-LD into the language service

@aeschli thanks for your advice, your suggestion is very helpful.

@aeschli I have verified your solution works for me. I add configuration below in my package.json:

"jsonValidation": [
  {
    "fileMatch": "**/*.interface.json",
    "url": "./resources/EmptySchema.json"
  },
  {
    "fileMatch": "**/*.template.json",
    "url": "./resources/EmptySchema.json"
  }
]

An interesting thing I found is configuration below does NOT work for me:

"jsonValidation": [
  {
    "fileMatch": "**/*.{interface,template}.json",
    "url": "./resources/EmptySchema.json"
  }
]

Anyway, I really appreciate your help!

Oh, right, that's expected, we only support * in the pattern.

Thanks for trying this out. I'm closing the issue then.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

philipgiuliani picture philipgiuliani  路  3Comments

DovydasNavickas picture DovydasNavickas  路  3Comments

omidgolparvar picture omidgolparvar  路  3Comments

sirius1024 picture sirius1024  路  3Comments

ryan-wong picture ryan-wong  路  3Comments