feat(ssh_config): Add first iteration of formatting

This commit is contained in:
Myzel394 2024-09-30 11:15:12 +02:00
parent d4e8269844
commit dd3c91a9ba
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
3 changed files with 217 additions and 1 deletions

View File

@ -0,0 +1,47 @@
package handlers
import (
sshconfig "config-lsp/handlers/ssh_config"
"config-lsp/handlers/ssh_config/ast"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func FormatDocument(
d *sshconfig.SSHDocument,
textRange protocol.Range,
options protocol.FormattingOptions,
) ([]protocol.TextEdit, error) {
edits := make([]protocol.TextEdit, 0)
it := d.Config.Options.Iterator()
for it.Next() {
line := it.Key().(uint32)
entry := it.Value().(ast.SSHEntry)
if !(line >= textRange.Start.Line && line <= textRange.End.Line) {
continue
}
switch entry.GetType() {
case ast.SSHTypeOption:
option := entry.(*ast.SSHOption)
edits = append(edits, formatSSHOption(
option,
options,
optionTemplate,
)...)
case ast.SSHTypeMatch:
matchBlock := entry.(*ast.SSHMatchBlock)
edits = formatSSHMatchBlock(textRange, matchBlock, options)
case ast.SSHTypeHost:
hostBlock := entry.(*ast.SSHHostBlock)
edits = formatSSHHostBlock(textRange, hostBlock, options)
}
}
return edits, nil
}

View File

@ -0,0 +1,160 @@
package handlers
import (
"config-lsp/common/formatting"
"config-lsp/handlers/ssh_config/ast"
hostparser "config-lsp/handlers/ssh_config/host-parser"
matchparser "config-lsp/handlers/ssh_config/match-parser"
"config-lsp/utils"
"fmt"
"strings"
protocol "github.com/tliron/glsp/protocol_3_16"
)
var optionTemplate = formatting.FormatTemplate(
"%s /!'%s/!'",
)
var matchTemplate = formatting.FormatTemplate(
"%s %s",
)
var matchOptionTemplate = formatting.FormatTemplate(
" %s /!'%s/!'",
)
func formatSSHOption(
option *ast.SSHOption,
options protocol.FormattingOptions,
template formatting.FormatTemplate,
) []protocol.TextEdit {
var key string
if option.Key != nil {
key = option.Key.Key
} else {
key = ""
}
var value string
if option.OptionValue != nil {
value = option.OptionValue.Value.Raw
} else {
value = ""
}
return []protocol.TextEdit{
{
Range: option.ToLSPRange(),
NewText: template.Format(options, key, value),
},
}
}
func formatSSHMatchBlock(
textRange protocol.Range,
matchBlock *ast.SSHMatchBlock,
options protocol.FormattingOptions,
) []protocol.TextEdit {
edits := make([]protocol.TextEdit, 0)
edits = append(edits, protocol.TextEdit{
Range: matchBlock.GetEntryOption().ToLSPRange(),
NewText: matchTemplate.Format(
options,
matchBlock.GetEntryOption().Key.Key,
formatMatchToString(matchBlock.MatchValue),
),
})
it := matchBlock.GetOptions().Iterator()
for it.Next() {
option := it.Value().(*ast.SSHOption)
if !(option.Start.Line >= textRange.Start.Line && option.End.Line <= textRange.End.Line) {
continue
}
edits = append(edits, formatSSHOption(
option,
options,
matchOptionTemplate,
)...)
}
return edits
}
func formatMatchToString(
match *matchparser.Match,
) string {
entriesAsStrings := utils.Map(
match.Entries,
func(entry *matchparser.MatchEntry) string {
return fmt.Sprintf(
"%s %s",
string(entry.Criteria.Type),
strings.Join(
utils.Map(
entry.Values.Values,
func(value *matchparser.MatchValue) string {
return value.Value.Raw
},
),
",",
),
)
},
)
return strings.Join(entriesAsStrings, " ")
}
func formatSSHHostBlock(
textRange protocol.Range,
hostBlock *ast.SSHHostBlock,
options protocol.FormattingOptions,
) []protocol.TextEdit {
edits := make([]protocol.TextEdit, 0)
edits = append(edits, protocol.TextEdit{
Range: hostBlock.GetEntryOption().ToLSPRange(),
NewText: matchTemplate.Format(
options,
hostBlock.GetEntryOption().Key.Key,
formatHostToString(hostBlock.HostValue),
),
})
it := hostBlock.GetOptions().Iterator()
for it.Next() {
option := it.Value().(*ast.SSHOption)
if !(option.Start.Line >= textRange.Start.Line && option.End.Line <= textRange.End.Line) {
continue
}
edits = append(edits, formatSSHOption(
option,
options,
matchOptionTemplate,
)...)
}
return edits
}
func formatHostToString(
host *hostparser.Host,
) string {
return strings.Join(
utils.Map(
host.Hosts,
func(host *hostparser.HostValue) string {
return host.Value.Raw
},
),
" ",
)
}

View File

@ -1,6 +1,9 @@
package lsp package lsp
import ( import (
sshconfig "config-lsp/handlers/ssh_config"
"config-lsp/handlers/ssh_config/handlers"
"github.com/tliron/glsp" "github.com/tliron/glsp"
protocol "github.com/tliron/glsp/protocol_3_16" protocol "github.com/tliron/glsp/protocol_3_16"
) )
@ -9,5 +12,11 @@ func TextDocumentRangeFormatting(
context *glsp.Context, context *glsp.Context,
params *protocol.DocumentRangeFormattingParams, params *protocol.DocumentRangeFormattingParams,
) ([]protocol.TextEdit, error) { ) ([]protocol.TextEdit, error) {
return nil, nil d := sshconfig.DocumentParserMap[params.TextDocument.URI]
return handlers.FormatDocument(
d,
params.Range,
params.Options,
)
} }