mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-19 07:25:27 +02:00
feat(gitconfig): Add fields; Improvements
This commit is contained in:
parent
45748a0634
commit
896207cc7b
@ -45,11 +45,11 @@ func calculateLineToKilobyte(value string, unit string) string {
|
|||||||
|
|
||||||
switch unit {
|
switch unit {
|
||||||
case "K":
|
case "K":
|
||||||
return strconv.Itoa(val)
|
|
||||||
case "M":
|
|
||||||
return strconv.Itoa(val * 1000)
|
return strconv.Itoa(val * 1000)
|
||||||
case "G":
|
case "M":
|
||||||
return strconv.Itoa(val * 1000 * 1000)
|
return strconv.Itoa(val * 1000 * 1000)
|
||||||
|
case "G":
|
||||||
|
return strconv.Itoa(val * 1000 * 1000 * 1000)
|
||||||
default:
|
default:
|
||||||
return "<unknown>"
|
return "<unknown>"
|
||||||
}
|
}
|
||||||
|
66
server/doc-values/value-hex-color.go
Normal file
66
server/doc-values/value-hex-color.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package docvalues
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
var color24BitPattern = regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
|
||||||
|
var color12BitPattern = regexp.MustCompile(`^#[0-9a-fA-F]{3}$`)
|
||||||
|
|
||||||
|
type InvalidColorError struct{}
|
||||||
|
|
||||||
|
func (e InvalidColorError) Error() string {
|
||||||
|
return "Color is invalid. It must be in the form of: #RRGGBB"
|
||||||
|
}
|
||||||
|
|
||||||
|
type HexColorValue struct {
|
||||||
|
Allow12Bit bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v HexColorValue) GetTypeDescription() []string {
|
||||||
|
return []string{"Color in HEX-Format (e.g. #RRGGBB)"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v HexColorValue) DeprecatedCheckIsValid(value string) []*InvalidValue {
|
||||||
|
if color24BitPattern.MatchString(value) || (v.Allow12Bit && color12BitPattern.MatchString(value)) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return []*InvalidValue{
|
||||||
|
{
|
||||||
|
Err: InvalidColorError{},
|
||||||
|
Start: 0,
|
||||||
|
End: uint32(len(value)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var characters = []rune{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}
|
||||||
|
|
||||||
|
func (v HexColorValue) DeprecatedFetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
|
||||||
|
completions := make([]protocol.CompletionItem, 0)
|
||||||
|
|
||||||
|
if line == "" {
|
||||||
|
kind := protocol.CompletionItemKindValue
|
||||||
|
completions = append(completions, protocol.CompletionItem{
|
||||||
|
Label: "#",
|
||||||
|
Kind: &kind,
|
||||||
|
})
|
||||||
|
} else if !color24BitPattern.MatchString(line) {
|
||||||
|
for _, c := range characters {
|
||||||
|
kind := protocol.CompletionItemKindValue
|
||||||
|
completions = append(completions, protocol.CompletionItem{
|
||||||
|
Label: string(c),
|
||||||
|
Kind: &kind,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return completions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v HexColorValue) DeprecatedFetchHoverInfo(line string, cursor uint32) []string {
|
||||||
|
return []string{"Color in HEX-Format (e.g. #RRGGBB)"}
|
||||||
|
}
|
@ -46,8 +46,12 @@ func (v PathValue) GetTypeDescription() []string {
|
|||||||
return []string{strings.Join(hints, ", ")}
|
return []string{strings.Join(hints, ", ")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v PathValue) createSystemPath(value string) string {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
func (v PathValue) DeprecatedCheckIsValid(value string) []*InvalidValue {
|
func (v PathValue) DeprecatedCheckIsValid(value string) []*InvalidValue {
|
||||||
if !utils.DoesPathExist(value) {
|
if !utils.DoesPathExist(v.createSystemPath(value)) {
|
||||||
return []*InvalidValue{{
|
return []*InvalidValue{{
|
||||||
Err: PathDoesNotExistError{},
|
Err: PathDoesNotExistError{},
|
||||||
Start: 0,
|
Start: 0,
|
||||||
|
@ -107,5 +107,5 @@ func (v TimeFormatValue) DeprecatedFetchCompletions(line string, cursor uint32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v TimeFormatValue) DeprecatedFetchHoverInfo(line string, cursor uint32) []string {
|
func (v TimeFormatValue) DeprecatedFetchHoverInfo(line string, cursor uint32) []string {
|
||||||
return []string{}
|
return []string{"A time value. For example: 5m (5 minutes)"}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,11 @@ type GitEntry struct {
|
|||||||
Value *GitValue
|
Value *GitValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GitSectionTitle string
|
||||||
|
|
||||||
type GitSectionHeader struct {
|
type GitSectionHeader struct {
|
||||||
common.LocationRange
|
common.LocationRange
|
||||||
Title string
|
Title GitSectionTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
type GitSection struct {
|
type GitSection struct {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import "slices"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
func (c *GitConfig) Clear() {
|
func (c *GitConfig) Clear() {
|
||||||
c.Sections = []*GitSection{}
|
c.Sections = []*GitSection{}
|
||||||
@ -66,3 +71,33 @@ func (s *GitSection) FindOption(line uint32) *GitEntry {
|
|||||||
|
|
||||||
return s.Entries[index]
|
return s.Entries[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nonWhitespacePattern = regexp.MustCompile(`\S+`)
|
||||||
|
var deprecatedSectionPattern = regexp.MustCompile(`.+?\..+`)
|
||||||
|
|
||||||
|
func (t GitSectionTitle) NormalizedTitle() string {
|
||||||
|
entries := nonWhitespacePattern.FindAllString(string(t), -1)
|
||||||
|
|
||||||
|
if entries == nil {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(entries) == 1 {
|
||||||
|
title := entries[0]
|
||||||
|
|
||||||
|
dotEntries := strings.Split(title, ".")
|
||||||
|
|
||||||
|
if len(dotEntries) == 2 {
|
||||||
|
// Deprecated title format
|
||||||
|
return fmt.Sprintf(`%s "%s"`, strings.ToLower(dotEntries[0]), strings.ToLower(dotEntries[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.ToLower(title)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(entries) == 2 {
|
||||||
|
return fmt.Sprintf(`%s "%s"`, strings.ToLower(entries[0]), entries[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
@ -157,7 +157,7 @@ func (c *GitConfig) parseHeader(
|
|||||||
LocationRange: location,
|
LocationRange: location,
|
||||||
Title: &GitSectionHeader{
|
Title: &GitSectionHeader{
|
||||||
LocationRange: location,
|
LocationRange: location,
|
||||||
Title: input[leftBracketIndex+1 : rightBracketIndex],
|
Title: GitSectionTitle(input[leftBracketIndex+1 : rightBracketIndex]),
|
||||||
},
|
},
|
||||||
Entries: make([]*GitEntry, 0),
|
Entries: make([]*GitEntry, 0),
|
||||||
}
|
}
|
||||||
|
9
server/handlers/gitconfig/fields/common.go
Normal file
9
server/handlers/gitconfig/fields/common.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package fields
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type NormalizedOptionName string
|
||||||
|
|
||||||
|
func CreateNormalizedName(s string) NormalizedOptionName {
|
||||||
|
return NormalizedOptionName(strings.ToLower(s))
|
||||||
|
}
|
1046
server/handlers/gitconfig/fields/options.go
Normal file
1046
server/handlers/gitconfig/fields/options.go
Normal file
File diff suppressed because it is too large
Load Diff
98
server/handlers/gitconfig/fields/values-integer.go
Normal file
98
server/handlers/gitconfig/fields/values-integer.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package fields
|
||||||
|
|
||||||
|
import (
|
||||||
|
docvalues "config-lsp/doc-values"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
var isJustDigitsPattern = regexp.MustCompile(`^\d+$`)
|
||||||
|
var dataAmountCheckPattern = regexp.MustCompile(`(?i)^(\d+)([kmg])$`)
|
||||||
|
|
||||||
|
type InvalidIntegerError struct{}
|
||||||
|
|
||||||
|
func (e InvalidIntegerError) Error() string {
|
||||||
|
return "Integer is invalid. It must be in the form of: <number>[k|m|g]"
|
||||||
|
}
|
||||||
|
|
||||||
|
type IntegerValue struct{}
|
||||||
|
|
||||||
|
func (v IntegerValue) GetTypeDescription() []string {
|
||||||
|
return []string{"Integer"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v IntegerValue) DeprecatedCheckIsValid(value string) []*docvalues.InvalidValue {
|
||||||
|
if !dataAmountCheckPattern.MatchString(value) {
|
||||||
|
return []*docvalues.InvalidValue{
|
||||||
|
{
|
||||||
|
Err: InvalidIntegerError{},
|
||||||
|
Start: 0,
|
||||||
|
End: uint32(len(value)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateLineToKilobyte(value string, unit string) string {
|
||||||
|
val, err := strconv.Atoi(value)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "<unknown>"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch unit {
|
||||||
|
case "K":
|
||||||
|
return strconv.Itoa(val * 1024)
|
||||||
|
case "m":
|
||||||
|
return strconv.Itoa(val * 1024 * 1024)
|
||||||
|
case "g":
|
||||||
|
return strconv.Itoa(val * 1024 * 1024 * 1024)
|
||||||
|
default:
|
||||||
|
return "<unknown>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v IntegerValue) DeprecatedFetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
|
||||||
|
completions := make([]protocol.CompletionItem, 0)
|
||||||
|
|
||||||
|
if line != "" && !dataAmountCheckPattern.MatchString(line) {
|
||||||
|
kind := protocol.CompletionItemKindValue
|
||||||
|
|
||||||
|
completions = append(
|
||||||
|
completions,
|
||||||
|
protocol.CompletionItem{
|
||||||
|
Label: line + "k",
|
||||||
|
Kind: &kind,
|
||||||
|
Documentation: fmt.Sprintf("scale %d by x1024", line),
|
||||||
|
},
|
||||||
|
protocol.CompletionItem{
|
||||||
|
Label: line + "m",
|
||||||
|
Kind: &kind,
|
||||||
|
Documentation: fmt.Sprintf("scale %d by x1024x1024", line),
|
||||||
|
},
|
||||||
|
protocol.CompletionItem{
|
||||||
|
Label: line + "g",
|
||||||
|
Kind: &kind,
|
||||||
|
Documentation: fmt.Sprintf("scale %d by x1024x1024x1024", line),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if line == "" || isJustDigitsPattern.MatchString(line) {
|
||||||
|
completions = append(
|
||||||
|
completions,
|
||||||
|
docvalues.GenerateBase10Completions(line)...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return completions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v IntegerValue) DeprecatedFetchHoverInfo(line string, cursor uint32) []string {
|
||||||
|
return []string{}
|
||||||
|
}
|
53
server/handlers/gitconfig/fields/values-pathname.go
Normal file
53
server/handlers/gitconfig/fields/values-pathname.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package fields
|
||||||
|
|
||||||
|
import (
|
||||||
|
docvalues "config-lsp/doc-values"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PathnameValue struct {
|
||||||
|
*docvalues.PathValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check if this works
|
||||||
|
func (v PathnameValue) createSystemPath(value string) string {
|
||||||
|
if strings.HasPrefix(value, "~/") {
|
||||||
|
// Path of current user
|
||||||
|
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
relativePath := strings.TrimPrefix(value, "~/")
|
||||||
|
return path.Join(home, relativePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(value, "~") {
|
||||||
|
// Path of another user
|
||||||
|
|
||||||
|
// TODO: Check how this is supposed to work.
|
||||||
|
// Why would you want to get the home directory of another user?
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
// nextSlash := strings.Index(value, "/")
|
||||||
|
//
|
||||||
|
// if nextSlash == -1 {
|
||||||
|
// // Path missing
|
||||||
|
// return value
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// user := value[1:nextSlash]
|
||||||
|
// relativePath := value[nextSlash+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(value, "%(prefix)/") {
|
||||||
|
// yeah hell no
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
88
server/handlers/gitconfig/fields/values.go
Normal file
88
server/handlers/gitconfig/fields/values.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package fields
|
||||||
|
|
||||||
|
import (
|
||||||
|
docvalues "config-lsp/doc-values"
|
||||||
|
"config-lsp/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var BooleanField = docvalues.EnumValue{
|
||||||
|
EnforceValues: true,
|
||||||
|
Values: []docvalues.EnumString{
|
||||||
|
docvalues.CreateEnumString("yes"),
|
||||||
|
docvalues.CreateEnumString("on"),
|
||||||
|
docvalues.CreateEnumString("true"),
|
||||||
|
docvalues.CreateEnumString("1"),
|
||||||
|
|
||||||
|
docvalues.CreateEnumString("no"),
|
||||||
|
docvalues.CreateEnumString("off"),
|
||||||
|
docvalues.CreateEnumString("false"),
|
||||||
|
docvalues.CreateEnumString("0"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var ColorField = docvalues.ArrayValue{
|
||||||
|
DuplicatesExtractor: &docvalues.SimpleDuplicatesExtractor,
|
||||||
|
Separator: " ",
|
||||||
|
SubValue: docvalues.OrValue{
|
||||||
|
Values: []docvalues.DeprecatedValue{
|
||||||
|
docvalues.NumberRangeValue(0, 255),
|
||||||
|
docvalues.HexColorValue{Allow12Bit: true},
|
||||||
|
docvalues.EnumValue{
|
||||||
|
EnforceValues: true,
|
||||||
|
Values: utils.MergeSlices(
|
||||||
|
fetchColors(),
|
||||||
|
fetchAttributes(),
|
||||||
|
[]docvalues.EnumString{
|
||||||
|
docvalues.CreateEnumString("normal"),
|
||||||
|
docvalues.CreateEnumString("default"),
|
||||||
|
docvalues.CreateEnumString("reset"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchColors() []docvalues.EnumString {
|
||||||
|
colors := []string{
|
||||||
|
"black",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"yellow",
|
||||||
|
"blue",
|
||||||
|
"magenta",
|
||||||
|
"cyan",
|
||||||
|
"white",
|
||||||
|
}
|
||||||
|
|
||||||
|
enums := make([]docvalues.EnumString, 0)
|
||||||
|
|
||||||
|
for _, color := range colors {
|
||||||
|
enums = append(enums, docvalues.CreateEnumString(color))
|
||||||
|
enums = append(enums, docvalues.CreateEnumString("bright"+color))
|
||||||
|
}
|
||||||
|
|
||||||
|
return enums
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchAttributes() []docvalues.EnumString {
|
||||||
|
attributes := []string{
|
||||||
|
"bold",
|
||||||
|
"dim",
|
||||||
|
"ul",
|
||||||
|
"blink",
|
||||||
|
"reverse",
|
||||||
|
"italic",
|
||||||
|
"strike",
|
||||||
|
}
|
||||||
|
|
||||||
|
enums := make([]docvalues.EnumString, 0)
|
||||||
|
|
||||||
|
for _, attribute := range attributes {
|
||||||
|
enums = append(enums, docvalues.CreateEnumString(attribute))
|
||||||
|
enums = append(enums, docvalues.CreateEnumString("no"+attribute))
|
||||||
|
enums = append(enums, docvalues.CreateEnumString("no-"+attribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
return enums
|
||||||
|
}
|
@ -141,3 +141,13 @@ func MergeMaps[T comparable, O any](maps ...map[T]O) map[T]O {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MergeSlices[T any](slices ...[]T) []T {
|
||||||
|
result := make([]T, 0)
|
||||||
|
|
||||||
|
for _, slice := range slices {
|
||||||
|
result = append(result, slice...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user