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,7 +147,8 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
SubValue: docvalues.ArrayValue{
|
||||
Separator: ",",
|
||||
DuplicatesExtractor: &docvalues.DuplicatesAllowedExtractor,
|
||||
SubValue: docvalues.StringValue{},
|
||||
// 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{},
|
||||
},
|
||||
},
|
||||
),
|
||||
@ -230,7 +231,7 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
},
|
||||
},
|
||||
),
|
||||
"DenyGroups": common.NewOption(`This keyword can be followed by a list of group name patterns, separated by spaces. Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny groups directives are processed in the following order: DenyGroups, AllowGroups.
|
||||
"DenyGroups": common.NewOption(`This keyword can be followed by a list of group name patterns, separated by spaces. Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny groups directives are processed in the following order: DenyGroups, AllowGroups.
|
||||
See PATTERNS in ssh_config(5) for more information on patterns. This keyword may appear multiple times in sshd_config with each instance appending to the list.`,
|
||||
docvalues.GroupValue(" ", false),
|
||||
),
|
||||
@ -430,7 +431,7 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
},
|
||||
},
|
||||
),
|
||||
"LogVerbose": common.NewOption(`Specify one or more overrides to LogLevel. An override consists of a pattern lists that matches the source file, function and line number to force detailed logging for. For example, an override pattern of:
|
||||
"LogVerbose": common.NewOption(`Specify one or more overrides to LogLevel. An override consists of a pattern lists that matches the source file, function and line number to force detailed logging for. For example, an override pattern of:
|
||||
kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
|
||||
would enable detailed logging for line 1000 of kex.c, everything in the kex_exchange_identification() function, and all code in the packet.c file. This option is intended for debugging and no overrides are enabled by default.`,
|
||||
docvalues.StringValue{},
|
||||
@ -605,16 +606,16 @@ See PATTERNS in ssh_config(5) for more information on patterns. This keyword may
|
||||
),
|
||||
|
||||
"SetEnv": common.NewOption(`Specifies one or more environment variables to set in child sessions started by sshd(8) as “NAME=VALUE”. The environment value may be quoted (e.g. if it contains whitespace characters). Environment variables set by SetEnv override the default environment and any variables specified by the user via AcceptEnv or PermitUserEnvironment.`,
|
||||
docvalues.ArrayValue{
|
||||
Separator: " ",
|
||||
DuplicatesExtractor: &SetEnvExtractor,
|
||||
SubValue: docvalues.KeyValueAssignmentValue{
|
||||
Separator: "=",
|
||||
Key: docvalues.StringValue{},
|
||||
Value: docvalues.StringValue{},
|
||||
docvalues.ArrayValue{
|
||||
Separator: " ",
|
||||
DuplicatesExtractor: &SetEnvExtractor,
|
||||
SubValue: docvalues.KeyValueAssignmentValue{
|
||||
Separator: "=",
|
||||
Key: docvalues.StringValue{},
|
||||
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