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 multiple items in context triggering a warning #11

Merged
merged 2 commits into from
Mar 22, 2020
Merged

Conversation

rchl
Copy link
Member

@rchl rchl commented Mar 19, 2020

If there was more than one object in context array, and those didn't
follow the same schema then warning was triggered.

@rchl rchl requested a review from predragnikolic March 19, 2020 12:40
@rchl
Copy link
Member Author

rchl commented Mar 19, 2020

Thanks to @AmjadHD for creating those schemas.

"type": "object"
"type": "object",
"properties": {
"additionalProperties": false,
Copy link
Member

@rwols rwols Mar 19, 2020

Choose a reason for hiding this comment

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

I don't agree with this decision to disallow additional properties. Various plugins out in the wild may use a sublime-project to store arbitrary data. Same goes for sublime-build files.

Disallowing additional properties in sublime-keymap, sublime-mousemap and sublime-completion files makes sense though.

Copy link
Member Author

Choose a reason for hiding this comment

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

But plugins add those to settings object, don't they? And settings object allows additional properties.

Copy link
Member Author

Choose a reason for hiding this comment

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

As for sublime-build, do you have any examples where this is done currently?

Copy link
Member

Choose a reason for hiding this comment

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

For sublime-build files, the value for the "target"key is a WindowCommand. It receives all key-value pairs of the invoked build target in **kwargs.
For instance, I utilize this fact in my CMakeBuilder plugin to pass along build artefact information that I store in the ST build system.

For sublime-project files, you can get the entire content via window.project_data(). It's a Python dictionary. You can put anything in there. And then you can store it with window.set_project_data(...). ST3 won't complain if there are unknown keys.

Copy link
Member Author

@rchl rchl Mar 20, 2020

Choose a reason for hiding this comment

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

For sublime-build files, the value for the "target"key is a WindowCommand.

From the schema's perspective, it's a string though, no?
And target is already in the schema:

"target": {
"markdownDescription": "The command to run when the build system is invoked. The default value of exec allows use of the additional options specified in [exec Target Options](https://www.sublimetext.com/docs/3/build_systems.html#exec_options). If a value other than `exec` is specified, none of the options in exec Target Options will do anything. See the [Advanced Example](https://www.sublimetext.com/docs/3/build_systems.html#advanced_example) for a complete example.",
"type": "string"
},

For sublime-project files, you can get the entire content via window.project_data(). It's a Python dictionary.

Actually for sublime-project.json, the additionalProperties key is in the wrong place which makes it work as you would expect. It's defined inside properties object which basically means that it defines a property called literally additionalProperties rather than functioning as limiter. If it would be defined in the root of the schema then it would actually restrict properties that are allowed on the object.
So, it works as expected right now. I'll just remove that key.

Copy link
Member

Choose a reason for hiding this comment

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

From the schema's perspective, it's a string though, no?

Ah, yes. I did not explain myself very well. You can have a build system like this:

{
  "target": "make_thing",
  "foo": "bar",
  "selector": "source.python",
  "some_number": 42
}

and define a command like this:

import sublime_plugin


class MakeThingCommand(sublime_plugin.WindowCommand):

    def run(self, *args, **kwargs):
        foo = kwargs.get("foo")  # will have the value "bar"
        selector = kwargs.get("selector")  # will have the value "source.python"
        some_number = kwargs.get("some_number")  # will have the value 42

Copy link
Member

Choose a reason for hiding this comment

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

So basically, ST does this: If "target" is present, then invoke the corresponding command with the rest of the key-value pairs. Otherwise, invoke ExecCommand with the rest of the key-value pairs.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I get it now. But in fact, sublime-build schema doesn't and never had additionalProperties: false so I think we are good. :)

schemas/sublime-settings.json Outdated Show resolved Hide resolved
schemas/sublime-settings.json Outdated Show resolved Hide resolved
schemas/sublime-settings.json Outdated Show resolved Hide resolved
schemas/sublime-settings.json Outdated Show resolved Hide resolved
schemas/sublime-settings.json Show resolved Hide resolved
schemas/sublime-settings.json Outdated Show resolved Hide resolved
schemas/sublime-settings.json Show resolved Hide resolved
@rwols
Copy link
Member

rwols commented Mar 21, 2020

I have played around with this branch. Overall it's pretty cool, especially for keybindings. I hope we can add way more stuff, especially for things like color schemes and themes which will help tremendously.

One thing that's annoying is that completions add two double-quotes at the beginning. When I type this (the | is the cursor)

	{"k|"}

I end up with this:

	{""keys": [|]"}

This is understandable, as the completion item is:

{
	'label': 'keys',
	'insertTextFormat': 2,
	'insertText': '"keys": [$1]',
	'textEdit':
	{
		'range':
		{
			'start': {'line': 17, 'character': 2},
			'end': {'line': 17, 'character': 5}
		},
		'newText': '"keys": [$1]'
	}
}

What this textEdit says is to remove the "k" part and replace it with "keys": []. We would have to add more workarounds in LSP/plugin/core/completion.py for this. The PR in sublimelsp/LSP#866 probably already solves this automatically.


Another thing I would suggest is to put "$schema": "http://json-schema.org/draft-07/schema", in every file at the top so that we get completions for the schema files.

@rchl
Copy link
Member Author

rchl commented Mar 21, 2020

have played around with this branch. Overall it's pretty cool, especially for keybindings. I hope we can add way more stuff, especially for things like color schemes and themes which will help tremendously.

It's time-consuming to create schemas but yes, we can do cool stuff with them. Even provide completions based on command type for keybindings (current schema is just the simplest possible that I had time to do and doesn't handle that).

