diff --git a/handlers/ssh_config/analyzer/match.go b/handlers/ssh_config/analyzer/match.go index e1b52e2..4f79493 100644 --- a/handlers/ssh_config/analyzer/match.go +++ b/handlers/ssh_config/analyzer/match.go @@ -81,7 +81,7 @@ func checkMatch( allEntry := allEntries[0] previousEntry := m.GetPreviousEntry(allEntry) - if previousEntry != nil && !utils.KeyExists(fields.MatchAllOptionAllowedPreviousOptions, previousEntry.Criteria.Type) { + if previousEntry != nil && !utils.KeyExists(fields.MatchAllArgumentAllowedPreviousOptions, previousEntry.Criteria.Type) { errs = append(errs, common.LSPError{ Range: allEntry.LocationRange, Err: errors.New("'all' should either be the first entry or immediately follow 'final' or 'canonical'"), diff --git a/handlers/ssh_config/fields/match.go b/handlers/ssh_config/fields/match.go index 5d65785..8803e85 100644 --- a/handlers/ssh_config/fields/match.go +++ b/handlers/ssh_config/fields/match.go @@ -27,7 +27,7 @@ var MatchValueFieldMap = map[matchparser.MatchCriteriaType]docvalues.DeprecatedV matchparser.MatchCriteriaTypeLocalUser: MatchTypeLocalUserField, } -var MatchAllOptionAllowedPreviousOptions = map[matchparser.MatchCriteriaType]struct{}{ +var MatchAllArgumentAllowedPreviousOptions = map[matchparser.MatchCriteriaType]struct{}{ matchparser.MatchCriteriaTypeCanonical: {}, matchparser.MatchCriteriaTypeFinal: {}, } diff --git a/handlers/ssh_config/handlers/completions_match.go b/handlers/ssh_config/handlers/completions_match.go index 372f38c..cc034bc 100644 --- a/handlers/ssh_config/handlers/completions_match.go +++ b/handlers/ssh_config/handlers/completions_match.go @@ -5,6 +5,7 @@ import ( sshconfig "config-lsp/handlers/ssh_config" "config-lsp/handlers/ssh_config/fields" matchparser "config-lsp/handlers/ssh_config/match-parser" + "config-lsp/utils" protocol "github.com/tliron/glsp/protocol_3_16" ) @@ -24,7 +25,21 @@ func getMatchCompletions( entry := match.GetEntryAtPosition(cursor) if entry == nil || entry.Criteria.ContainsPosition(cursor) { - return getMatchCriteriaCompletions(), nil + completions := getMatchCriteriaCompletions() + + var showAllArgument = true + + previousEntry := match.GetPreviousEntryFromCursor(cursor) + + if previousEntry != nil && !utils.KeyExists(fields.MatchAllArgumentAllowedPreviousOptions, previousEntry.Criteria.Type) { + showAllArgument = false + } + + if showAllArgument { + completions = append(completions, getMatchAllKeywordCompletion()) + } + + return completions, nil } return getMatchValueCompletions(entry, cursor), nil diff --git a/handlers/ssh_config/match-parser/match_fields.go b/handlers/ssh_config/match-parser/match_fields.go index b0c1293..d047ba5 100644 --- a/handlers/ssh_config/match-parser/match_fields.go +++ b/handlers/ssh_config/match-parser/match_fields.go @@ -53,6 +53,19 @@ func (m Match) GetPreviousEntry(e *MatchEntry) *MatchEntry { return m.Entries[index-1] } +func (m Match) GetPreviousEntryFromCursor(cursor common.CursorPosition) *MatchEntry { + entries := slices.Clone(m.Entries) + slices.Reverse(entries) + + for _, entry := range entries { + if entry.IsPositionAfterStart(cursor) { + return entry + } + } + + return nil +} + func (e MatchEntry) GetValueAtPosition(position common.Position) *MatchValue { if e.Values == nil { return nil