fix(doc-values): Overall improvements

This commit is contained in:
Myzel394 2024-08-07 22:34:59 +02:00
parent 4d4d8a1376
commit 4aa54ffcc1
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
11 changed files with 332 additions and 12 deletions

View File

@ -159,6 +159,12 @@ func PositiveNumberValue() Value {
}
}
func MaskValue() Value {
min := 0
max := 777
return NumberValue{Min: &min, Max: &max}
}
func SingleEnumValue(value string) EnumValue {
return EnumValue{
EnforceValues: true,

View File

@ -29,7 +29,7 @@ func MergeKeyEnumAssignmentMaps(maps ...map[EnumString]Value) map[EnumString]Val
for _, m := range maps {
for key, value := range m {
if _, ok := existingEnums[key.InsertText]; !ok {
if _, ok := existingEnums[key.InsertText]; ok {
continue
}

View File

@ -122,8 +122,8 @@ func (v ArrayValue) FetchCompletions(line string, cursor uint32) []protocol.Comp
relativePosition, found := utils.FindPreviousCharacter(line, v.Separator, int(cursor-1))
if found {
line = line[uint32(relativePosition):]
cursor -= uint32(relativePosition)
line = line[uint32(relativePosition+1):]
cursor -= uint32(relativePosition + 1)
}
return v.SubValue.FetchCompletions(line, cursor)

View File

@ -30,6 +30,17 @@ type EnumString struct {
Documentation string
}
func (v EnumString) ToCompletionItem() protocol.CompletionItem {
textFormat := protocol.InsertTextFormatPlainText
kind := protocol.CompletionItemKindEnum
return protocol.CompletionItem{
Label: v.InsertText,
InsertTextFormat: &textFormat,
Kind: &kind,
Documentation: &v.Documentation,
}
}
func CreateEnumString(value string) EnumString {
return EnumString{
InsertText: value,

128
doc-values/value-gid.go Normal file
View File

@ -0,0 +1,128 @@
package docvalues
import (
"config-lsp/utils"
"strconv"
protocol "github.com/tliron/glsp/protocol_3_16"
)
type GIDNotInPasswdErr struct{}
func (e GIDNotInPasswdErr) Error() string {
return "This UID does not exist"
}
type InvalidGIDError struct{}
func (e InvalidGIDError) Error() string {
return "This UID is invalid"
}
type GIDNotInRangeError struct{}
func (e GIDNotInRangeError) Error() string {
return "UIDs must be between 0 and 65535"
}
type GIDValue struct {
EnforceUsingExisting bool
}
func (v GIDValue) GetTypeDescription() []string {
return []string{"Group ID"}
}
func (v GIDValue) CheckIsValid(value string) []*InvalidValue {
uid, err := strconv.Atoi(value)
if err != nil {
return []*InvalidValue{{
Err: InvalidGIDError{},
Start: 0,
End: uint32(len(value)),
}}
}
if uid < 0 || uid > 65535 {
return []*InvalidValue{{
Err: GIDNotInRangeError{},
Start: 0,
End: uint32(len(value)),
}}
}
if v.EnforceUsingExisting {
infos, err := fetchPasswdInfo()
if err != nil {
return []*InvalidValue{}
}
found := false
for _, info := range infos {
if info.GID == value {
found = true
break
}
}
if !found {
return []*InvalidValue{{
Err: GIDNotInPasswdErr{},
Start: 0,
End: uint32(len(value)),
}}
}
}
return []*InvalidValue{}
}
var defaultGIDsExplanation = []EnumString{
{
InsertText: "0",
DescriptionText: "root",
Documentation: "The group of the root user",
},
}
func (v GIDValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
infos, err := fetchGroupInfo()
if err != nil {
return utils.Map(defaultUIDsExplanation, func(enum EnumString) protocol.CompletionItem {
return enum.ToCompletionItem()
})
}
textFormat := protocol.InsertTextFormatPlainText
kind := protocol.CompletionItemKindValue
completions := make([]protocol.CompletionItem, len(infos))
for index, info := range infos {
// Find default gids
var existingGID *EnumString
for _, defaultGID := range defaultUIDsExplanation {
if defaultGID.InsertText == info.GID {
existingGID = &defaultGID
break
}
}
if existingGID != nil {
completions[index] = existingGID.ToCompletionItem()
} else {
completions[index] = protocol.CompletionItem{
InsertTextFormat: &textFormat,
Kind: &kind,
InsertText: &info.GID,
Documentation: info.Name,
}
}
}
return completions
}

View File

@ -111,13 +111,23 @@ func (v KeyEnumAssignmentValue) FetchEnumCompletions() []protocol.CompletionItem
for enumKey := range v.Values {
textFormat := protocol.InsertTextFormatPlainText
kind := protocol.CompletionItemKindEnum
kind := protocol.CompletionItemKindField
val := v.Values[enumKey]
description := val.GetTypeDescription()
var documentation string
if len(description) == 1 {
documentation = fmt.Sprintf("%s%s<%s> \n\n%s", enumKey.InsertText, v.Separator, description[0], enumKey.Documentation)
} else {
documentation = fmt.Sprintf("%s%s<value> \n\n%s", enumKey.InsertText, v.Separator, enumKey.Documentation)
}
completions = append(completions, protocol.CompletionItem{
Label: enumKey.InsertText,
InsertTextFormat: &textFormat,
Kind: &kind,
Documentation: &enumKey.Documentation,
Documentation: documentation,
})
}

View File

@ -1,6 +1,7 @@
package docvalues
import (
"config-lsp/utils"
"strings"
protocol "github.com/tliron/glsp/protocol_3_16"
@ -49,6 +50,26 @@ func (v OrValue) CheckIsValid(value string) []*InvalidValue {
return errors
}
func (v OrValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
// Check for special cases
if len(v.Values) == 2 {
switch v.Values[0].(type) {
case KeyEnumAssignmentValue:
if cursor > 0 {
// KeyEnumAssignment + other values
// If there is an separator, we only want to show
// the values of the KeyEnumAssignment
keyEnumValue := v.Values[0].(KeyEnumAssignmentValue)
println("line eta cursor", line, cursor)
_, found := utils.FindPreviousCharacter(line, keyEnumValue.Separator, int(cursor-1))
if found {
return keyEnumValue.FetchCompletions(line, cursor)
}
}
}
}
completions := make([]protocol.CompletionItem, 0)
for _, subValue := range v.Values {

View File

@ -62,7 +62,7 @@ var powers = []int{1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192
func (v PowerOfTwoValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
textFormat := protocol.InsertTextFormatPlainText
kind := protocol.CompletionItemKindEnum
kind := protocol.CompletionItemKindValue
return utils.Map(
powers,

View File

@ -26,16 +26,15 @@ func (v RegexValue) GetTypeDescription() []string {
}
func (v RegexValue) CheckIsValid(value string) []*InvalidValue {
if value == "" {
if !v.Regex.MatchString(value) {
return []*InvalidValue{{
Err: EmptyStringError{},
Err: RegexInvalidError{Regex: v.Regex.String()},
Start: 0,
End: uint32(len(value)),
},
}
}}
}
return nil
return []*InvalidValue{}
}
func (v RegexValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {

View File

@ -10,7 +10,15 @@ func (e EmptyStringError) Error() string {
return "This setting may not be empty"
}
type StringValue struct{}
type StringTooLongError struct{}
func (e StringTooLongError) Error() string {
return "This setting is too long"
}
type StringValue struct {
MaxLength *uint32
}
func (v StringValue) GetTypeDescription() []string {
return []string{"String"}
@ -26,6 +34,14 @@ func (v StringValue) CheckIsValid(value string) []*InvalidValue {
}
}
if v.MaxLength != nil && uint32(len(value)) > *v.MaxLength {
return []*InvalidValue{{
Err: StringTooLongError{},
Start: 0,
End: uint32(len(value)),
}}
}
return nil
}

129
doc-values/value-uid.go Normal file
View File

@ -0,0 +1,129 @@
package docvalues
import (
"config-lsp/utils"
"fmt"
"strconv"
protocol "github.com/tliron/glsp/protocol_3_16"
)
type UIDNotInPasswdErr struct{}
func (e UIDNotInPasswdErr) Error() string {
return "This UID does not exist"
}
type InvalidUIDError struct{}
func (e InvalidUIDError) Error() string {
return "This UID is invalid"
}
type UIDNotInRangeError struct{}
func (e UIDNotInRangeError) Error() string {
return "UIDs must be between 0 and 65535"
}
type UIDValue struct {
EnforceUsingExisting bool
}
func (v UIDValue) GetTypeDescription() []string {
return []string{"User ID"}
}
func (v UIDValue) CheckIsValid(value string) []*InvalidValue {
uid, err := strconv.Atoi(value)
if err != nil {
return []*InvalidValue{{
Err: InvalidUIDError{},
Start: 0,
End: uint32(len(value)),
}}
}
if uid < 0 || uid > 65535 {
return []*InvalidValue{{
Err: UIDNotInRangeError{},
Start: 0,
End: uint32(len(value)),
}}
}
if v.EnforceUsingExisting {
infos, err := fetchPasswdInfo()
if err != nil {
return []*InvalidValue{}
}
found := false
for _, info := range infos {
if info.UID == value {
found = true
break
}
}
if !found {
return []*InvalidValue{{
Err: UIDNotInPasswdErr{},
Start: 0,
End: uint32(len(value)),
}}
}
}
return []*InvalidValue{}
}
var defaultUIDsExplanation = []EnumString{
{
InsertText: "0",
DescriptionText: "root",
Documentation: "The root user",
},
}
func (v UIDValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
infos, err := fetchPasswdInfo()
if err != nil {
return utils.Map(defaultUIDsExplanation, func(enum EnumString) protocol.CompletionItem {
return enum.ToCompletionItem()
})
}
textFormat := protocol.InsertTextFormatPlainText
kind := protocol.CompletionItemKindValue
completions := make([]protocol.CompletionItem, len(infos))
for index, info := range infos {
// Find default uids
var existingUID *EnumString
for _, defaultUID := range defaultUIDsExplanation {
if defaultUID.InsertText == info.UID {
existingUID = &defaultUID
break
}
}
if existingUID != nil {
completions[index] = existingUID.ToCompletionItem()
} else {
completions[index] = protocol.CompletionItem{
InsertTextFormat: &textFormat,
Kind: &kind,
InsertText: &info.UID,
Documentation: fmt.Sprintf("User %s; Home: %s", info.Name, info.HomePath),
}
}
}
return completions
}