mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 15:05:28 +02:00
feat(ssh_config): Add completions support for tokens
This commit is contained in:
parent
3caaf6aec4
commit
b4aaa2cc3a
@ -28,7 +28,7 @@ func analyzeTokens(
|
||||
tokens = []string{}
|
||||
}
|
||||
|
||||
disallowedTokens := utils.Without(fields.AvailableTokens, tokens)
|
||||
disallowedTokens := utils.Without(utils.KeysOfMap(fields.AvailableTokens), tokens)
|
||||
|
||||
for _, token := range disallowedTokens {
|
||||
if strings.Contains(text, token) {
|
||||
|
@ -1,25 +1,27 @@
|
||||
package fields
|
||||
|
||||
var AvailableTokens = []string{
|
||||
"%%",
|
||||
"%C",
|
||||
"%d",
|
||||
"%f",
|
||||
"%H",
|
||||
"%h",
|
||||
"%l",
|
||||
"%i",
|
||||
"%j",
|
||||
"%K",
|
||||
"%k",
|
||||
"%L",
|
||||
"%l",
|
||||
"%n",
|
||||
"%p",
|
||||
"%r",
|
||||
"%T",
|
||||
"%t",
|
||||
"%u",
|
||||
import "config-lsp/utils"
|
||||
|
||||
var AvailableTokens = map[string]string{
|
||||
"%%": "A literal ‘%’.",
|
||||
"%C": "Hash of %l%h%p%r%j.",
|
||||
"%d": "Local user's home directory.",
|
||||
"%f": "The fingerprint of the server's host key.",
|
||||
"%H": "The known_hosts hostname or address that is being searched for.",
|
||||
"%h": "The remote hostname.",
|
||||
"%I": "A string describing the reason for a KnownHostsCommand execution: either ADDRESS when looking up a host by address (only when CheckHostIP is enabled), HOSTNAME when searching by hostname, or ORDER when preparing the host key algorithm preference list to use for the destination host.",
|
||||
"%i": "The local user ID.",
|
||||
"%j": "The contents of the ProxyJump option, or the empty string if this option is unset.",
|
||||
"%K": "The base64 encoded host key.",
|
||||
"%k": "The host key alias if specified, otherwise the original remote hostname given on the command line.",
|
||||
"%L": "The local hostname.",
|
||||
"%l": "The local hostname, including the domain name.",
|
||||
"%n": "The original remote hostname, as given on the command line.",
|
||||
"%p": "The remote port.",
|
||||
"%r": "The remote username.",
|
||||
"%T": "The local tun(4) or tap(4) network interface assigned if tunnel forwarding was requested, or \"NONE\" otherwise.",
|
||||
"%t": "The type of the server host key, e.g. ssh-ed25519.",
|
||||
"%u": "The local username.",
|
||||
}
|
||||
|
||||
// A map of <option name> to <list of supported tokens>
|
||||
@ -47,7 +49,7 @@ var OptionsTokensMap = map[NormalizedOptionName][]string{
|
||||
"%h",
|
||||
},
|
||||
|
||||
"localcommand": AvailableTokens,
|
||||
"localcommand": utils.KeysOfMap(AvailableTokens),
|
||||
|
||||
"proxycommand": {
|
||||
"%%", "%h", "%n", "%p", "%r",
|
||||
|
@ -15,7 +15,7 @@ func GetRootCompletions(
|
||||
d *sshconfig.SSHDocument,
|
||||
parentBlock ast.SSHBlock,
|
||||
suggestValue bool,
|
||||
) ([]protocol.CompletionItem, error) {
|
||||
) []protocol.CompletionItem {
|
||||
kind := protocol.CompletionItemKindField
|
||||
|
||||
availableOptions := make(map[fields.NormalizedOptionName]docvalues.DocumentationValue, 0)
|
||||
@ -58,7 +58,7 @@ func GetRootCompletions(
|
||||
|
||||
return *completion
|
||||
},
|
||||
), nil
|
||||
)
|
||||
}
|
||||
|
||||
func GetOptionCompletions(
|
||||
@ -67,11 +67,11 @@ func GetOptionCompletions(
|
||||
block ast.SSHBlock,
|
||||
line uint32,
|
||||
cursor common.CursorPosition,
|
||||
) ([]protocol.CompletionItem, error) {
|
||||
) []protocol.CompletionItem {
|
||||
option, found := fields.Options[entry.Key.Key]
|
||||
|
||||
if !found {
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
if entry.Key.Key == matchOption {
|
||||
@ -92,18 +92,48 @@ func GetOptionCompletions(
|
||||
}
|
||||
|
||||
if entry.OptionValue == nil {
|
||||
return option.DeprecatedFetchCompletions("", 0), nil
|
||||
return option.DeprecatedFetchCompletions("", 0)
|
||||
}
|
||||
|
||||
// token completions
|
||||
completions := getTokenCompletions(entry, cursor)
|
||||
|
||||
// Hello wo|rld
|
||||
lineValue := entry.OptionValue.Value.Raw
|
||||
// NEW: docvalues index
|
||||
return option.DeprecatedFetchCompletions(
|
||||
completions = append(completions, option.DeprecatedFetchCompletions(
|
||||
lineValue,
|
||||
common.DeprecatedImprovedCursorToIndex(
|
||||
cursor,
|
||||
lineValue,
|
||||
entry.OptionValue.Start.Character,
|
||||
),
|
||||
), nil
|
||||
)...)
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
func getTokenCompletions(
|
||||
entry *ast.SSHOption,
|
||||
cursor common.CursorPosition,
|
||||
) []protocol.CompletionItem {
|
||||
completions := make([]protocol.CompletionItem, 0)
|
||||
index := common.CursorToCharacterIndex(uint32(cursor))
|
||||
|
||||
if entry.Value.Raw[index] == '%' {
|
||||
if tokens, found := fields.OptionsTokensMap[entry.Key.Key]; found {
|
||||
for _, token := range tokens {
|
||||
description := fields.AvailableTokens[token]
|
||||
kind := protocol.CompletionItemKindConstant
|
||||
|
||||
completions = append(completions, protocol.CompletionItem{
|
||||
Label: token,
|
||||
Kind: &kind,
|
||||
Documentation: description,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ func getMatchCompletions(
|
||||
d *sshconfig.SSHDocument,
|
||||
cursor common.CursorPosition,
|
||||
match *matchparser.Match,
|
||||
) ([]protocol.CompletionItem, error) {
|
||||
) []protocol.CompletionItem {
|
||||
if match == nil || len(match.Entries) == 0 {
|
||||
completions := getMatchCriteriaCompletions()
|
||||
completions = append(completions, getMatchAllKeywordCompletion())
|
||||
|
||||
return completions, nil
|
||||
return completions
|
||||
}
|
||||
|
||||
entry := match.GetEntryAtPosition(cursor)
|
||||
@ -39,10 +39,10 @@ func getMatchCompletions(
|
||||
completions = append(completions, getMatchAllKeywordCompletion())
|
||||
}
|
||||
|
||||
return completions, nil
|
||||
return completions
|
||||
}
|
||||
|
||||
return getMatchValueCompletions(entry, cursor), nil
|
||||
return getMatchValueCompletions(entry, cursor)
|
||||
}
|
||||
|
||||
func getMatchCriteriaCompletions() []protocol.CompletionItem {
|
||||
|
@ -15,7 +15,7 @@ func getTagCompletions(
|
||||
line uint32,
|
||||
cursor common.CursorPosition,
|
||||
entry *ast.SSHOption,
|
||||
) ([]protocol.CompletionItem, error) {
|
||||
) []protocol.CompletionItem {
|
||||
completions := make([]protocol.CompletionItem, 0)
|
||||
|
||||
for name, info := range d.Indexes.Tags {
|
||||
@ -35,7 +35,7 @@ func getTagCompletions(
|
||||
})
|
||||
}
|
||||
|
||||
return completions, nil
|
||||
return completions
|
||||
}
|
||||
|
||||
func renderMatchBlock(
|
||||
|
@ -34,7 +34,7 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa
|
||||
block,
|
||||
// Empty line, or currently typing a new key
|
||||
option == nil || isEmptyPattern.Match([]byte(option.Value.Raw[cursor:])),
|
||||
)
|
||||
), nil
|
||||
}
|
||||
|
||||
if option.Separator != nil && option.OptionValue.IsPositionAfterStart(cursor) {
|
||||
@ -44,7 +44,7 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa
|
||||
block,
|
||||
line,
|
||||
cursor,
|
||||
)
|
||||
), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user