Language grammars and syntax highlighting for mcfunction files.
This project provides two types of grammars: the default, version-agnostic grammar (shown below), and WIP version-specific grammars.
The extension language-mcfunction is available from the Marketplace: https://marketplace.visualstudio.com/items?itemName=arcensoth.language-mcfunction
It is recommended you use Package Control to manage the package:
- Install Package Control if it is not already present.
- Run the
Package Control: Add Repository
command and enterhttps://github.com/Arcensoth/language-mcfunction
to add the repository as a package. - Run the
Package Control: Install Package
and search forlanguage-mcfunction
to install it as you would a normal package.
This will keep the package updated with the repository automatically.
Otherwise you can clone the repository into user packages (e.g. %appdata%\Sublime Text 3\Packages
) and update it manually.
Here's an album with everything below.
- Comments and indentation:
# This is a comment
- Custom block comments:
#> This is a block heading
- Booleans:
true
/false
- Numbers:
20
/3.14
/.001
- Operations:
=
//=
/%=
/ etc - Ranges:
1..
/3.14..20
/...001
- Relative coordinates:
~
/~10
/~-4.5
- Local coordinates:
^
/^-1
/^.05
- Resource locations:
minecraft:chests/simple_dungeon
/#minecraft:wools
- Block predicates:
minecraft:dispenser[facing=up]
- Unquoted strings:
mypack.some.tag
/mypack.custom_crafting_marker
- Quoted strings with escaping:
"hello world"
/"CustomName With Spaces"
- Single-quoted strings:
'hello world'
/'{"text": "hello world"}'
- NBT compounds/lists:
{ Fire: 20s , NoGravity: true, Tags: [ "mytag" ] }
- NBT paths:
SelectedItem.Count
/RecordItem.tag.mycustomtag
- JSON/text components:
{"text": "hello world", "color": "blue"}
- UUIDs:
f7a39418-72ca-4bf2-bc7e-ba9df67a4707
0-0-0-0-0
- Fakeplayers:
#hidden
/$fakefoo
/%fakebar
- Base selectors:
@e
- Selectors with arguments:
@e[tag=foo]
/@e[tag=!foo]
- Literal arguments:
gamemode
/sort
- Numeric arguments:
x
/y
/z
/limit
- Range arguments:
distance
/level
- Resource location arguments:
type
- Unquoted string arguments:
tag
- Quoted string arguments:
name
- NBT compound arguments:
nbt
- Score arguments:
scores
- Advancement arguments:
advancements
- Literal arguments:
It's common for datapack developers to comment parts of their code with things like headings, parameters, return values, etc. To support these patterns for those who wish to use them, the grammar implements custom block comments. These types of comments are gated behind a vanilla-compatible alternate comment style.
The prefix #>
can be used to initiate a block comment:
#> This is a block heading
# All adjacent comments will be considered part of the block.
#
# So long as you keep comments attached, they will remain part of the block.
# This line no longer attached to the block.
#> But we can start a new block here!
Click here for a detailed example.
As of writing there is no documentation standard, however the grammar has the capacity to support this via block comments and alternate comment styles.
This is a generic "version-agnostic" grammar that does not target any particular version of Minecraft. As a result it may not be as accurate as version-specific grammars, however it will continue to work for multiple versions of the game.
The version-agnostic mcfunction
language should be active by default. It provides a decent fallback for otherwise unsupported versions of Minecraft. In order to do this, it must not assume any particular version. Because it cannot assume a version, it cannot provide context-sensitive highlighting.
In the future, the version-specific grammars will be preferred when available.
The version-specific grammars are currently under heavy development. These grammars are incomplete and experimental. They do not yet support the same feature set as the version-agnostic grammar. Please only use these grammars if you intend to contribute in some form, such as pull requests, bug reports, or general feedback. To use the version-specific grammars, you will need to build them and configure the extension yourself.
The version-specific grammars are partially generated based on Minecraft's generated data, which is available for Minecraft versions 1.13 and higher. They have context-sensitive highlighting and command validation comparable to the in-game command bar.
In VSCode, you can easily choose which version of mcfunction to use by changing the .mcfunction
extension association in your workspace settings:
"files.associations": {
"*.mcfunction": "mcfunction-snapshot"
}
This option can also be set on the user-level in settings.json
or folder-level in .vscode/settings.json
.
Currently available for the version-specific grammars.
Scopes have been assigned with user customization in mind. If your editor allows scope overrides, this will make it easy to customize your own colours for a variety of scopes.
- Customizing errors
- Customizing comments
- Customizing commands
- Customizing selectors
- Customizing NBT
- Customizing text components
- Customizing resource locations
- Customizing strings
- Customizing numbers
- Customizing tags, teams, and objectives
- Other customizable scopes
Short name | Full scope name | Examples |
---|---|---|
invalid |
invalid.illegal._.invalid.mcfunction |
execute (foo) |
underline |
markup.underline._.underline.mcfunction |
execute (foo) |
Short name | Full scope name | Examples |
---|---|---|
comment.plain |
comment._.plain.comment.mcfunction |
(# This is a plain comment) |
comment.block |
comment.block._.block.comment.mcfunction |
(#> This is part of a block comment) |
comment.block.symbol |
markup.list._.symbol.block.comment.mcfunction |
(#)> This is part of a block comment |
comment.block.prefix |
markup.list._.prefix.block.comment.mcfunction |
#(>) This is part of a block comment |
comment.block.heading_1 |
markup.bold._.heading_1.block.comment.mcfunction |
#> (This is part of a block comment) |
comment.block.heading_2 |
markup.list._.heading_2.block.comment.mcfunction |
#> (This is part of a block comment) |
comment.block.annotation.label |
markup.heading._.label.annotation.block.comment.mcfunction |
#> (@annotation) some annotation |
comment.block.annotation.text |
comment.block._.text.annotation.block.comment.mcfunction |
#> @annotation (some annotation) |
Short name | Full scope name | Examples |
---|---|---|
command |
keyword.control._.command.mcfunction |
(execute) as @a run (function) |
subcommand |
keyword.other._.subcommand.mcfunction |
execute (as) @a (run) function |
command.slash |
keyword.control._.command.mcfunction |
/ |
Short name | Full scope name | Examples |
---|---|---|
target_selector.base |
support.class._.base.target_selector.mcfunction |
@a |
target_selector.bracket |
support.class._.bracket.target_selector.mcfunction |
[] |
target_selector.equals |
support.class._.equals.target_selector.mcfunction |
= |
target_selector.comma |
support.class._.comma.target_selector.mcfunction |
, |
target_selector.not |
constant.character.escape._.not.target_selector.mcfunction |
! |
target_selector.param |
keyword.other._.param.target_selector.mcfunction |
tag / type |
score_map.bracket |
storage._.bracket.score_map.mcfunction |
{} |
score_map.equals |
storage._.equals.score_map.mcfunction |
= |
score_map.comma |
storage._.comma.score_map.mcfunction |
, |
advancement_map.bracket |
storage._.bracket.advancement_map.mcfunction |
{} |
advancement_map.equals |
storage._.equals.advancement_map.mcfunction |
= |
advancement_map.comma |
storage._.comma.advancement_map.mcfunction |
, |
Short name | Full scope name | Examples |
---|---|---|
nbt_compound.bracket |
storage._.bracket.nbt_compound.mcfunction |
{} |
nbt_compound.colon |
storage._.colon.nbt_compound.mcfunction |
: |
nbt_compound.comma |
storage._.comma.nbt_compound.mcfunction |
, |
nbt_list.bracket |
storage._.bracket.nbt_list.mcfunction |
[] |
nbt_list.comma |
storage._.comma.nbt_list.mcfunction |
, |
Short name | Full scope name | Examples |
---|---|---|
nbt_path.property |
string._.property.nbt_path.mcfunction |
(RecordItem) |
nbt_path.dot |
storage._.dot.nbt_path.mcfunction |
RecordItem(.)tag |
nbt_path.compound.bracket |
storage._.bracket.compound.nbt_path.mcfunction |
SelectedItem({)(}) |
nbt_path.index.bracket |
storage._.bracket.index.nbt_path.mcfunction |
Inventory([)(]) |
Short name | Full scope name | Examples |
---|---|---|
text_component.bracket |
storage._.bracket.text_component.mcfunction |
{}[] |
text_component.colon |
storage._.colon.text_component.mcfunction |
: |
text_component.comma |
storage._.comma.text_component.mcfunction |
, |
text_component.property |
string._.property.text_component.mcfunction |
text / color / selector |
text_component.property.color |
string._.color.property.text_component.mcfunction |
red / green / blue |
text_component.property.keybind |
string._.keybind.property.text_component.mcfunction |
key.drop / key.use |
text_component.property.event |
string._.event.property.text_component.mcfunction |
run_command / show_text |
Short name | Full scope name | Examples |
---|---|---|
resource_location.namespace |
entity.name.function._.namespace.resource_location.mcfunction |
(mypack):some/resource |
resource_location.colon |
entity.name.function._.colon.resource_location.mcfunction |
mypack(:)some/resource |
resource_location.path |
entity.name.function._.path.resource_location.mcfunction |
mypack:(some/resource) |
tagged_resource_location.hash |
entity.name.function._.hash.tagged_resource_location.mcfunction |
(#)mypack:some/resource |
tagged_resource_location.namespace |
entity.name.function._.namespace.tagged_resource_location.mcfunction |
#(mypack):some/resource |
tagged_resource_location.colon |
entity.name.function._.colon.tagged_resource_location.mcfunction |
#mypack(:)some/resource |
tagged_resource_location.path |
entity.name.function._.path.tagged_resource_location.mcfunction |
#mypack:(some/resource) |
Short name | Full scope name | Examples |
---|---|---|
string |
string._.string.mcfunction |
("hello world") |
string_escape |
constant.character.escape._.string_escape.mcfunction |
"hello(\n)newline" |
word |
string._.word.mcfunction |
foo / foo_bar |
keyword |
keyword._.word.mcfunction |
nearest / creative |
Short name | Full scope name | Examples |
---|---|---|
number |
constant.numeric._.number.mcfunction |
0 / 123 / -99 |
range.minimum |
constant.numeric._.minimum.range.mcfunction |
(10)..20 |
range.maximum |
constant.numeric._.maximum.range.mcfunction |
10..(20) |
range.ellipsis |
keyword.control._.ellipsis.range.mcfunction |
10(..)20 |
position.absolute.number |
constant.numeric._.number.absolute.position.mcfunction |
(10) ~20 (30) |
position.relative.operator |
keyword.control._.operator.relative.position.mcfunction |
10 (~)20 30 |
position.relative.number |
constant.numeric._.number.relative.position.mcfunction |
10 ~(20) 30 |
position.local.operator |
keyword.control._.operator.local.position.mcfunction |
(^)10 (^)20 (^)30 |
position.local.number |
constant.numeric._.number.local.position.mcfunction |
^(10) ^(20) ^(30) |
Short name | Full scope name | Examples |
---|---|---|
entity_tag |
entity.other.attribute-name._.entity_tag.mcfunction |
mypack.some.tag |
scoreboard_team |
entity.other.attribute-name._.scoreboard_team.mcfunction |
mypack.blue |
scoreboard_objective |
entity.other.attribute-name._.scoreboard_objective.mcfunction |
mypack.points |
score_holder.all |
support.class._.all.score_holder.mcfunction |
* |
score_holder.fakeplayer |
support.class._.fakeplayer.score_holder.mcfunction |
#temp / $mypack.calc |
Short name | Full scope name | Examples |
---|---|---|
boolean |
constant.numeric._.boolean.mcfunction |
true / false |
entity_anchor |
constant.numeric._.entity_anchor.mcfunction |
eyes / feet |
swizzle |
constant.numeric._.swizzle.mcfunction |
y / xz / xyz |
target.uuid |
support.class._.uuid.target.mcfunction |
f7a39418-72ca-4bf2-bc7e-ba9df67a4707 / 0-0-0-0-0 |
target.player_name |
support.class._.uuid.target.mcfunction |
Arcensoth / some_guy |
generic.dict.bracket |
storage._.bracket.dict.generic.mcfunction |
({) key: value (}) |
generic.dict.content |
string._.content.dict.generic.mcfunction |
{( key: value )} |
generic.list.bracket |
storage._.bracket.list.generic.mcfunction |
([) item, item (]) |
generic.list.content |
string._.content.list.generic.mcfunction |
[( item, item )] |
Contributions are welcome; see CONTRIBUTING.md
.
- https://github.com/Arcensoth/language-tmdemo
- https://github.com/github/linguist/blob/master/CONTRIBUTING.md
- https://github.com/github/linguist/blob/master/vendor/README.md
- https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide
- https://code.visualstudio.com/api/extension-guides/icon-theme
- https://gist.github.com/Aerijo/b8c82d647db783187804e86fa0a604a1
- https://macromates.com/manual/en/language_grammars
- https://regex101.com/