diff --git a/goini.go b/goini.go index 510f217..ad2b8eb 100644 --- a/goini.go +++ b/goini.go @@ -152,7 +152,7 @@ func (ini *GoINI) SetString(name string, key string, value string) { if index, ok := ini.findSectionKeyLineIndex(name, key); ok { ini.fileLines[index].keyValue = value ini.fileLines[index].modified = true - ini.rebuildIndexes() + ini.sectionValues[name][key] = value return } ini.ensureSectionLine(name) diff --git a/internal.go b/internal.go index 12eedec..afd5aac 100644 --- a/internal.go +++ b/internal.go @@ -68,6 +68,9 @@ func parseRawLine(rawLine string, sectionName string) (iniLine, string) { line.sectionName = nextSection return line, nextSection } + if strings.HasPrefix(trimmed, "[") && strings.HasSuffix(trimmed, "]") { + return line, sectionName + } if parsed, ok := parseKeyValue(rawLine); ok { line.kind = lineKeyValue line.keyName = parsed.key @@ -234,6 +237,9 @@ func (ini *GoINI) findSectionInsertIndex(sectionName string) int { insert := len(ini.fileLines) for i, line := range ini.fileLines { if line.kind == lineSection { + if current == sectionName { + insert, _ = ini.commentRangeBefore(i) + } current = line.sectionName if current == sectionName { insert = i + 1 @@ -250,9 +256,13 @@ func (ini *GoINI) findSectionInsertIndex(sectionName string) int { func (ini *GoINI) findRootInsertIndex() int { for i, line := range ini.fileLines { if line.kind == lineSection { - return i + start, _ := ini.commentRangeBefore(i) + return start } } + if len(ini.sectionKeys[ini.rootSection]) == 0 { + return ini.firstRootLineIndex() + } return len(ini.fileLines) } @@ -306,7 +316,11 @@ func (ini *GoINI) firstRootLineIndex() int { return i } } - return 0 + index := len(ini.fileLines) + for index > 0 && ini.fileLines[index-1].kind == lineBlank { + index-- + } + return index } func commentLines(comment string) []iniLine { @@ -337,8 +351,7 @@ func stripComment(comment string) string { if !isComment(trimmed) { return trimmed } - trimmed = strings.TrimPrefix(strings.TrimPrefix(trimmed, "#"), ";") - return strings.TrimPrefix(trimmed, " ") + return strings.TrimPrefix(trimmed[1:], " ") } func renderLine(line iniLine) string { @@ -360,10 +373,14 @@ func renderLine(line iniLine) string { func renderKeyValue(line iniLine) string { separator := line.separator - if separator == "" { + if separator == "" || !strings.Contains(separator, "=") && strings.Contains(line.keyValue, "=") { separator = defaultSeparator } - return line.indent + line.keyName + separator + formatValue(line.keyValue) + value := formatValue(line.keyValue) + if strings.HasPrefix(line.keyName, "[") && strings.HasSuffix(value, "]") { + value = `"` + value + `"` + } + return line.indent + line.keyName + separator + value } func formatValue(value string) string { @@ -392,7 +409,9 @@ func (ini *GoINI) formatString() string { case lineKeyValue: formattedLines = append(formattedLines, pendingComments...) pendingComments = pendingComments[:0] - formattedLines = append(formattedLines, line.keyName+defaultSeparator+formatValue(line.keyValue)) + line.indent = "" + line.separator = defaultSeparator + formattedLines = append(formattedLines, renderKeyValue(line)) case lineComment: pendingComments = append(pendingComments, formatINIComment(line.text)) }