One thing that's annoying is that completions add two double-quotes at the beginning.

Yes, the completion behavior is broken. I wonder if it has something to do with not respecting triggerCharacters that server specifies. This server returns

        "completionProvider": {
            "resolveProvider": false,
            "triggerCharacters": [
                "\"",
                ":"
            ]
        },

from initialize.

But in any case, I won't look into that unless new completions code still has problems with it.

@deathaxe
Copy link
Contributor

I am not sure about whether it's worth adding schemes for sublime-settings files for two reasons:

  1. The static definition in this repo won't ever be able to reflect the keys and settings of all package related settings. Providing completions/validation for Preferences.sublime-settings only feels incomplete then.
  2. The resulting completions and info popups interfer with PackageDev, which provides tooltips/completions dynamically created from sublime-settings files.

In a perfect world LSP-json would at least provide the ability to collect json schemes from all packages so authors can provide plugin-specific completion/tooltip infos. But in a real world anything else then something being created from sublime-settings files itself will always be out-dated.

@rchl
Copy link
Member Author

rchl commented Mar 21, 2020

2. The resulting completions and info popups interfer with PackageDev, which provides tooltips/completions dynamically created from sublime-settings files.

As far as completions and tooltips, PackageDev seems to "win the battle" and show its own, overriding ones that LSP-json provides.

I've created PR in PackageDev to add a setting to disable PackageDev's completions (and should also mention tooltips there). Then it would be user's choice what he prefers.

Currently PackageDev does a better job of presenting tooltips as it shows default value and nicer formatting but LSP-json could do that as well. The information is there and formatting can be improved as it can use markdown too.

Also, LSP-json has more potential, even if it's not there yet with all it could do.
What it already does better is:

  • Providing autocomplete suggestions with all allowed values (PackageDev doesn't have knowledge about those apart from default value).
  • With detailed schema, it can provide contextual suggestions that change depending on value of another key.
  • It validates values - if you use string where array is required or just put a value that is not one of allowed values it will warn about it

In a perfect world LSP-json would at least provide the ability to collect json schemes from all packages so authors can provide plugin-specific completion/tooltip infos. But in a real world anything else then something being created from sublime-settings files itself will always be out-dated.

Yes, we've mentioned that in PR. And I agree that it would never be 100% complete if authors would have to opt-in into that so not sure if it's worth investing time in it.

This package could also do what PackageDev is doing and create schemas dynamically from all discovered *.sublime-settings. It wouldn't be as complete as manually created schema but still useful.

 - Add $schema to all schemas and unify whitespace
 - Remove `additionalProperties: false` from sublime-project schema because:
   a) we don't actually want to limit keys to only known names
   b) it was defined in the wrong spot so it didn't function as one would
      expect (it was just an extra property called literally `additionalProperties`).
 - Add enum descriptions in sublime-settings schema
 - Use markdown for rendering descriptions
 - Added schema definitions created by AmjadHD
   Original schemas from https://github.com/AmjadHD/sublime_json_schemas
 - Fix multiple items in context triggering a warning
   If there was more than one object in context array, and those didn't
   follow the same schema then warning was triggered.
@rchl rchl force-pushed the fix/keymap-context branch from f2a6ab4 to 3617e0d Compare March 21, 2020 22:04
@deathaxe
Copy link
Contributor

This package could also do what PackageDev is doing and create schemas dynamically from all discovered *.sublime-settings. It wouldn't be as complete as manually created schema but still useful.

Interesting idea.

Basically agree with the other arguments - lsp may be more powerful especially in long term with regards to object/array-like values such as the "clients" key in the LSP.sublime-settings.

We'd just need a good tooling in order to create markdown descriptions. Writing such in a json file is just horrible.

@rchl
Copy link
Member Author

rchl commented Mar 22, 2020

As far as completions and tooltips, PackageDev seems to "win the battle" and show its own, overriding ones that LSP-json provides.

Actually it seems to be a bit random. Timing specific probably.

@rchl rchl merged commit a219d56 into master Mar 22, 2020
@rchl rchl deleted the fix/keymap-context branch March 22, 2020 18:28
@rchl rchl restored the fix/keymap-context branch March 22, 2020 18:31
@rchl rchl deleted the fix/keymap-context branch March 22, 2020 18:32
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.

5 participants