120 lines
2.4 KiB
Go

package formatting
import (
"fmt"
"strings"
protocol "github.com/tliron/glsp/protocol_3_16"
)
var DefaultFormattingOptions = protocol.FormattingOptions{
"tabSize": float64(4),
"insertSpaces": false,
"trimTrailingWhitespace": true,
}
type FormatTemplate string
func (f FormatTemplate) Format(
options protocol.FormattingOptions,
a ...any,
) string {
trimTrailingSpace := true
if shouldTrim, found := options["trimTrailingWhitespace"]; found {
trimTrailingSpace = shouldTrim.(bool)
}
value := ""
value = fmt.Sprintf(
string(
f.replace("/t", getTab(options)),
),
a...,
)
if trimTrailingSpace {
value = strings.TrimRight(value, " ")
value = strings.TrimRight(value, "\t")
}
value = surroundWithQuotes(value)
return value
}
func (f FormatTemplate) replace(format string, replacement string) FormatTemplate {
value := string(f)
currentIndex := 0
for {
position := strings.Index(value[currentIndex:], format)
if position == -1 {
break
}
position = position + currentIndex
currentIndex = position
if position == 0 || value[position-1] != '\\' {
value = value[:position] + replacement + value[position+len(format):]
}
}
return FormatTemplate(value)
}
func surroundWithQuotes(s string) string {
value := s
currentIndex := 0
for {
startPosition := strings.Index(value[currentIndex:], "/!'")
if startPosition == -1 {
break
}
startPosition = startPosition + currentIndex + 3
currentIndex = startPosition
endPosition := strings.Index(value[startPosition:], "/!'")
if endPosition == -1 {
break
}
endPosition = endPosition + startPosition
currentIndex = endPosition
innerValue := value[startPosition:endPosition]
if innerValue[0] == '"' && innerValue[len(innerValue)-1] == '"' && (len(innerValue) >= 2 || innerValue[len(innerValue)-2] != '\\') {
// Already surrounded
value = value[:startPosition-3] + innerValue + value[endPosition+3:]
} else if strings.Contains(innerValue, " ") {
value = value[:startPosition-3] + "\"" + innerValue + "\"" + value[endPosition+3:]
} else {
value = value[:startPosition-3] + innerValue + value[endPosition+3:]
}
if endPosition+3 >= len(value) {
break
}
}
return value
}
func getTab(options protocol.FormattingOptions) string {
tabSize := options["tabSize"].(float64)
insertSpace := options["insertSpaces"].(bool)
if insertSpace {
return strings.Repeat(" ", int(tabSize))
} else {
return "\t"
}
}