Skip to content

Commit

Permalink
feat(ssh_config): Add completions for match option
Browse files Browse the repository at this point in the history
  • Loading branch information
Myzel394 committed Sep 29, 2024
1 parent ac1d14d commit 3afcf4c
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 19 deletions.
66 changes: 66 additions & 0 deletions handlers/ssh_config/ast/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,72 @@ Match originalhost laptop exec "[[ $(/usr/bin/dig +short laptop.lan) == '' ]]"
}
}

func TestIncompleteExample(
t *testing.T,
) {
input := utils.Dedent(`
User
`)
p := NewSSHConfig()

errors := p.Parse(input)

if len(errors) > 0 {
t.Fatalf("Expected no errors, got %v", errors)
}

if !(p.Options.Size() == 1) {
t.Errorf("Expected 1 option, but got: %v", p.Options.Size())
}

if !(len(utils.KeysOfMap(p.CommentLines)) == 0) {
t.Errorf("Expected no comment lines, but got: %v", len(p.CommentLines))
}

rawFirstEntry, _ := p.Options.Get(uint32(0))
firstEntry := rawFirstEntry.(*SSHOption)
if !(firstEntry.Value.Raw == "User " && firstEntry.Key.Value.Raw == "User") {
t.Errorf("Expected first entry to be User, but got: %v", firstEntry)
}

if !(firstEntry.OptionValue != nil && firstEntry.OptionValue.Value.Raw == "") {
t.Errorf("Expected first entry to have an empty value, but got: %v", firstEntry)
}
}

func TestIncompleteMatch(
t *testing.T,
) {
input := utils.Dedent(`
Match
`)
p := NewSSHConfig()

errors := p.Parse(input)

if len(errors) > 0 {
t.Fatalf("Expected no errors, got %v", errors)
}

if !(p.Options.Size() == 1) {
t.Errorf("Expected 1 option, but got: %v", p.Options.Size())
}

if !(len(utils.KeysOfMap(p.CommentLines)) == 0) {
t.Errorf("Expected no comment lines, but got: %v", len(p.CommentLines))
}

rawFirstEntry, _ := p.Options.Get(uint32(0))
firstEntry := rawFirstEntry.(*SSHMatchBlock)
if !(firstEntry.MatchOption.Key.Value.Raw == "Match") {
t.Errorf("Expected first entry to be User, but got: %v", firstEntry)
}

if !(firstEntry.MatchOption.OptionValue != nil && firstEntry.MatchOption.OptionValue.Value.Raw == "") {
t.Errorf("Expected first entry to have an empty value, but got: %v", firstEntry)
}
}

func TestComplexBigExample(
t *testing.T,
) {
Expand Down
4 changes: 4 additions & 0 deletions handlers/ssh_config/ast/ssh_config_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ func (c SSHConfig) FindOption(line uint32) (*SSHOption, SSHBlock) {
option = rawOption.(*SSHOption)
}
} else {
if line == block.GetLocation().Start.Line {
return block.GetEntryOption(), block
}

if rawOption, found := block.GetOptions().Get(line); found {
option = rawOption.(*SSHOption)
}
Expand Down
27 changes: 27 additions & 0 deletions handlers/ssh_config/fields/match.go
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
package fields

import (
docvalues "config-lsp/doc-values"
matchparser "config-lsp/handlers/ssh_config/match-parser"
)

var MatchExecField = docvalues.StringValue{}
var MatchLocalNetworkField = docvalues.IPAddressValue{
AllowIPv4: true,
AllowIPv6: true,
AllowRange: false,
}
var MatchHostField = docvalues.StringValue{}
var MatchOriginalHostField = docvalues.StringValue{}
var MatchTypeTaggedField = docvalues.StringValue{}
var MatchUserField = docvalues.UserValue("", false)
var MatchTypeLocalUserField = docvalues.UserValue("", false)

var MatchValueFieldMap = map[matchparser.MatchCriteriaType]docvalues.DeprecatedValue{
matchparser.MatchCriteriaTypeExec: MatchExecField,
matchparser.MatchCriteriaTypeLocalNetwork: MatchLocalNetworkField,
matchparser.MatchCriteriaTypeHost: MatchHostField,
matchparser.MatchCriteriaTypeOriginalHost: MatchOriginalHostField,
matchparser.MatchCriteriaTypeTagged: MatchTypeTaggedField,
matchparser.MatchCriteriaTypeUser: MatchUserField,
matchparser.MatchCriteriaTypeLocalUser: MatchTypeLocalUserField,
}
12 changes: 6 additions & 6 deletions handlers/ssh_config/handlers/completions.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ func GetOptionCompletions(
}

if entry.Key.Key == "Match" {
return nil, nil
// return getMatchCompletions(
// d,
// cursor,
// matchBlock.MatchValue,
// )
matchBlock := block.(*ast.SSHMatchBlock)
return getMatchCompletions(
d,
cursor,
matchBlock.MatchValue,
)
}

if entry.OptionValue == nil {
Expand Down
27 changes: 14 additions & 13 deletions handlers/ssh_config/handlers/completions_match.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package handlers
import (
"config-lsp/common"
sshconfig "config-lsp/handlers/ssh_config"
"config-lsp/handlers/ssh_config/fields"
matchparser "config-lsp/handlers/ssh_config/match-parser"
"config-lsp/handlers/sshd_config/fields"

protocol "github.com/tliron/glsp/protocol_3_16"
)

Expand Down Expand Up @@ -103,20 +104,20 @@ func getMatchValueCompletions(
}

switch entry.Criteria.Type {
case matchparser.MatchCriteriaTypeUser:
return fields.MatchUserField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeGroup:
return fields.MatchGroupField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeExec:
return fields.MatchExecField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeLocalNetwork:
return fields.MatchLocalNetworkField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeHost:
return fields.MatchHostField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeAddress:
return fields.MatchAddressField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeLocalAddress:
return fields.MatchLocalAddressField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeLocalPort:
return fields.MatchLocalPortField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeRDomain:
return fields.MatchRDomainField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeOriginalHost:
return fields.MatchOriginalHostField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeTagged:
return fields.MatchTypeTaggedField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeUser:
return fields.MatchUserField.DeprecatedFetchCompletions(line, relativeCursor)
case matchparser.MatchCriteriaTypeLocalUser:
return fields.MatchTypeLocalUserField.DeprecatedFetchCompletions(line, relativeCursor)
}

return nil
Expand Down

0 comments on commit 3afcf4c

Please sign in to comment.