From 5d2db397c49e5b526154b66daa2cd9d8d05a403d Mon Sep 17 00:00:00 2001
From: zml
Date: Tue, 20 Dec 2022 20:01:43 -0800
Subject: [PATCH] yaml: whitespace/comment fixes
---
.../configurate/yaml/MergeTag.java | 26 ++++
.../configurate/yaml/ScalarStyle.java | 2 +-
.../spongepowered/configurate/yaml/Tag.java | 10 +-
.../configurate/yaml/Yaml11Tags.java | 15 +--
.../yaml/YamlConfigurationLoader.java | 10 +-
.../configurate/yaml/YamlParserComposer.java | 34 ++++--
.../configurate/yaml/YamlVisitor.java | 46 ++++---
.../configurate/yaml/IntegrationTests.groovy | 6 +-
.../yaml/YamlParserComposerTest.groovy | 11 +-
.../configurate/yaml/YamlTest.groovy | 52 +++++---
.../configurate/yaml/essx-example.yml | 112 +++++++++---------
.../configurate/yaml/essx-legacy.yml | 2 +-
.../configurate/yaml/mobcleaner-example.yml | 8 ++
13 files changed, 204 insertions(+), 130 deletions(-)
create mode 100644 format/yaml/src/main/java/org/spongepowered/configurate/yaml/MergeTag.java
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/MergeTag.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/MergeTag.java
new file mode 100644
index 000000000..664cc66ce
--- /dev/null
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/MergeTag.java
@@ -0,0 +1,26 @@
+/*
+ * Configurate
+ * Copyright (C) zml and Configurate contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.spongepowered.configurate.yaml;
+
+final class MergeTag {
+
+ static final MergeTag INSTANCE = new MergeTag();
+
+ private MergeTag() {
+ }
+
+}
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/ScalarStyle.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/ScalarStyle.java
index e4a64aff0..4c462e2dc 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/ScalarStyle.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/ScalarStyle.java
@@ -113,7 +113,7 @@ static ScalarStyle fromSnakeYaml(final DumperOptions.ScalarStyle style) {
}
static {
- for (ScalarStyle style : values()) {
+ for (final ScalarStyle style : values()) {
BY_SNAKE.put(style.snake, style);
}
}
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Tag.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Tag.java
index 40fc2d9de..8dd8ffdd4 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Tag.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Tag.java
@@ -69,7 +69,12 @@ public String toString(final String own) {
this(tagUri, supportedTypes, pattern, null);
}
- Scalar(final URI tagUri, final Set> supportedTypes, final @Nullable Pattern pattern, final @Nullable ScalarStyle preferredScalarStyle) {
+ Scalar(
+ final URI tagUri,
+ final Set> supportedTypes,
+ final @Nullable Pattern pattern,
+ final @Nullable ScalarStyle preferredScalarStyle
+ ) {
super(tagUri, supportedTypes);
this.pattern = pattern;
this.preferredScalarStyle = preferredScalarStyle;
@@ -89,7 +94,8 @@ public String toString(final String own) {
}
/**
- * Get the preferred scalar style to use for this type, when none is specifically used.
+ * Get the preferred scalar style to use for this type, when none is
+ * specifically used.
*
* @return the preferred scalar style
* @since 4.2.0
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Yaml11Tags.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Yaml11Tags.java
index 6b0420168..5a319df9d 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Yaml11Tags.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/Yaml11Tags.java
@@ -73,15 +73,16 @@ public String toString(final byte[] own) {
*
* @implNote Canonically, these are y|n in YAML 1.1, but because YAML 1.2
* will only support true|false, we will treat those as the default
- * output format.
+ * output format. We also modify the regex to only automatically match
+ * true/false and on/off in order to avoid cases of confusion (such as
+ * the classic Norway problem).
* @see tag:yaml.org,2002:bool
* @since 4.2.0
*/
public static final Tag.Scalar BOOL = new Tag.Scalar(
yamlOrg("bool"),
UnmodifiableCollections.toSet(Boolean.class),
- Pattern.compile("y|Y|yes|Yes|YES|n|N|no|No|NO"
- + "|true|True|TRUE|false|False|FALSE"
+ Pattern.compile("true|True|TRUE|false|False|FALSE"
+ "|on|On|ON|off|Off|OFF")
) {
private final Set trues = UnmodifiableCollections.toSet(
@@ -189,13 +190,13 @@ public String toString(final Number own) {
// used as map key, where the next node will be a reference that should be merged in to this node
@Override
- public Object fromString(final String input) throws ParsingException {
- throw new ParsingException(ParsingException.UNKNOWN_POS, ParsingException.UNKNOWN_POS, null, "Merge keys are not yet implemented", null);
+ public Object fromString(final String input) {
+ return MergeTag.INSTANCE;
}
@Override
- public String toString(final Object own) {
- return own.toString();
+ public String toString(final Object own) throws ParsingException {
+ throw new ParsingException(ParsingException.UNKNOWN_POS, ParsingException.UNKNOWN_POS, null, "Merge keys cannot be serialized", null);
}
};
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConfigurationLoader.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConfigurationLoader.java
index 59b79208f..5e8696fc4 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConfigurationLoader.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConfigurationLoader.java
@@ -30,8 +30,8 @@
import org.spongepowered.configurate.util.UnmodifiableCollections;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
-import org.yaml.snakeyaml.reader.StreamReader;
import org.yaml.snakeyaml.events.DocumentStartEvent;
+import org.yaml.snakeyaml.reader.StreamReader;
import java.io.BufferedReader;
import java.io.Writer;
@@ -210,6 +210,8 @@ protected void populate(final LoaderOptionSource options) {
if (declared != null) {
this.style = declared;
}
+
+ this.enableComments = options.getBoolean(false, "yaml", "comments-enabled");
}
/**
@@ -317,7 +319,6 @@ public YamlConfigurationLoader build() {
private final DumperOptions options;
private final YamlVisitor visitor;
private final @Nullable NodeStyle defaultNodeStyle;
- private final boolean enableComments;
private YamlConfigurationLoader(final Builder builder) {
super(builder, new CommentHandler[] {CommentHandlers.HASH});
@@ -326,19 +327,18 @@ private YamlConfigurationLoader(final Builder builder) {
opts.setDefaultFlowStyle(NodeStyle.asSnakeYaml(builder.nodeStyle()));
opts.setProcessComments(builder.commentsEnabled());
this.defaultNodeStyle = builder.nodeStyle();
- this.enableComments = builder.commentsEnabled();
this.options = opts;
this.loader = new LoaderOptions()
.setAcceptTabs(true)
.setProcessComments(builder.commentsEnabled());
this.loader.setCodePointLimit(Integer.MAX_VALUE);
- this.visitor = new YamlVisitor(this.enableComments, true, Yaml11Tags.REPOSITORY);
+ this.visitor = new YamlVisitor(true, Yaml11Tags.REPOSITORY);
}
@Override
protected void loadInternal(final CommentedConfigurationNode node, final BufferedReader reader) throws ParsingException {
// Match the superclass implementation, except we substitute our own scanner implementation
- final YamlParserComposer parser = new YamlParserComposer(new StreamReader(reader), this.loader, Yaml11Tags.REPOSITORY, this.enableComments);
+ final YamlParserComposer parser = new YamlParserComposer(new StreamReader(reader), this.loader, Yaml11Tags.REPOSITORY);
parser.singleDocumentStream(node);
}
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlParserComposer.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlParserComposer.java
index 31d5d2d30..1763af4c2 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlParserComposer.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlParserComposer.java
@@ -66,7 +66,6 @@ final class YamlParserComposer extends ParserImpl {
private static final int FRAME_STACK_INCREMENT = 8;
private @Nullable StringBuilder commentCollector;
- private final boolean processComments;
private final boolean stripLeadingCommentWhitespace = true;
final Map aliases = new HashMap<>();
final TagRepository tags;
@@ -75,9 +74,8 @@ final class YamlParserComposer extends ParserImpl {
private Frame[] frames = new Frame[INITIAL_STACK_SIZE];
private int framePointer = -1;
- YamlParserComposer(final StreamReader reader, final LoaderOptions opts, final TagRepository tags, final boolean enableComments) {
+ YamlParserComposer(final StreamReader reader, final LoaderOptions opts, final TagRepository tags) {
super(new ScannerImpl(reader, opts));
- this.processComments = enableComments;
this.tags = tags;
}
@@ -226,6 +224,9 @@ static class Frame {
static final int SUPPRESS_COMMENTS = 1; // whether to associate comment events with this node
static final int SAVE_NODE = 1 << 1; // don't clear node when popping
+ static final int MERGE_REFERENCE_VALUE = 1 << 2; // when values have an anchor
+
+ static final int UNINHERITABLE_FLAGS = MERGE_REFERENCE_VALUE;
@MonotonicNonNull ComposerState state;
@@ -236,13 +237,13 @@ static class Frame {
* tag resolution.
*/
@Nullable Tag resolvedTag;
- ConfigurationNode node;
+ @MonotonicNonNull ConfigurationNode node;
int flags;
void init(final ComposerState state, final Frame parent) {
this.state = state;
this.node = parent.node;
- this.flags = parent.flags;
+ this.flags = parent.flags & ~UNINHERITABLE_FLAGS;
this.resolvedTag = null;
}
@@ -323,10 +324,6 @@ void applyComment(final @Nullable String comment, final ConfigurationNode node)
}
void collectComments() {
- if (!this.processComments) {
- return;
- }
-
while (this.peekEvent().is(Event.ID.Comment)) {
final CommentEvent event = (CommentEvent) this.getEvent();
if (event.getCommentType() != CommentType.BLANK_LINE) {
@@ -342,6 +339,10 @@ void collectComments() {
} else {
commentCollector.append(event.getValue());
}
+ } else if (this.commentCollector != null
+ && this.commentCollector.length() > 0
+ && this.peekEvent().is(Event.ID.Comment)) { // mid-comment blank line
+ this.commentCollector.append("\n");
}
}
}
@@ -607,6 +608,11 @@ public Frame accept(final Frame head, final YamlParserComposer self) throws Pars
if (keyHolder == null) {
throw new IllegalStateException("null keyHolder");
}
+ // if merge key, set a flag on the next value state
+ if (keyHolder.ownHint(YamlConfigurationLoader.TAG) == Yaml11Tags.MERGE) {
+ head.addFlag(Frame.MERGE_REFERENCE_VALUE);
+ }
+
final @Nullable Object key = keyHolder.raw();
if (key == null) {
throw head.makeError(self.scanner.peekToken().getStartMark(), "'null' is not permitted as a mapping key", null);
@@ -683,8 +689,14 @@ private Alias() {
if (target == null) {
throw head.makeError(event.getStartMark(), "Unknown anchor '" + event.getAnchor() + "'", null);
}
- head.node.from(target); // TODO: Reference node types
- head.node.hint(YamlConfigurationLoader.ANCHOR_ID, null); // don't duplicate alias
+ final ConfigurationNode into;
+ if (head.hasFlag(Frame.MERGE_REFERENCE_VALUE)) {
+ into = head.node.parent();
+ } else {
+ into = head.node;
+ }
+ into.from(target); // TODO: Reference node types
+ into.hint(YamlConfigurationLoader.ANCHOR_ID, null); // don't duplicate alias
return null;
}
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlVisitor.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlVisitor.java
index 39b815be6..038beeebf 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlVisitor.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlVisitor.java
@@ -52,7 +52,7 @@ final class YamlVisitor implements ConfigurationVisitor && this.enableComments) {
+ if (node instanceof CommentedConfigurationNodeIntermediary<@NonNull ?> && state.options.isProcessComments()) {
final @Nullable String comment = ((CommentedConfigurationNodeIntermediary<@NonNull ?>) node).comment();
if (comment != null) {
- if (this.shouldPadComments && node != state.start && !node.parent().isList()) {
- // todo: try and avoid emitting a blank line when we're the first element of a mapping?
- state.emit(WHITESPACE);
+ if (this.shouldPadComments && node != state.start) {
+ if (!state.first) {
+ if (!node.parent().isList()) {
+ state.emit(WHITESPACE);
+ }
+ } else {
+ state.first = false;
+ }
}
for (final String line : COMMENT_SPLIT.split(comment, -1)) {
if (line.isEmpty()) {
@@ -111,13 +114,14 @@ public void enterNode(final ConfigurationNode node, final State state) throws Co
@Override
public void enterMappingNode(final ConfigurationNode node, final State state) throws ConfigurateException {
final TagRepository.AnalyzedTag analysis = this.tags.analyze(node);
+ state.first = true;
state.emit(new MappingStartEvent(
this.anchor(node),
analysis.actual().tagUri().toString(),
analysis.implicit(),
null,
null,
- NodeStyle.asSnakeYaml(this.determineStyle(node, state))
+ NodeStyle.asSnakeYaml(state.determineStyle(node))
));
}
@@ -130,7 +134,7 @@ public void enterListNode(final ConfigurationNode node, final State state) throw
analysis.implicit(),
null,
null,
- NodeStyle.asSnakeYaml(this.determineStyle(node, state))
+ NodeStyle.asSnakeYaml(state.determineStyle(node))
));
}
@@ -168,6 +172,7 @@ public void enterScalarNode(final ConfigurationNode node, final State state) thr
@Override
public void exitMappingNode(final ConfigurationNode node, final State state) throws ConfigurateException {
+ state.first = false; // only true if empty map
state.emit(MAPPING_END);
}
@@ -181,29 +186,32 @@ public Void endVisit(final State state) {
return null;
}
- private @Nullable NodeStyle determineStyle(final ConfigurationNode node, final State state) {
- // todo: some basic rules:
- // - if a node has any children with comments, convert it to block style
- // - when the default style is `AUTO` and `flowLevel` == 0,
- final @Nullable NodeStyle style = node.hint(YamlConfigurationLoader.NODE_STYLE);
- return style == null ? state.defaultStyle : style;
- }
-
private @Nullable String anchor(final ConfigurationNode node) {
return node.hint(YamlConfigurationLoader.ANCHOR_ID);
}
- static class State {
+ static final class State {
private final Emitter emit;
+ final DumperOptions options;
@Nullable ConfigurationNode start;
final @Nullable NodeStyle defaultStyle;
ConfigurationNode mapKeyHolder;
+ boolean first; // reset to true at the beginning of each mapping node
State(final DumperOptions options, final Writer writer, final @Nullable NodeStyle defaultStyle) {
this.emit = new Emitter(writer, options);
+ this.options = options;
this.defaultStyle = defaultStyle;
}
+ @Nullable NodeStyle determineStyle(final ConfigurationNode node) {
+ // todo: some basic rules:
+ // - if a node has any children with comments, convert it to block style
+ // - when the default style is `AUTO` and `flowLevel` == 0,
+ final @Nullable NodeStyle style = node.hint(YamlConfigurationLoader.NODE_STYLE);
+ return style == null ? this.defaultStyle : style;
+ }
+
public void emit(final Event event) throws ConfigurateException {
try {
this.emit.emit(event);
diff --git a/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/IntegrationTests.groovy b/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/IntegrationTests.groovy
index 70d77e33a..54729b001 100644
--- a/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/IntegrationTests.groovy
+++ b/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/IntegrationTests.groovy
@@ -28,7 +28,7 @@ class IntegrationTests implements YamlTest {
@Test
void testEssentialsXDefault() {
- def input = this.class.getResourceAsStream("essx-example.yml").text
+ def input = this.class.getResourceAsStream("essx-example.yml").getText('utf-8')
def node = parseString(input)
def serialized = dump(node)
@@ -38,7 +38,7 @@ class IntegrationTests implements YamlTest {
@Test
void testEssentialsXLegacy() {
- def input = this.class.getResourceAsStream("essx-legacy.yml").text
+ def input = this.class.getResourceAsStream("essx-legacy.yml").getText('utf-8')
def node = parseString(input)
def serialized = dump(node)
@@ -48,7 +48,7 @@ class IntegrationTests implements YamlTest {
@Test
void testMobCleaner() {
- def input = this.class.getResourceAsStream("mobcleaner-example.yml").text
+ def input = this.class.getResourceAsStream("mobcleaner-example.yml").getText('utf-8')
def node = parseString(input)
def serialized = dump(node)
diff --git a/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlParserComposerTest.groovy b/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlParserComposerTest.groovy
index a07568110..983dd1731 100644
--- a/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlParserComposerTest.groovy
+++ b/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlParserComposerTest.groovy
@@ -191,8 +191,6 @@ class YamlParserComposerTest implements YamlTest {
# - def
"""
- println dump(result)
-
assertThat(result.node('hello').comment())
.isEqualTo("the greetings")
}
@@ -200,13 +198,12 @@ class YamlParserComposerTest implements YamlTest {
// Test that implicit tags are resolved properly
@Test
- @Disabled("not yet implemented")
void testMergeKey() {
def result = parseString """\
src: &ref
old: merged
dest:
- >>: *ref
+ <<: *ref
new: added
""".stripIndent(true)
@@ -219,7 +216,7 @@ class YamlParserComposerTest implements YamlTest {
}
@Test
- void testYIsBooleanForSomeReason() {
+ void testYIsNotBoolean() {
def result = parseString """\
asVal: y
y: asKey
@@ -229,9 +226,9 @@ class YamlParserComposerTest implements YamlTest {
extracting { it.virtual() }
.is(false)
extracting { it.raw() }
- .isEqualTo(true)
+ .isEqualTo("y")
}
- assertThat(result.node(true)).with {
+ assertThat(result.node("y")).with {
extracting { it.virtual() }
.is(false)
extracting { it.raw() }
diff --git a/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlTest.groovy b/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlTest.groovy
index c92588aff..3f9a81291 100644
--- a/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlTest.groovy
+++ b/format/yaml/src/test/groovy/org/spongepowered/configurate/yaml/YamlTest.groovy
@@ -19,6 +19,9 @@ package org.spongepowered.configurate.yaml
import static org.junit.jupiter.api.Assertions.assertNotNull
import org.spongepowered.configurate.CommentedConfigurationNode
+import org.yaml.snakeyaml.LoaderOptions
+import org.yaml.snakeyaml.events.CollectionEndEvent
+import org.yaml.snakeyaml.events.CollectionStartEvent
import org.yaml.snakeyaml.parser.ParserImpl
import org.yaml.snakeyaml.reader.StreamReader
import org.yaml.snakeyaml.scanner.ScannerImpl
@@ -27,17 +30,13 @@ trait YamlTest {
CommentedConfigurationNode parseString(final String input) {
// Print events
- def scanner = new ScannerImpl(new StreamReader(input))
- scanner.parseComments = true
- scanner.acceptTabs = true
- def parser = new ParserImpl(scanner)
-
- while (true) {
- println parser.getEvent()
- if (!parser.peekEvent()) break
+ def loaderOpts = new LoaderOptions().tap {
+ processComments = true
+ acceptTabs = true
}
+ this.dumpEvents(new StreamReader(input), loaderOpts)
- final YamlParserComposer loader = new YamlParserComposer(new StreamReader(input), Yaml11Tags.REPOSITORY, true)
+ final YamlParserComposer loader = new YamlParserComposer(new StreamReader(input), loaderOpts, Yaml11Tags.REPOSITORY)
final CommentedConfigurationNode result = CommentedConfigurationNode.root()
loader.singleDocumentStream(result)
return result
@@ -45,26 +44,43 @@ trait YamlTest {
CommentedConfigurationNode parseResource(final URL url) {
// Print events
+ def loaderOpts = new LoaderOptions().tap {
+ processComments = true
+ acceptTabs = true
+ }
url.openStream().withReader('UTF-8') {reader ->
- def scanner = new ScannerImpl(new StreamReader(reader))
- scanner.parseComments = true
- scanner.acceptTabs = true
- def parser = new ParserImpl(scanner)
- while (true) {
- println parser.getEvent()
- if (!parser.peekEvent()) break
- }
+ this.dumpEvents(new StreamReader(reader), loaderOpts)
}
assertNotNull(url, "Expected resource is missing")
url.openStream().withReader('UTF-8') { reader ->
- final YamlParserComposer loader = new YamlParserComposer(new StreamReader(reader), Yaml11Tags.REPOSITORY, true)
+ final YamlParserComposer loader = new YamlParserComposer(new StreamReader(reader), loaderOpts, Yaml11Tags.REPOSITORY)
final CommentedConfigurationNode result = CommentedConfigurationNode.root()
loader.singleDocumentStream(result)
return result
}
}
+ private void dumpEvents(StreamReader reader, LoaderOptions loaderOpts) {
+ def scanner = new ScannerImpl(reader, loaderOpts)
+ def parser = new ParserImpl(scanner)
+ int indentLevel = 0
+ while (true) {
+ if (parser.peekEvent() instanceof CollectionEndEvent) {
+ indentLevel--
+ }
+ indentLevel.times {
+ print " "
+ }
+ if (parser.peekEvent() instanceof CollectionStartEvent) {
+ indentLevel++
+ }
+
+ println parser.getEvent()
+ if (!parser.peekEvent()) break
+ }
+ }
+
String dump(final CommentedConfigurationNode input) {
return dump(input, null)
}
diff --git a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-example.yml b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-example.yml
index 382d9ac6f..76ed4502f 100644
--- a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-example.yml
+++ b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-example.yml
@@ -51,23 +51,23 @@ change-displayname: true
# When this option is enabled, the (tab) player list will be updated with the displayname.
# The value of change-displayname (above) has to be true.
-#change-playerlist: true
+# change-playerlist: true
# When EssentialsChat.jar isn't used, force essentials to add the prefix and suffix from permission plugins to displayname.
# This setting is ignored if EssentialsChat.jar is used, and defaults to 'true'.
# The value of change-displayname (above) has to be true.
# Do not edit this setting unless you know what you are doing!
-#add-prefix-suffix: false
+# add-prefix-suffix: false
# When this option is enabled, player prefixes will be shown in the playerlist.
# This feature only works for Minecraft version 1.8 and higher.
# This value of change-playerlist has to be true
-#add-prefix-in-playerlist: true
+# add-prefix-in-playerlist: true
# When this option is enabled, player suffixes will be shown in the playerlist.
-# This feature only works for Minecraft version 1.8 and higher.
+# This feature only works for Minecraft version 1.8 and higher.
# This value of change-playerlist has to be true
-#add-suffix-in-playerlist: true
+# add-suffix-in-playerlist: true
# If the teleport destination is unsafe, should players be teleported to the nearest safe location?
# If this is set to true, Essentials will attempt to teleport players close to the intended destination.
@@ -350,30 +350,30 @@ use-nbt-serialization-in-createkit: false
# Color is not an actual sign, it's for enabling using color codes on signs, when the correct permissions are given.
enabledSigns:
- #- color
- #- balance
- #- buy
- #- sell
- #- trade
- #- free
- #- warp
- #- kit
- #- mail
- #- enchant
- #- gamemode
- #- heal
- #- info
- #- spawnmob
- #- repair
- #- time
- #- weather
- #- anvil
- #- cartography
- #- disposal
- #- grindstone
- #- loom
- #- smithing
- #- workbench
+ # - color
+ # - balance
+ # - buy
+ # - sell
+ # - trade
+ # - free
+ # - warp
+ # - kit
+ # - mail
+ # - enchant
+ # - gamemode
+ # - heal
+ # - info
+ # - spawnmob
+ # - repair
+ # - time
+ # - weather
+ # - anvil
+ # - cartography
+ # - disposal
+ # - grindstone
+ # - loom
+ # - smithing
+ # - workbench
# How many times per second can Essentials signs be interacted with per player.
# Values should be between 1-20, 20 being virtually no lag protection.
@@ -392,7 +392,7 @@ allow-old-id-signs: false
#
# See https://github.com/drtshock/Essentials/pull/699 for more information.
unprotected-sign-names:
- #- kit
+ # - kit
# Backup runs a custom batch/bash command at a specified interval.
# The server will save the world before executing the backup command, and disable
@@ -406,7 +406,7 @@ backup:
# Unless you add a valid backup command or script here, this feature will be useless.
# Use 'save-all' to simply force regular world saving without backup.
# The example command below utilizes rdiff-backup: https://rdiff-backup.net/
- #command: 'rdiff-backup World1 backups/World1'
+ # command: 'rdiff-backup World1 backups/World1'
# Set this true to enable permission per warp.
per-warp-permission: false
@@ -416,14 +416,14 @@ per-warp-permission: false
# Detailed instructions and examples can be found on the wiki: http://wiki.ess3.net/wiki/List
list:
# To merge groups, list the groups you wish to merge
- #Staff: owner admin moderator
+ # Staff: owner admin moderator
Admins: owner admin
# To limit groups, set a max user limit
- #builder: 20
+ # builder: 20
# To hide groups, set the group as hidden
- #default: hidden
+ # default: hidden
# Uncomment the line below to simply list all players with no grouping
- #Players: '*'
+ # Players: '*'
# Displays real names in /list next to players who are using a nickname.
real-names-on-list: false
@@ -436,7 +436,7 @@ debug: false
# For example, to set language to English, set locale to en, to use the file "messages_en.properties".
# Don't forget to remove the # in front of the line.
# For more information, visit http://wiki.ess3.net/wiki/Locale
-#locale: en
+# locale: en
# Turn off god mode when people leave the server.
remove-god-on-disconnect: false
@@ -485,7 +485,7 @@ sleep-ignores-afk-players: true
# Users with the permission node essentials.sleepingignored will always be ignored.
sleep-ignores-vanished-player: true
-# Set the player's list name when they are AFK. This is none by default which specifies that Essentials
+# Set the player's list name when they are AFK. This is none by default which specifies that Essentials
# should not interfere with the AFK player's list name.
# You may use color codes, use {USERNAME} the player's name or {PLAYER} for the player's displayname.
afk-list-name: "none"
@@ -522,7 +522,7 @@ allow-silent-join-quit: false
# or set this to "" to hide the message entirely.
# Available placeholders:
-# {PLAYER} - The player's displayname.
+# {PLAYER} - The player's displayname.
# {USERNAME} - The player's username.
# {PREFIX} - The player's prefix.
# {SUFFIX} - The player's suffix.
@@ -538,7 +538,7 @@ custom-quit-message: "none"
# Set this to "none" to use the the "custom-join-message" above for every join.
# Available placeholders:
-# {PLAYER} - The player's displayname.
+# {PLAYER} - The player's displayname.
# {USERNAME} - The player's username.
# {OLDUSERNAME} - The player's old username.
# {PREFIX} - The player's prefix.
@@ -586,20 +586,20 @@ repair-enchanted: true
# Warning: Mixing and overleveling some enchantments can cause issues with clients, servers and plugins.
unsafe-enchantments: false
-#Do you want Essentials to keep track of previous location for /back in the teleport listener?
-#If you set this to true any plugin that uses teleport will have the previous location registered.
+# Do you want Essentials to keep track of previous location for /back in the teleport listener?
+# If you set this to true any plugin that uses teleport will have the previous location registered.
register-back-in-listener: false
-#Delay to wait before people can cause attack damage after logging in.
+# Delay to wait before people can cause attack damage after logging in.
login-attack-delay: 5
-#Set the max fly speed, values range from 0.1 to 1.0
+# Set the max fly speed, values range from 0.1 to 1.0
max-fly-speed: 0.8
-#Set the max walk speed, values range from 0.1 to 1.0
+# Set the max walk speed, values range from 0.1 to 1.0
max-walk-speed: 0.8
-#Set the maximum amount of mail that can be sent within a minute.
+# Set the maximum amount of mail that can be sent within a minute.
mails-per-minute: 1000
# Set the maximum time /mute can be used for in seconds.
@@ -674,8 +674,8 @@ delay-motd: 0
# A list of commands that should have their complementary confirm commands enabled by default.
# This is empty by default, for the latest list of valid commands see the latest source config.yml.
default-enabled-confirm-commands:
-#- pay
-#- clearinventory
+# - pay
+# - clearinventory
# Where should Essentials teleport players when they are freed from jail?
# You can set to "back" to have them teleported to where they were before they were jailed, "spawn" to have them
@@ -780,12 +780,12 @@ starting-balance: 0
# Some commands like /repair have sub-costs, check the wiki for more information.
command-costs:
# /example costs $1000 PER USE
- #example: 1000
+ # example: 1000
# /kit tools costs $1500 PER USE
- #kit-tools: 1500
+ # kit-tools: 1500
# Set this to a currency symbol you want to use.
-# Remember, if you want to use special characters in this document,
+# Remember, if you want to use special characters in this document,
# such as accented letters, you MUST save the file as UTF-8, not ANSI.
currency-symbol: '$'
@@ -822,7 +822,7 @@ show-zero-baltop: true
# The format of currency, excluding symbols. See currency-symbol-format-locale for symbol configuration.
#
# "#,##0.00" is how the majority of countries display currency.
-#currency-format: "#,##0.00"
+# currency-format: "#,##0.00"
# Format currency symbols. Some locales use , and . interchangeably.
# Some formats do not display properly in-game due to faulty Minecraft font rendering.
@@ -830,7 +830,7 @@ show-zero-baltop: true
# For 1.234,50 use de-DE
# For 1,234.50 use en-US
# For 1'234,50 use fr-ch
-#currency-symbol-format-locale: en-US
+# currency-symbol-format-locale: en-US
############################################################
# +------------------------------------------------------+ #
@@ -895,7 +895,7 @@ chat:
# If you are using group formats make sure to remove the '#' to allow the setting to be read.
# Note: Group names are case-sensitive so you must match them up with your permission plugin.
-
+
# You can use permissions to control whether players can use formatting codes in their chat messages.
# See https://essentialsx.net/wiki/Color-Permissions.html for more information.
@@ -1112,7 +1112,7 @@ newbies:
# Should we announce to the server when someone logs in for the first time?
# If so, use this format, replacing {DISPLAYNAME} with the player name.
# If not, set to ''
- #announce-format: ''
+ # announce-format: ''
announce-format: '&dWelcome {DISPLAYNAME}&d to the server!'
# When we spawn for the first time, which spawnpoint do we use?
@@ -1121,7 +1121,7 @@ newbies:
# Do we want to give users anything on first join? Set to '' to disable
# This kit will be given regardless of cost and permissions, and will not trigger the kit delay.
- #kit: ''
+ # kit: ''
kit: tools
# What priority should we use for handling respawns?
@@ -1152,7 +1152,7 @@ respawn-at-anchor: false
spawn-on-join: false
# The following value of `guests` states that all players in group `guests` will be teleported to spawn when joining.
#spawn-on-join: guests
-# The following list value states that all players in group `guests` and `admin` are to be teleported to spawn when joining.
+# The following list value states that all players in group `guests` and `admin` are to be teleported to spawn when joining.
#spawn-on-join:
#- guests
#- admin
diff --git a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-legacy.yml b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-legacy.yml
index 88c2743e5..00f9e55d2 100644
--- a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-legacy.yml
+++ b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/essx-legacy.yml
@@ -725,4 +725,4 @@ respawn-listener-priority: high
# When users die, should they respawn at their first home or bed, instead of the spawnpoint?
respawn-at-home: false
-# End of file <-- No seriously, you're done with configuration.
\ No newline at end of file
+# End of file <-- No seriously, you're done with configuration.
diff --git a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/mobcleaner-example.yml b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/mobcleaner-example.yml
index 93885e67d..3a3a9d803 100644
--- a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/mobcleaner-example.yml
+++ b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/mobcleaner-example.yml
@@ -31,6 +31,7 @@ worlds:
- SQUID
- WOLF
- ZOMBIE
+
# Should only entities with a specific spawn reason be removed?
# Setting this to false will check for any spawn reason
spawn-reason:
@@ -66,12 +67,15 @@ nearby-entities:
# This is useful to only remove large groups of entities while leaving smaller entity groups alone
# Using this would prevent every entity from being removed then just respawning again naturally
enabled: true
+
# Only apply to worlds with the mob spawning gamerule enabled?
gamerule-enabled-only: false
+
# The distance in blocks that the plugin should check for extra entities
x: 3
y: 3
z: 3
+
# How many additional entities must be around the first entity to be removed?
count: 4
@@ -84,6 +88,7 @@ remove-named: false
messages:
# Should there be action bar messages?
actionbar: true
+
# Should there be chat messages?
chat: false
actionbar-message: "&6&lCommon entities will be removed in &e&l{SECONDS} &6&lsecond{S}!"
@@ -111,12 +116,15 @@ commands:
low-tps:
# Should the entity removal task be triggered when the TPS is low?
enabled: false
+
# Below what TPS should the plugin remove the entities?
threshold: 17
+
# Should the plugin remove the entities instantly or trigger the countdown?
# Warning: If the TPS is too low and remove-instantly is false, the plugin may
# not be able to remove the entities before the server crashes
remove-instantly: true
+
# Should there be a chat message sent to players with the `entityclearer.lowtps`
# permission stating that the TPS is low?
chat: true