feat: Make separators more dynamic

This commit is contained in:
Myzel394 2024-07-30 22:10:04 +02:00
parent 33c32e4dd1
commit 529d28d943
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
4 changed files with 45 additions and 36 deletions

View File

@ -12,12 +12,20 @@ type SimpleConfigPosition struct {
type SimpleConfigLine struct {
Value string
Separator string
Position SimpleConfigPosition
}
// Get the character positions of [Option End, Separator End, Value End]
func (l SimpleConfigLine) GetCharacterPositions(optionName string) [3]int {
return [3]int{len(optionName), len(optionName + l.Separator), len(optionName + l.Separator + l.Value)}
}
type SimpleConfigOptions struct {
Separator string
Separator regexp.Regexp
IgnorePattern regexp.Regexp
// This is the separator that will be used when adding a new line
IdealSeparator string
AvailableOptions *map[string]Option
}
@ -27,24 +35,43 @@ type SimpleConfigParser struct {
}
func (p *SimpleConfigParser) AddLine(line string, lineNumber uint32) (string, error) {
parts := strings.SplitN(line, p.Options.Separator, 2)
var option string
var separator string
var value string
if len(parts) == 0 {
re := p.Options.Separator
matches := re.FindStringSubmatch(line)
if len(matches) == 0 {
return "", docvalues.MalformedLineError{}
}
option := parts[0]
optionIndex := re.SubexpIndex("OptionName")
if optionIndex == -1 {
return "", docvalues.MalformedLineError{}
}
option = matches[optionIndex]
if _, exists := (*p.Options.AvailableOptions)[option]; !exists {
return option, docvalues.OptionUnknownError{}
}
value := ""
separatorIndex := re.SubexpIndex("Separator")
if len(parts) > 1 {
value = parts[1]
if separatorIndex == -1 {
return option, docvalues.MalformedLineError{}
}
valueIndex := re.SubexpIndex("Value")
if valueIndex == -1 {
return option, docvalues.MalformedLineError{}
}
value = matches[valueIndex]
if _, exists := p.Lines[option]; exists {
return option, docvalues.OptionAlreadyExistsError{
AlreadyLine: p.Lines[option].Position.Line,
@ -53,6 +80,7 @@ func (p *SimpleConfigParser) AddLine(line string, lineNumber uint32) (string, er
p.Lines[option] = SimpleConfigLine{
Value: value,
Separator: separator,
Position: SimpleConfigPosition{
Line: lineNumber,
},
@ -75,26 +103,12 @@ func (p *SimpleConfigParser) RemoveOption(option string) {
delete(p.Lines, option)
}
func (p *SimpleConfigParser) UpsertOption(option string, value string) {
if _, exists := p.Lines[option]; exists {
p.ReplaceOption(option, value)
} else {
p.AddLine(option+p.Options.Separator+value, uint32(len(p.Lines)))
}
}
func (p *SimpleConfigParser) GetOption(option string) (SimpleConfigLine, error) {
if _, exists := p.Lines[option]; exists {
return p.Lines[option], nil
}
return SimpleConfigLine{
Value: "",
Position: SimpleConfigPosition{
Line: 0,
},
},
docvalues.OptionUnknownError{}
return SimpleConfigLine{}, docvalues.OptionUnknownError{}
}
func (p *SimpleConfigParser) ParseFromFile(content string) []docvalues.OptionError {

View File

@ -55,7 +55,7 @@ func (v ArrayValue) GetTypeDescription() []string {
func (v ArrayValue) CheckIsValid(value string) error {
values := strings.Split(value, v.Separator)
if v.DuplicatesExtractor != nil {
if *v.DuplicatesExtractor != nil {
valuesOccurrences := utils.SliceToMap(
utils.Map(values, *v.DuplicatesExtractor),
0,

View File

@ -6,17 +6,12 @@ import (
)
func createOpenSSHConfigParser() common.SimpleConfigParser {
pattern, err := regexp.Compile(`^(?:#|\s*$)`)
if err != nil {
panic(err)
}
return common.SimpleConfigParser{
Lines: make(map[string]common.SimpleConfigLine),
Options: common.SimpleConfigOptions{
Separator: " ",
IgnorePattern: *pattern,
Separator: *regexp.MustCompile(`(?m)^\s*(?P<OptionName>\w+)(?P<Separator>\s*)(?P<Value>.*)\s*$`),
IgnorePattern: *regexp.MustCompile(`^(?:#|\s*$)`),
IdealSeparator: " ",
AvailableOptions: &Options,
},
}

View File

@ -19,7 +19,7 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa
if params.Position.Character < uint32(len(optionName)) {
return getRootCompletions(), nil
} else {
cursor := params.Position.Character - uint32(len(optionName+Parser.Options.Separator))
cursor := params.Position.Character - uint32(line.GetCharacterPositions(optionName)[1])
return getOptionCompletions(optionName, line.Value, cursor), nil
}