Aren't we all tired of the fact that configs don't keep comments? Well, I decided to make a little util class to fix this problem. All you need to do is add the below class to your project, and use Code:java CommentYamlConfiguration.loadConfiguration(File file); The class also includes a JavaPlugin which uses the comment-supporting configs, all you need to do is extend CommentYamlConfiguration.JavaPlugin instead of JavaPlugin. Here's the class: Code:java import com.google.common.base.Charsets;import com.google.common.collect.Maps;import com.google.common.io.Files;import org.apache.commons.lang.Validate;import org.bukkit.Bukkit;import org.bukkit.configuration.InvalidConfigurationException;import org.bukkit.configuration.file.FileConfiguration;import org.bukkit.configuration.file.YamlConfiguration; import java.io.*;import java.util.*;import java.util.logging.Level; public class CommentYamlConfiguration extends YamlConfiguration { private Map<Integer, String> comments = Maps.newHashMap(); @Override public void load(Reader reader) throws IOException, InvalidConfigurationException { StringBuilder builder = new StringBuilder(); String line; try (BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader)) { int index = 0; while ((line = input.readLine()) != null) { if (line.startsWith("#") || line.isEmpty()) { comments.put(index, line); } builder.append(line); builder.append(System.lineSeparator()); index++; } } this.loadFromString(builder.toString()); } @Override public void save(File file) throws IOException { Validate.notNull(file, "File cannot be null"); Files.createParentDirs(file); String data = this.saveToString(); if (comments.size() != 0) { String[] stringArray = data.split(System.lineSeparator()); StringBuilder stringBuilder = new StringBuilder(); int arrayIndex = 0; for (int i = 0; i < stringArray.length + comments.size(); i++) { if (comments.containsKey(i)) { stringBuilder.append(System.lineSeparator()).append(comments.get(i)); } else { if (arrayIndex >= stringArray.length) { stringBuilder.append(System.lineSeparator()); } else { stringBuilder.append(System.lineSeparator()).append(stringArray[arrayIndex++]); } } } data = stringBuilder.toString().substring(1); } try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)) { writer.write(data); } } @Override protected String buildHeader() { return ""; } @Override protected String parseHeader(String input) { return ""; } public static YamlConfiguration loadConfiguration(File file) { Validate.notNull(file, "File cannot be null"); YamlConfiguration config = new CommentYamlConfiguration(); try { config.load(file); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException | InvalidConfigurationException var4) { Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, var4); } return config; } public static class JavaPlugin extends org.bukkit.plugin.java.JavaPlugin { private File configFile; private FileConfiguration config; @Override public void reloadConfig() { if (configFile == null) { configFile = new File(this.getDataFolder(), "config.yml"); } config = loadConfiguration(configFile); InputStream defConfigStream = this.getResource("config.yml"); if(defConfigStream != null) { config.setDefaults(loadConfiguration(new InputStreamReader(defConfigStream, Charsets.UTF_8))); } } @Override public FileConfiguration getConfig() { if(this.config == null) { this.reloadConfig(); } return this.config; } }} Also, please note that this might not work as you expect if the amount of lines above the comments changes. I'd recommend keeping anything that might be an unpredictable amount of lines at the bottom with no comments below it.
@AlvinB, that's really funny. I was thinking about working on the same thing and realized I'd have the same limitation you ran into. Nice extending JavaPlugin though. That's how all my own libraries work now in addition to reading additional data off the plugin.yml, an idea @I Al Istannen has begun to shamelessly steal (not that I care). lol
Instead of hard coding Code: "\n" Isn't System.lineSeperator better? I was just wondering and I personally don't know, but to my insight it is better.
@PhantomUnicorns, yeah. It is. Java is an architecture neutral language, and not all systems will use that character to break the end of the line.
@PhantomUnicorns @Tecno_Wizard Fixed. Although I'm not sure it's entirely needed as System.lineSeperator() returns "\r\n" for my windows machine, but "\n" appears to be working just fine.
@Tecno_Wizard Did a quick google search, and it seems that the Windows C implementation auto-converts "\n" to "\r\n" when writing and reading from files. So theoretically I don't think this is actually a problem in Java, as windows auto-converts it and all Unix systems already use "\n", unless there's some non-unix system besides windows with a JVM.
@AlvinB That. That is idiotic. #WindowsProblems. I can imagine the conversation between the engineers. "Should we check to make sure the \r isn't already there?" "Nah. Too much effort." "Sounds good."
Hmm I know why but it's still pretty weird that the most people do # for comments in config.yml, I know Ruby uses it (And a bunch others) but I'm use to seeing //
@PhantomUnicorns I think // or # is just fine as a comment character. What annoys me is batch where you have to use the REM command. If you don't know that REM stood for reminder it's almost impossible to guess that it's a comment. (I know there's the "::" to comment out lines, but that doesn't work properly in all cases....)