textmate / yaml.tmbundle

TextMate support for YAML
17 stars 17 forks source link

YAML syntax highlight is wrong on keys that happen to be keywords #34

Closed alexr00 closed 4 years ago

alexr00 commented 4 years ago

From @leafac in https://github.com/microsoft/vscode/issues/94738

Issue Type: Bug

The keys are highlighted as keywords, for example, consider the keyword on:

on: push
all: Are
other: highlighted
keys: differently
Screen Shot 2020-04-09 at 12 08 04 AM

(For example, you may see the on keyword as a key in the configuration for a GitHub Action.)

VS Code version: Code 1.44.0 (2aae1f26c72891c399f860409176fe435a154b13, 2020-04-08T08:23:56.137Z) OS version: Darwin x64 19.4.0

System Info |Item|Value| |---|---| |CPUs|Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz (4 x 2300)| |GPU Status|2d_canvas: enabled
flash_3d: enabled
flash_stage3d: enabled
flash_stage3d_baseline: enabled
gpu_compositing: enabled
metal: disabled_off
multiple_raster_threads: enabled_on
oop_rasterization: disabled_off
protected_video_decode: unavailable_off
rasterization: enabled
skia_renderer: disabled_off_ok
video_decode: enabled
viz_display_compositor: enabled_on
viz_hit_test_surface_layer: disabled_off_ok
webgl: enabled
webgl2: enabled| |Load (avg)|2, 2, 2| |Memory (System)|8.00GB (0.56GB free)| |Process Argv|| |Screen Reader|no| |VM|0%|
Extensions (5) Extension|Author (truncated)|Version ---|---|--- githistory|don|0.6.3 prettier-vscode|esb|4.1.1 latex-workshop|Jam|8.8.0 code-spell-checker|str|1.8.0 code-spell-checker-portuguese|str|0.1.2
sanssecours commented 4 years ago

That is not really a bug, as far as I can tell. The word on is an alternative way to specify the boolean value true according to the YAML spec.

leafac commented 4 years ago

But that’s only when the keyword is used in a value position, to the right of the :, for example, lights: on. In this case it’s a key, to the left of the :, that happens to also be a keyword.

sanssecours commented 4 years ago

The text on is a plain scalar, (that usually does represent the value true). If it is used as a value or as key does not make a difference, as far as I know. If you want a scalar that represents the string on you usually should quote it (e.g. "on", 'on') or use a tag such as !!str. Anyway, if on is a string or not also depends on the schema and the version of YAML you are using. For example on definitely represents the value true, if you uses the current version of the YAML library shipped with CPython (3.8.2). The following Python code:

from yaml import safe_load

print(safe_load('on: on'))
print(safe_load("'on': 'on'"))
print(safe_load('on: !!str on'))

prints the following text on my machine:

{True: True}
{'on': 'on'}
{True: 'on'}

I can totally understand that you were surprised that on (usually) has a special meaning in YAML though 😊.

leafac commented 4 years ago

Thanks for the explanation. You can close the issue if you want (I can’t because the issue wasn’t created by me.)

It seems that different libraries don’t agree on what YAML means:

JavaScript

> require("js-yaml").load("on: on")
{ on: 'on' }
> require("yaml").parse("on: on")
{ on: 'on' }

Ruby

> require "yaml"
> YAML.load("on: on")
=> {true=>true}

In any case, from a syntax highlighter’s perspective, it makes more sense to do what yaml.tmbundle does: highlight on differently regardless of where it appears.

geekley commented 2 years ago

Interesting. It seems YAML spec itself (at least the grammar) doesn't strictly define what is to be interpreted as !!bool. YAML 1.2.2 spec does define a recommended Core Schema which only specifies: true | True | TRUE | false | False | FALSE = tag:yaml.org,2002:bool However, a working draft for YAML 1.1 does specify many more options in the regex (and y|n as canonical): y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF = tag:yaml.org,2002:bool I guess it makes sense that it's debatable which is "more right".

Well, if it was up to me I would at least distinguish true|false from the rest, so that themes|users could decide what applies. E.g: entity.name.tag.yaml constant.language.boolean.strict.yaml (true|True|TRUE|false|False|FALSE) entity.name.tag.yaml constant.language.boolean.lenient.yaml (others) But whatever.