From 57d820f0e078d076b69e5288824f414c0211efc7 Mon Sep 17 00:00:00 2001
From: Tim203
Date: Thu, 22 Jun 2023 12:36:27 +0200
Subject: [PATCH 01/17] Added support for YAML comments
---
.../yaml/YamlConfigurationLoader.java | 6 +-
.../configurate/yaml/YamlRepresenter.java | 100 ++++++++++++++++++
.../yaml/YamlConfigurationLoaderTest.java | 24 +++++
.../configurate/yaml/comments-expected.yml | 5 +
4 files changed, 132 insertions(+), 3 deletions(-)
create mode 100644 format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
create mode 100644 format/yaml/src/test/resources/org/spongepowered/configurate/yaml/comments-expected.yml
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 e68418492..6564425ab 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
@@ -29,7 +29,6 @@
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
-import org.yaml.snakeyaml.representer.Representer;
import java.io.BufferedReader;
import java.io.Writer;
@@ -175,7 +174,8 @@ private YamlConfigurationLoader(final Builder builder) {
final DumperOptions opts = builder.options;
opts.setDefaultFlowStyle(NodeStyle.asSnakeYaml(builder.style));
- this.yaml = ThreadLocal.withInitial(() -> new Yaml(new Constructor(loaderOpts), new Representer(opts), opts, loaderOpts));
+ opts.setProcessComments(true);
+ this.yaml = ThreadLocal.withInitial(() -> new Yaml(new Constructor(loaderOpts), new YamlRepresenter(opts), opts, loaderOpts));
}
@Override
@@ -185,7 +185,7 @@ protected void loadInternal(final CommentedConfigurationNode node, final Buffere
@Override
protected void saveInternal(final ConfigurationNode node, final Writer writer) {
- this.yaml.get().dump(node.raw(), writer);
+ this.yaml.get().dump(node, writer);
}
@Override
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
new file mode 100644
index 000000000..f29723592
--- /dev/null
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+import static org.spongepowered.configurate.loader.AbstractConfigurationLoader.CONFIGURATE_LINE_PATTERN;
+
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.configurate.CommentedConfigurationNodeIntermediary;
+import org.spongepowered.configurate.ConfigurationNode;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
+import org.yaml.snakeyaml.comments.CommentLine;
+import org.yaml.snakeyaml.comments.CommentType;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+import org.yaml.snakeyaml.nodes.SequenceNode;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.representer.Represent;
+import org.yaml.snakeyaml.representer.Representer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+final class YamlRepresenter extends Representer {
+
+ YamlRepresenter(final DumperOptions options) {
+ super(options);
+ multiRepresenters.put(ConfigurationNode.class, new ConfigurationNodeRepresent());
+ }
+
+ private final class ConfigurationNodeRepresent implements Represent {
+ @Override
+ public Node representData(final Object nodeObject) {
+ final ConfigurationNode node = (ConfigurationNode) nodeObject;
+
+ final Node yamlNode;
+ if (node.isMap()) {
+ final List children = new ArrayList<>();
+ for (Map.Entry
+ *
+ * @param lineLength the maximum length of a configuration line
+ * @return this builder (for chaining)
+ * @since 4.2.0
+ */
+ public Builder lineLength(final int lineLength) {
+ this.lineLength = lineLength;
+ return this;
+ }
+
+ /**
+ * Get the maximum length of a configuration line.
+ *
+ * @return the maximum length of a configuration line
+ * @see #lineLength(int) for details on the line length
+ * @since 4.2.0
+ */
+ public int lineLength() {
+ return this.lineLength;
+ }
+
@Override
public YamlConfigurationLoader build() {
return new YamlConfigurationLoader(this);
@@ -207,6 +236,7 @@ private YamlConfigurationLoader(final Builder builder) {
final DumperOptions opts = builder.options;
opts.setDefaultFlowStyle(NodeStyle.asSnakeYaml(builder.style));
opts.setProcessComments(builder.commentsEnabled());
+ opts.setWidth(builder.lineLength());
// the constructor needs ConfigurationOptions, which is only available when called (loadInternal)
this.constructor = ThreadLocal.withInitial(() -> new YamlConstructor(loaderOpts));
this.yaml = ThreadLocal.withInitial(() -> new Yaml(this.constructor.get(), new YamlRepresenter(opts), opts, loaderOpts));
From ffcbfcbd9fa12bc028cb0a3ddb4a599a80d6e08e Mon Sep 17 00:00:00 2001
From: Tim203
Date: Mon, 16 Oct 2023 11:01:44 +0200
Subject: [PATCH 14/17] Fix checkstyle
---
.../org/spongepowered/configurate/yaml/YamlConstructor.java | 1 -
.../org/spongepowered/configurate/yaml/YamlRepresenter.java | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
index 1f944a278..f9c139fd0 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
@@ -63,7 +63,6 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
node.raw(Collections.emptyMap());
((MappingNode) yamlNode).getValue().forEach(tuple -> {
- // I don't think it's possible to have a non-scalar node as key
final ConfigurationNode keyNode = (ConfigurationNode) this.constructObject(tuple.getKeyNode());
final Node valueNode = tuple.getValueNode();
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
index b1aee8475..c2d0d014b 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
@@ -105,7 +105,7 @@ private CommentLine commentLineFor(final String comment) {
private static final class EmptyNullRepresenter implements Represent {
@Override
- public Node representData(Object data) {
+ public Node representData(final Object data) {
return new ScalarNode(Tag.NULL, "", null, null, ScalarStyle.PLAIN);
}
}
From f8acad91c8eee4e21bf7115c6907e8f3a32c1dc4 Mon Sep 17 00:00:00 2001
From: zml
Date: Sun, 15 Oct 2023 20:03:41 -0700
Subject: [PATCH 15/17] chore(yaml): Clear up some stream usage
---
.../configurate/yaml/YamlConstructor.java | 35 +++++++++++--------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
index f9c139fd0..9a09482a9 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
@@ -21,18 +21,19 @@
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
+import org.spongepowered.configurate.loader.AbstractConfigurationLoader;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.comments.CommentLine;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
+import org.yaml.snakeyaml.nodes.NodeTuple;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
class YamlConstructor extends Constructor {
@@ -62,7 +63,7 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
// make sure to mark it as a map type, even if the map itself is empty
node.raw(Collections.emptyMap());
- ((MappingNode) yamlNode).getValue().forEach(tuple -> {
+ for (final NodeTuple tuple : ((MappingNode) yamlNode).getValue()) {
final ConfigurationNode keyNode = (ConfigurationNode) this.constructObject(tuple.getKeyNode());
final Node valueNode = tuple.getValueNode();
@@ -70,7 +71,7 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
node.node(keyNode.raw())
.from((ConfigurationNode) constructObject(valueNode))
.comment(commentFor(tuple.getKeyNode().getBlockComments()));
- });
+ }
return node.comment(commentFor(yamlNode.getBlockComments()));
}
@@ -80,9 +81,9 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
// make sure to mark it as a list type, even if the collection itself is empty
node.raw(Collections.emptyList());
- ((Collection>) raw).forEach(value -> {
+ for (final Object value : (Collection>) raw) {
node.appendListNode().from((ConfigurationNode) value);
- });
+ }
} else {
node.raw(raw);
}
@@ -94,16 +95,20 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
if (commentLines == null || commentLines.isEmpty()) {
return null;
}
- return commentLines.stream()
- .map(input -> {
- final String lineStripped = removeLineBreaksForLine(input.getValue());
- if (!lineStripped.isEmpty() && lineStripped.charAt(0) == ' ') {
- return lineStripped.substring(1);
- } else {
- return lineStripped;
- }
- })
- .collect(Collectors.joining("\n"));
+
+ final StringBuilder outputBuilder = new StringBuilder();
+ for (final CommentLine line : commentLines) {
+ if (outputBuilder.length() > 0) {
+ outputBuilder.append(AbstractConfigurationLoader.CONFIGURATE_LINE_SEPARATOR);
+ }
+ final String lineStripped = removeLineBreaksForLine(line.getValue());
+ if (!lineStripped.isEmpty() && lineStripped.charAt(0) == ' ') {
+ outputBuilder.append(lineStripped, 1, lineStripped.length());
+ } else {
+ outputBuilder.append(lineStripped);
+ }
+ }
+ return outputBuilder.toString();
}
private static String removeLineBreaksForLine(final String line) {
From e5986b47a15baaeb3d0a735ec303ee5b3414b846 Mon Sep 17 00:00:00 2001
From: zml
Date: Sun, 15 Oct 2023 22:51:24 -0700
Subject: [PATCH 16/17] chore(yaml): Tweak formatting, preserve scalar + node
styles
---
.../configurate/yaml/NodeStyle.java | 13 ++
.../configurate/yaml/ScalarStyle.java | 116 ++++++++++++++++++
.../yaml/YamlConfigurationLoader.java | 24 +++-
.../configurate/yaml/YamlConstructor.java | 14 ++-
.../configurate/yaml/YamlRepresenter.java | 47 ++++++-
.../yaml/YamlConfigurationLoaderTest.java | 2 +
6 files changed, 209 insertions(+), 7 deletions(-)
create mode 100644 format/yaml/src/main/java/org/spongepowered/configurate/yaml/ScalarStyle.java
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/NodeStyle.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/NodeStyle.java
index a269d280a..8fc9277dc 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/NodeStyle.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/NodeStyle.java
@@ -47,4 +47,17 @@ static DumperOptions.FlowStyle asSnakeYaml(final @Nullable NodeStyle style) {
return style == null ? DumperOptions.FlowStyle.AUTO : style.snake;
}
+ static @Nullable NodeStyle fromSnakeYaml(final DumperOptions.FlowStyle style) {
+ switch (style) {
+ case AUTO:
+ return null;
+ case BLOCK:
+ return BLOCK;
+ case FLOW:
+ return FLOW;
+ default:
+ throw new IllegalArgumentException("Unknown style " + style);
+ }
+ }
+
}
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
new file mode 100644
index 000000000..a0c6a2859
--- /dev/null
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/ScalarStyle.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.yaml.snakeyaml.DumperOptions;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+/**
+ * Style that can be used to represent a scalar.
+ *
+ * @since 4.2.0
+ */
+public enum ScalarStyle {
+
+ /**
+ * A double-quoted string.
+ *
+ * "hello world"
+ *
+ * @since 4.2.0
+ */
+ DOUBLE_QUOTED(DumperOptions.ScalarStyle.DOUBLE_QUOTED),
+
+ /**
+ * A single-quoted string.
+ *
+ * 'hello world'
+ *
+ * @since 4.2.0
+ */
+ SINGLE_QUOTED(DumperOptions.ScalarStyle.SINGLE_QUOTED),
+
+ /**
+ * String without any quotation.
+ *
+ * This may be ambiguous with non-string types.
+ *
+ * @since 4.2.0
+ */
+ UNQUOTED(DumperOptions.ScalarStyle.PLAIN),
+
+ /**
+ * Folded scalar.
+ *
+ * {@code
+ * key: >
+ * folded scalar
+ * line breaks collapsed
+ * }
+ *
+ * @since 4.2.0
+ */
+ FOLDED(DumperOptions.ScalarStyle.FOLDED),
+
+ /**
+ * Literal scalar.
+ *
+ * {@code
+ * key: |
+ * literal scalar
+ * line breaks preserved
+ * }
+ *
+ * @since 4.2.0
+ */
+ LITERAL(DumperOptions.ScalarStyle.LITERAL)
+ ;
+
+ private static final Map BY_SNAKE = new EnumMap<>(DumperOptions.ScalarStyle.class);
+ private final DumperOptions.ScalarStyle snake;
+
+ ScalarStyle(final DumperOptions.ScalarStyle snake) {
+ this.snake = snake;
+ }
+
+ static DumperOptions.ScalarStyle asSnakeYaml(
+ final @Nullable ScalarStyle style,
+ final DumperOptions.@Nullable ScalarStyle fallback
+ ) {
+ if (style != null) {
+ return style.snake;
+ } else if (fallback != null) {
+ return fallback;
+ } else {
+ return DumperOptions.ScalarStyle.PLAIN;
+ }
+ }
+
+ static ScalarStyle fromSnakeYaml(final DumperOptions.ScalarStyle style) {
+ return BY_SNAKE.getOrDefault(style, UNQUOTED);
+ }
+
+ static {
+ for (final ScalarStyle style : values()) {
+ BY_SNAKE.put(style.snake, style);
+ }
+ }
+
+}
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 9a64e571f..beb27bd0d 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
@@ -20,6 +20,7 @@
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
+import org.spongepowered.configurate.RepresentationHint;
import org.spongepowered.configurate.loader.AbstractConfigurationLoader;
import org.spongepowered.configurate.loader.CommentHandler;
import org.spongepowered.configurate.loader.CommentHandlers;
@@ -53,6 +54,25 @@ public final class YamlConfigurationLoader extends AbstractConfigurationLoaderIf the chosen scalar style would produce syntactically invalid YAML, a
+ * valid one will replace it.
+ *
+ * @since 4.2.0
+ */
+ public static final RepresentationHint SCALAR_STYLE = RepresentationHint.of("configurate:yaml/scalarstyle", ScalarStyle.class);
+
+ /**
+ * The YAML node style to use for collection nodes. A {@code null} value
+ * will instruct the emitter to fall back to the
+ * {@link Builder#nodeStyle()} setting.
+ *
+ * @since 4.2.0
+ */
+ public static final RepresentationHint NODE_STYLE = RepresentationHint.of("configurate:yaml/nodestyle", NodeStyle.class);
+
/**
* Creates a new {@link YamlConfigurationLoader} builder.
*
@@ -237,9 +257,11 @@ private YamlConfigurationLoader(final Builder builder) {
opts.setDefaultFlowStyle(NodeStyle.asSnakeYaml(builder.style));
opts.setProcessComments(builder.commentsEnabled());
opts.setWidth(builder.lineLength());
+ opts.setIndicatorIndent(builder.indent());
+ opts.setIndentWithIndicator(true);
// the constructor needs ConfigurationOptions, which is only available when called (loadInternal)
this.constructor = ThreadLocal.withInitial(() -> new YamlConstructor(loaderOpts));
- this.yaml = ThreadLocal.withInitial(() -> new Yaml(this.constructor.get(), new YamlRepresenter(opts), opts, loaderOpts));
+ this.yaml = ThreadLocal.withInitial(() -> new Yaml(this.constructor.get(), new YamlRepresenter(true, opts), opts, loaderOpts));
}
@Override
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
index 9a09482a9..3818f80c9 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlConstructor.java
@@ -29,6 +29,8 @@
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
import org.yaml.snakeyaml.nodes.NodeTuple;
+import org.yaml.snakeyaml.nodes.ScalarNode;
+import org.yaml.snakeyaml.nodes.SequenceNode;
import java.util.Collection;
import java.util.Collections;
@@ -62,8 +64,12 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
if (yamlNode.getNodeId() == NodeId.mapping) {
// make sure to mark it as a map type, even if the map itself is empty
node.raw(Collections.emptyMap());
+ final MappingNode mapping = (MappingNode) yamlNode;
+ if (mapping.getFlowStyle() != null) {
+ node.hint(YamlConfigurationLoader.NODE_STYLE, NodeStyle.fromSnakeYaml(mapping.getFlowStyle()));
+ }
- for (final NodeTuple tuple : ((MappingNode) yamlNode).getValue()) {
+ for (final NodeTuple tuple : mapping.getValue()) {
final ConfigurationNode keyNode = (ConfigurationNode) this.constructObject(tuple.getKeyNode());
final Node valueNode = tuple.getValueNode();
@@ -80,11 +86,17 @@ protected Object constructObjectNoCheck(final Node yamlNode) {
if (raw instanceof Collection>) {
// make sure to mark it as a list type, even if the collection itself is empty
node.raw(Collections.emptyList());
+ if (((SequenceNode) yamlNode).getFlowStyle() != null) {
+ node.hint(YamlConfigurationLoader.NODE_STYLE, NodeStyle.fromSnakeYaml(((SequenceNode) yamlNode).getFlowStyle()));
+ }
for (final Object value : (Collection>) raw) {
node.appendListNode().from((ConfigurationNode) value);
}
} else {
+ if (yamlNode instanceof ScalarNode) {
+ node.hint(YamlConfigurationLoader.SCALAR_STYLE, ScalarStyle.fromSnakeYaml(((ScalarNode) yamlNode).getScalarStyle()));
+ }
node.raw(raw);
}
diff --git a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
index c2d0d014b..a018bb349 100644
--- a/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
+++ b/format/yaml/src/main/java/org/spongepowered/configurate/yaml/YamlRepresenter.java
@@ -44,8 +44,13 @@
final class YamlRepresenter extends Representer {
- YamlRepresenter(final DumperOptions options) {
+ private static final CommentLine BLANK_LINE = new CommentLine(null, null, "", CommentType.BLANK_LINE);
+
+ private final boolean padComments;
+
+ YamlRepresenter(final boolean padComments, final DumperOptions options) {
super(options);
+ this.padComments = padComments;
multiRepresenters.put(ConfigurationNode.class, new ConfigurationNodeRepresent());
nullRepresenter = new EmptyNullRepresenter();
}
@@ -58,24 +63,49 @@ public Node representData(final Object nodeObject) {
final Node yamlNode;
if (node.isMap()) {
final List children = new ArrayList<>();
+ boolean first = true;
for (Map.Entry ent : node.childrenMap().entrySet()) {
// SnakeYAML supports both key and value comments. Add the comments on the key
final Node value = represent(ent.getValue());
final Node key = represent(ent.getKey());
key.setBlockComments(value.getBlockComments());
value.setBlockComments(Collections.emptyList());
+ if (
+ !first
+ && !(node.parent() != null && node.parent().isList())
+ && key.getBlockComments() != null
+ && !key.getBlockComments().isEmpty()
+ ) {
+ key.getBlockComments().add(0, BLANK_LINE);
+ }
+ first = false;
children.add(new NodeTuple(key, value));
}
- yamlNode = new MappingNode(Tag.MAP, children, FlowStyle.AUTO);
+ yamlNode = new MappingNode(Tag.MAP, children, this.flowStyle(node));
} else if (node.isList()) {
final List children = new ArrayList<>();
for (ConfigurationNode ent : node.childrenList()) {
children.add(represent(ent));
}
- yamlNode = new SequenceNode(Tag.SEQ, children, FlowStyle.AUTO);
+ yamlNode = new SequenceNode(Tag.SEQ, children, this.flowStyle(node));
} else {
- yamlNode = represent(node.rawScalar());
+ final Node optionNode = represent(node.rawScalar());
+ final org.spongepowered.configurate.yaml.@Nullable ScalarStyle requestedStyle
+ = node.ownHint(YamlConfigurationLoader.SCALAR_STYLE);
+ if (optionNode instanceof ScalarNode && requestedStyle != null) {
+ final ScalarNode scalar = (ScalarNode) optionNode;
+ yamlNode = new ScalarNode(
+ scalar.getTag(),
+ scalar.getValue(),
+ scalar.getStartMark(),
+ scalar.getEndMark(),
+ org.spongepowered.configurate.yaml.ScalarStyle.asSnakeYaml(requestedStyle, scalar.getScalarStyle())
+ );
+ } else {
+ yamlNode = optionNode;
+ }
+
}
if (node instanceof CommentedConfigurationNodeIntermediary>) {
@@ -92,9 +122,16 @@ public Node representData(final Object nodeObject) {
return yamlNode;
}
+ private FlowStyle flowStyle(final ConfigurationNode node) {
+ final @Nullable NodeStyle requested = node.ownHint(YamlConfigurationLoader.NODE_STYLE);
+ return NodeStyle.asSnakeYaml(requested);
+ }
+
private CommentLine commentLineFor(final String comment) {
if (comment.isEmpty()) {
- return new CommentLine(null, null, "", CommentType.BLANK_LINE);
+ return BLANK_LINE;
+ } else if (!YamlRepresenter.this.padComments || comment.charAt(0) == '#') {
+ return new CommentLine(null, null, comment, CommentType.BLOCK);
}
// prepend a space before the comment:
// before: #hello
diff --git a/format/yaml/src/test/java/org/spongepowered/configurate/yaml/YamlConfigurationLoaderTest.java b/format/yaml/src/test/java/org/spongepowered/configurate/yaml/YamlConfigurationLoaderTest.java
index b9e636c01..a5a087f9f 100644
--- a/format/yaml/src/test/java/org/spongepowered/configurate/yaml/YamlConfigurationLoaderTest.java
+++ b/format/yaml/src/test/java/org/spongepowered/configurate/yaml/YamlConfigurationLoaderTest.java
@@ -192,6 +192,7 @@ void testRoundtripEssX(final @TempDir Path tempDir) throws IOException {
final YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
.path(destination)
.url(source)
+ .indent(2)
.nodeStyle(NodeStyle.BLOCK)
.build();
@@ -227,6 +228,7 @@ void testRoundtripMobCleaner(final @TempDir Path tempDir) throws IOException {
final YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
.path(destination)
.url(source)
+ .indent(2)
.nodeStyle(NodeStyle.BLOCK)
.build();
From ce367360aa7cabbb083566d15a5e59d4b3f9802a Mon Sep 17 00:00:00 2001
From: Tim203
Date: Thu, 1 Feb 2024 22:03:05 +0100
Subject: [PATCH 17/17] Update test files to match latest changes
---
.../org/spongepowered/configurate/yaml/comments-test.yml | 6 +++---
.../org/spongepowered/configurate/yaml/write-expected.yml | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/comments-test.yml b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/comments-test.yml
index 8d02ab2b1..cea852f3a 100644
--- a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/comments-test.yml
+++ b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/comments-test.yml
@@ -4,6 +4,6 @@ waffles-with-syrup:
# comments
ingredients:
# would you've guessed the ingredients?
- - waffles
- # I certainly didn't
- - syrup
+ - waffles
+ # I certainly didn't
+ - syrup
diff --git a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/write-expected.yml b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/write-expected.yml
index e3ea843b4..3aea74347 100644
--- a/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/write-expected.yml
+++ b/format/yaml/src/test/resources/org/spongepowered/configurate/yaml/write-expected.yml
@@ -2,7 +2,7 @@ mapping:
first: hello
second: world
list:
-- 1
-- 2
-- 3
-- 4
+ - 1
+ - 2
+ - 3
+ - 4