mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-19 07:25:27 +02:00
feat: Add TimeFormatValue
This commit is contained in:
parent
ac2d972d3d
commit
26514ed059
@ -47,11 +47,9 @@ func (p *SimpleConfigParser) AddLine(line string, lineNumber uint32) (string, er
|
||||
}
|
||||
|
||||
optionIndex := re.SubexpIndex("OptionName")
|
||||
|
||||
if optionIndex == -1 {
|
||||
return "", docvalues.MalformedLineError{}
|
||||
}
|
||||
|
||||
option = matches[optionIndex]
|
||||
|
||||
if _, exists := (*p.Options.AvailableOptions)[option]; !exists {
|
||||
@ -59,17 +57,15 @@ func (p *SimpleConfigParser) AddLine(line string, lineNumber uint32) (string, er
|
||||
}
|
||||
|
||||
separatorIndex := re.SubexpIndex("Separator")
|
||||
|
||||
if separatorIndex == -1 {
|
||||
return option, docvalues.MalformedLineError{}
|
||||
}
|
||||
separator = matches[separatorIndex]
|
||||
|
||||
valueIndex := re.SubexpIndex("Value")
|
||||
|
||||
if valueIndex == -1 {
|
||||
return option, docvalues.MalformedLineError{}
|
||||
}
|
||||
|
||||
value = matches[valueIndex]
|
||||
|
||||
if _, exists := p.Lines[option]; exists {
|
||||
|
@ -89,7 +89,6 @@ type groupInfo struct {
|
||||
|
||||
var _cachedGroupInfo []groupInfo
|
||||
|
||||
|
||||
func fetchGroupInfo() ([]groupInfo, error) {
|
||||
if len(_cachedGroupInfo) > 0 {
|
||||
return _cachedGroupInfo, nil
|
||||
|
@ -90,6 +90,10 @@ func (v ArrayValue) CheckIsValid(value string) error {
|
||||
}
|
||||
|
||||
func (v ArrayValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
|
||||
if cursor == 0 {
|
||||
return v.SubValue.FetchCompletions(line, cursor)
|
||||
}
|
||||
|
||||
relativePosition, found := utils.FindPreviousCharacter(line, v.Separator, int(cursor-1))
|
||||
|
||||
if found {
|
||||
|
@ -55,10 +55,14 @@ func (v KeyValueAssignmentValue) CheckIsValid(value string) error {
|
||||
}
|
||||
|
||||
func (v KeyValueAssignmentValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
|
||||
if cursor == 0 {
|
||||
return v.Key.FetchCompletions(line, cursor)
|
||||
}
|
||||
|
||||
relativePosition, found := utils.FindPreviousCharacter(line, v.Separator, int(cursor-1))
|
||||
|
||||
if found {
|
||||
line = line[uint32(relativePosition):]
|
||||
line = line[uint32(relativePosition+len(v.Separator)):]
|
||||
cursor -= uint32(relativePosition)
|
||||
|
||||
return v.Value.FetchCompletions(line, cursor)
|
||||
|
38
doc-values/value-regex.go
Normal file
38
doc-values/value-regex.go
Normal file
@ -0,0 +1,38 @@
|
||||
package docvalues
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
type RegexInvalidError struct {
|
||||
Regex string
|
||||
}
|
||||
|
||||
func (e RegexInvalidError) Error() string {
|
||||
return fmt.Sprintf("This value does not match the regular expression (Pattern: `%s`)", e.Regex)
|
||||
}
|
||||
|
||||
type RegexValue struct {
|
||||
Regex regexp.Regexp
|
||||
}
|
||||
|
||||
func (v RegexValue) GetTypeDescription() []string {
|
||||
return []string{
|
||||
fmt.Sprintf("String matching the regular expression (Pattern: `%s`)", v.Regex.String()),
|
||||
}
|
||||
}
|
||||
|
||||
func (v RegexValue) CheckIsValid(value string) error {
|
||||
if value == "" {
|
||||
return EmptyStringError{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v RegexValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
|
||||
return []protocol.CompletionItem{}
|
||||
}
|
@ -147,6 +147,7 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
SubValue: docvalues.ArrayValue{
|
||||
Separator: ",",
|
||||
DuplicatesExtractor: &docvalues.DuplicatesAllowedExtractor,
|
||||
// TODO: Add
|
||||
SubValue: docvalues.StringValue{},
|
||||
},
|
||||
},
|
||||
@ -182,7 +183,7 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
"x11-connection",
|
||||
},
|
||||
},
|
||||
Value: docvalues.StringValue{},
|
||||
Value: TimeFormatValue{},
|
||||
},
|
||||
},
|
||||
),
|
||||
@ -614,7 +615,7 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
Value: docvalues.StringValue{},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
"StreamLocalBindMask": common.NewOption(`Sets the octal file creation mode mask (umask) used when creating a Unix-domain socket file for local or remote port forwarding. This option is only used for port forwarding to a Unix-domain socket file.
|
||||
The default value is 0177, which creates a Unix-domain socket file that is readable and writable only by the owner. Note that not all operating systems honor the file mode on Unix-domain socket files.`,
|
||||
docvalues.PositiveNumberValue{},
|
||||
|
109
handlers/openssh/value-time-format.go
Normal file
109
handlers/openssh/value-time-format.go
Normal file
@ -0,0 +1,109 @@
|
||||
package openssh
|
||||
|
||||
import (
|
||||
docvalues "config-lsp/doc-values"
|
||||
"config-lsp/utils"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
var timeFormatCompletionsPattern = regexp.MustCompile(`(?i)^(\d+)([smhdw])$`)
|
||||
var timeFormatCheckPattern = regexp.MustCompile(`(?i)^(\d+)([smhdw]?)$`)
|
||||
var isJustDigitsPattern = regexp.MustCompile(`^\d+$`)
|
||||
|
||||
type TimeFormatValue struct{}
|
||||
|
||||
func (v TimeFormatValue) GetTypeDescription() []string {
|
||||
return []string{"Time value"}
|
||||
}
|
||||
|
||||
func (v TimeFormatValue) CheckIsValid(value string) error {
|
||||
if !timeFormatCheckPattern.MatchString(value) {
|
||||
return docvalues.RegexInvalidError{Regex: timeFormatCheckPattern.String()}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func calculateInSeconds(value int, unit string) int {
|
||||
switch unit {
|
||||
case "s":
|
||||
return value
|
||||
case "m":
|
||||
return value * 60
|
||||
case "h":
|
||||
return value * 60 * 60
|
||||
case "d":
|
||||
return value * 60 * 60 * 24
|
||||
case "w":
|
||||
return value * 60 * 60 * 24 * 7
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (v TimeFormatValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem {
|
||||
completions := make([]protocol.CompletionItem, 0)
|
||||
|
||||
if line != "" && !timeFormatCompletionsPattern.MatchString(line) {
|
||||
completions = append(
|
||||
completions,
|
||||
utils.Map(
|
||||
[]string{"s", "m", "h", "d", "w"},
|
||||
func(unit string) protocol.CompletionItem {
|
||||
kind := protocol.CompletionItemKindValue
|
||||
|
||||
unitName := map[string]string{
|
||||
"s": "seconds",
|
||||
"m": "minutes",
|
||||
"h": "hours",
|
||||
"d": "days",
|
||||
"w": "weeks",
|
||||
}[unit]
|
||||
|
||||
var detail string
|
||||
value, err := strconv.Atoi(line)
|
||||
|
||||
if err == nil {
|
||||
if unit == "s" {
|
||||
detail = fmt.Sprintf("%d seconds", value)
|
||||
} else {
|
||||
detail = fmt.Sprintf("%d %s (%d seconds)", value, unitName, calculateInSeconds(value, unit))
|
||||
}
|
||||
}
|
||||
|
||||
return protocol.CompletionItem{
|
||||
Label: line + unit,
|
||||
Kind: &kind,
|
||||
Detail: &detail,
|
||||
}
|
||||
},
|
||||
)...,
|
||||
)
|
||||
}
|
||||
|
||||
if line == "" || isJustDigitsPattern.MatchString(line) {
|
||||
completions = append(
|
||||
completions,
|
||||
utils.Map(
|
||||
[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
func(index int) protocol.CompletionItem {
|
||||
kind := protocol.CompletionItemKindValue
|
||||
|
||||
sortText := strconv.Itoa(index)
|
||||
|
||||
return protocol.CompletionItem{
|
||||
Label: line + strconv.Itoa(index),
|
||||
Kind: &kind,
|
||||
SortText: &sortText,
|
||||
}
|
||||
},
|
||||
)...,
|
||||
)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user