refactor(sshd_config): Migrating cursor to index position

This commit is contained in:
Myzel394 2024-09-21 11:49:09 +02:00
parent ad8311d0c6
commit 41472c1a58
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
13 changed files with 74 additions and 59 deletions

View File

@ -31,13 +31,13 @@ PasswordAuthentication yes
firstEntry.LocationRange.Start.Line == 0 &&
firstEntry.LocationRange.End.Line == 0 &&
firstEntry.LocationRange.Start.Character == 0 &&
firstEntry.LocationRange.End.Character == 17 &&
firstEntry.LocationRange.End.Character == 18 &&
firstEntry.Key.Value.Value == "PermitRootLogin" &&
firstEntry.Key.LocationRange.Start.Character == 0 &&
firstEntry.Key.LocationRange.End.Character == 14 &&
firstEntry.Key.LocationRange.End.Character == 15 &&
firstEntry.OptionValue.Value.Value == "no" &&
firstEntry.OptionValue.LocationRange.Start.Character == 16 &&
firstEntry.OptionValue.LocationRange.End.Character == 17) {
firstEntry.OptionValue.LocationRange.End.Character == 18) {
t.Errorf("Expected first entry to be PermitRootLogin no, but got: %v", firstEntry)
}
@ -48,13 +48,13 @@ PasswordAuthentication yes
secondEntry.LocationRange.Start.Line == 1 &&
secondEntry.LocationRange.End.Line == 1 &&
secondEntry.LocationRange.Start.Character == 0 &&
secondEntry.LocationRange.End.Character == 25 &&
secondEntry.LocationRange.End.Character == 26 &&
secondEntry.Key.Value.Value == "PasswordAuthentication" &&
secondEntry.Key.LocationRange.Start.Character == 0 &&
secondEntry.Key.LocationRange.End.Character == 21 &&
secondEntry.Key.LocationRange.End.Character == 22 &&
secondEntry.OptionValue.Value.Value == "yes" &&
secondEntry.OptionValue.LocationRange.Start.Character == 23 &&
secondEntry.OptionValue.LocationRange.End.Character == 25) {
secondEntry.OptionValue.LocationRange.End.Character == 26) {
t.Errorf("Expected second entry to be PasswordAuthentication yes, but got: %v", secondEntry)
}
}
@ -92,7 +92,7 @@ Match Address 192.168.0.1
t.Errorf("Expected second entry to be 'Match Address 192.168.0.1', but got: %v", secondEntry.MatchEntry.Value)
}
if !(secondEntry.Start.Line == 2 && secondEntry.Start.Character == 0 && secondEntry.End.Line == 3 && secondEntry.End.Character == 26) {
if !(secondEntry.Start.Line == 2 && secondEntry.Start.Character == 0 && secondEntry.End.Line == 3 && secondEntry.End.Character == 27) {
t.Errorf("Expected second entry's location to be 2:0-3:25, but got: %v", secondEntry.LocationRange)
}
@ -240,14 +240,14 @@ Match Address 192.168.0.2
t.Errorf("Expected match option to be 'Match User lena', but got: %v, %v", matchOption, matchBlock)
}
if !(matchOption.Start.Line == 2 && matchOption.End.Line == 2 && matchOption.Start.Character == 0 && matchOption.End.Character == 14) {
if !(matchOption.Start.Line == 2 && matchOption.End.Line == 2 && matchOption.Start.Character == 0 && matchOption.End.Character == 15) {
t.Errorf("Expected match option to be at 2:0-14, but got: %v", matchOption.LocationRange)
}
if !(matchBlock.Start.Line == 2 &&
matchBlock.Start.Character == 0 &&
matchBlock.End.Line == 4 &&
matchBlock.End.Character == 20) {
matchBlock.End.Character == 21) {
t.Errorf("Expected match block to be at 2:0-4:20, but got: %v", matchBlock.LocationRange)
}
}

View File

@ -1,17 +1,20 @@
package matchparser
import "slices"
import (
"config-lsp/common"
"slices"
)
func (m Match) GetEntryByCursor(cursor uint32) *MatchEntry {
func (m Match) GetEntryByCursor(cursor common.CursorPosition) *MatchEntry {
index, found := slices.BinarySearchFunc(
m.Entries,
cursor,
func(current *MatchEntry, target uint32) int {
if target < current.Start.Character {
func(current *MatchEntry, target common.CursorPosition) int {
if current.Start.IsAfterCursorPosition(target) {
return 1
}
if target > current.End.Character {
if current.End.IsBeforeCursorPosition(target) {
return -1
}

View File

@ -25,15 +25,15 @@ func TestComplexExample(
t.Fatalf("Expected User, but got %v", match.Entries[0])
}
if !(match.Entries[0].Values.Values[0].Value.Value == "root" && match.Entries[0].Values.Values[0].Start.Character == 5+offset && match.Entries[0].Values.Values[0].End.Character == 8+offset && match.Entries[0].Start.Character == 0+offset && match.Entries[0].End.Character == 20+offset) {
if !(match.Entries[0].Values.Values[0].Value.Value == "root" && match.Entries[0].Values.Values[0].Start.Character == 5+offset && match.Entries[0].Values.Values[0].End.Character == 8+offset+1 && match.Entries[0].Start.Character == 0+offset && match.Entries[0].End.Character == 20+offset+1) {
t.Errorf("Expected root, but got %v", match.Entries[0].Values.Values[0])
}
if !(match.Entries[0].Values.Values[1].Value.Value == "admin" && match.Entries[0].Values.Values[1].Start.Character == 10+offset && match.Entries[0].Values.Values[1].End.Character == 14+offset) {
if !(match.Entries[0].Values.Values[1].Value.Value == "admin" && match.Entries[0].Values.Values[1].Start.Character == 10+offset && match.Entries[0].Values.Values[1].End.Character == 14+offset+1) {
t.Errorf("Expected admin, but got %v", match.Entries[0].Values.Values[1])
}
if !(match.Entries[0].Values.Values[2].Value.Value == "alice" && match.Entries[0].Values.Values[2].Start.Character == 16+offset && match.Entries[0].Values.Values[2].End.Character == 20+offset) {
if !(match.Entries[0].Values.Values[2].Value.Value == "alice" && match.Entries[0].Values.Values[2].Start.Character == 16+offset && match.Entries[0].Values.Values[2].End.Character == 20+offset+1) {
t.Errorf("Expected alice, but got %v", match.Entries[0].Values.Values[2])
}
@ -41,11 +41,11 @@ func TestComplexExample(
t.Errorf("Expected Address, but got %v", match.Entries[1])
}
if !(match.Entries[1].Values.Values[0].Value.Value == "*" && match.Entries[1].Values.Values[0].Start.Character == 30+offset && match.Entries[1].Values.Values[0].End.Character == 30+offset) {
if !(match.Entries[1].Values.Values[0].Value.Value == "*" && match.Entries[1].Values.Values[0].Start.Character == 30+offset && match.Entries[1].Values.Values[0].End.Character == 30+offset+1) {
t.Errorf("Expected *, but got %v", match.Entries[1].Values.Values[0])
}
if !(match.Entries[1].Values.Values[1].Value.Value == "!192.168.0.1" && match.Entries[1].Values.Values[1].Start.Character == 32+offset && match.Entries[1].Values.Values[1].End.Character == 43+offset) {
if !(match.Entries[1].Values.Values[1].Value.Value == "!192.168.0.1" && match.Entries[1].Values.Values[1].Start.Character == 32+offset && match.Entries[1].Values.Values[1].End.Character == 43+offset+1) {
t.Errorf("Expected !192.168.0.1, but got %v", match.Entries[1].Values.Values[1])
}
}
@ -103,7 +103,7 @@ func TestIncompleteBetweenEntriesExample(
t.Errorf("Expected 3 values, but got %v", len(match.Entries[0].Values.Values))
}
if !(match.Entries[0].Start.Character == 0 && match.Entries[0].End.Character == 20) {
if !(match.Entries[0].Start.Character == 0 && match.Entries[0].End.Character == 21) {
t.Errorf("Expected 0-20, but got %v", match.Entries[0])
}
}

View File

@ -71,7 +71,7 @@ func GetOptionCompletions(
d *sshdconfig.SSHDocument,
entry *ast.SSHDOption,
matchBlock *ast.SSHDMatchBlock,
cursor uint32,
cursor common.CursorPosition,
) ([]protocol.CompletionItem, error) {
option, found := fields.Options[entry.Key.Key]
@ -82,8 +82,8 @@ func GetOptionCompletions(
if entry.Key.Key == "Match" {
return getMatchCompletions(
d,
cursor,
matchBlock.MatchValue,
cursor-matchBlock.MatchEntry.Start.Character,
)
}
@ -92,8 +92,12 @@ func GetOptionCompletions(
}
line := entry.OptionValue.Value.Raw
// NEW: docvalues index
return option.FetchCompletions(
line,
common.CursorToCharacterIndex(cursor-entry.OptionValue.Start.Character),
common.DeprecatedImprovedCursorToIndex(
entry.OptionValue.Start.GetRelativeCursorPosition(cursor),
line,
),
), nil
}

View File

@ -1,6 +1,7 @@
package handlers
import (
"config-lsp/common"
sshdconfig "config-lsp/handlers/sshd_config"
"config-lsp/handlers/sshd_config/fields"
matchparser "config-lsp/handlers/sshd_config/fields/match-parser"
@ -10,8 +11,8 @@ import (
func getMatchCompletions(
d *sshdconfig.SSHDocument,
cursor common.CursorPosition,
match *matchparser.Match,
cursor uint32,
) ([]protocol.CompletionItem, error) {
if match == nil || len(match.Entries) == 0 {
completions := getMatchCriteriaCompletions()
@ -22,7 +23,7 @@ func getMatchCompletions(
entry := match.GetEntryByCursor(cursor)
if entry == nil || entry.Criteria.IsCursorBetween(cursor) {
if entry == nil || entry.Criteria.ContainsCursorPosition(cursor) {
return getMatchCriteriaCompletions(), nil
}
@ -75,7 +76,7 @@ func getMatchAllKeywordCompletion() protocol.CompletionItem {
func getMatchValueCompletions(
entry *matchparser.MatchEntry,
cursor uint32,
cursor common.CursorPosition,
) []protocol.CompletionItem {
value := entry.GetValueByCursor(entry.End.Character)
@ -84,7 +85,10 @@ func getMatchValueCompletions(
if value != nil {
line = value.Value.Raw
relativeCursor = cursor - value.Start.Character
relativeCursor = common.DeprecatedImprovedCursorToIndex(
value.Start.GetRelativeCursorPosition(cursor),
line,
)
} else {
line = ""
relativeCursor = 0

View File

@ -1,9 +1,9 @@
package handlers
import (
"config-lsp/common"
"config-lsp/handlers/sshd_config/indexes"
"config-lsp/utils"
"fmt"
"slices"
protocol "github.com/tliron/glsp/protocol_3_16"
@ -11,17 +11,17 @@ import (
func GetIncludeOptionLocation(
include *indexes.SSHDIndexIncludeLine,
cursor uint32,
index common.IndexPosition,
) []protocol.Location {
index, found := slices.BinarySearchFunc(
foundIndex, found := slices.BinarySearchFunc(
include.Values,
cursor,
func(current *indexes.SSHDIndexIncludeValue, target uint32) int {
if target < current.Start.Character {
index,
func(current *indexes.SSHDIndexIncludeValue, target common.IndexPosition) int {
if current.Start.IsAfterIndexPosition(target) {
return 1
}
if target > current.End.Character {
if current.End.IsBeforeIndexPosition(target) {
return -1
}
@ -33,8 +33,7 @@ func GetIncludeOptionLocation(
return nil
}
path := include.Values[index]
println("paths", fmt.Sprintf("%v", path.Paths))
path := include.Values[foundIndex]
return utils.Map(
path.Paths,

View File

@ -54,7 +54,7 @@ func formatSSHDMatchBlock(
)
edits = append(edits, protocol.TextEdit{
Range: matchBlock.ToLSPRange(),
NewText: template.Format(options, matchBlock.MatchEntry.Key.Key, formatMatchToString(matchBlock.MatchValue, options)),
NewText: template.Format(options, matchBlock.MatchEntry.Key.Key, formatMatchToString(matchBlock.MatchValue)),
})
it := matchBlock.Options.Iterator()
@ -69,12 +69,11 @@ func formatSSHDMatchBlock(
func formatMatchToString(
match *matchparser.Match,
options protocol.FormattingOptions,
) string {
entriesAsStrings := utils.Map(
match.Entries,
func(entry *matchparser.MatchEntry) string {
return formatMatchEntryToString(entry, options)
return formatMatchEntryToString(entry)
},
)
@ -83,18 +82,16 @@ func formatMatchToString(
func formatMatchEntryToString(
entry *matchparser.MatchEntry,
options protocol.FormattingOptions,
) string {
return fmt.Sprintf(
"%s %s",
string(entry.Criteria.Type),
formatMatchValuesToString(entry.Values, options),
formatMatchValuesToString(entry.Values),
)
}
func formatMatchValuesToString(
values *matchparser.MatchValues,
options protocol.FormattingOptions,
) string {
valuesAsStrings := utils.Map(
values.Values,

View File

@ -1,6 +1,7 @@
package handlers
import (
"config-lsp/common"
docvalues "config-lsp/doc-values"
"config-lsp/handlers/sshd_config/ast"
"config-lsp/handlers/sshd_config/fields"
@ -13,7 +14,7 @@ func GetHoverInfoForOption(
option *ast.SSHDOption,
matchBlock *ast.SSHDMatchBlock,
line uint32,
cursor uint32,
index common.IndexPosition,
) (*protocol.Hover, error) {
var docValue *docvalues.DocumentationValue
@ -28,7 +29,7 @@ func GetHoverInfoForOption(
}
}
if cursor >= option.Key.Start.Character && cursor <= option.Key.End.Character {
if option.Key.ContainsIndexPosition(index) {
if docValue != nil {
contents := []string{
"## " + option.Key.Key,
@ -52,9 +53,12 @@ func GetHoverInfoForOption(
}
}
if option.OptionValue != nil && cursor >= option.OptionValue.Start.Character && cursor <= option.OptionValue.End.Character {
relativeCursor := cursor - option.OptionValue.Start.Character
contents := docValue.FetchHoverInfo(option.OptionValue.Value.Raw, relativeCursor)
if option.OptionValue != nil && option.OptionValue.ContainsIndexPosition(index) {
line := option.OptionValue.Value.Raw
contents := docValue.FetchHoverInfo(
line,
uint32(option.OptionValue.Start.GetRelativeIndexPosition(index)),
)
return &protocol.Hover{
Contents: strings.Join(contents, "\n"),

View File

@ -63,7 +63,7 @@ func CreateIndexes(config ast.SSHDConfig) (*SSHDIndexes, []common.LSPError) {
},
End: common.Location{
Line: includeOption.Start.Line,
Character: uint32(endIndex) + offset - 1,
Character: uint32(endIndex) + offset,
},
},
Value: rawPath,

View File

@ -79,7 +79,7 @@ Include /etc/ssh/sshd_config.d/*.conf hello_world
indexes.Includes[1].Values[0].Start.Line == 1 &&
indexes.Includes[1].Values[0].End.Line == 1 &&
indexes.Includes[1].Values[0].Start.Character == 8 &&
indexes.Includes[1].Values[0].End.Character == 36) {
indexes.Includes[1].Values[0].End.Character == 37) {
t.Errorf("Expected '/etc/ssh/sshd_config.d/*.conf' on line 1, but got %v on line %v", indexes.Includes[1].Values[0].Value, indexes.Includes[1].Values[0].Start.Line)
}
@ -87,7 +87,7 @@ Include /etc/ssh/sshd_config.d/*.conf hello_world
indexes.Includes[1].Values[1].Start.Line == 1 &&
indexes.Includes[1].Values[1].End.Line == 1 &&
indexes.Includes[1].Values[1].Start.Character == 38 &&
indexes.Includes[1].Values[1].End.Character == 48) {
indexes.Includes[1].Values[1].End.Character == 49) {
t.Errorf("Expected 'hello_world' on line 1, but got %v on line %v", indexes.Includes[1].Values[1].Value, indexes.Includes[1].Values[1].Start.Line)
}
}

View File

@ -1,6 +1,7 @@
package lsp
import (
"config-lsp/common"
sshdconfig "config-lsp/handlers/sshd_config"
"config-lsp/handlers/sshd_config/handlers"
"regexp"
@ -13,7 +14,7 @@ var isEmptyPattern = regexp.MustCompile(`^\s*$`)
func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) {
line := params.Position.Line
cursor := params.Position.Character
cursor := common.LSPCharacterAsCursorPosition(params.Position.Character)
d := sshdconfig.DocumentParserMap[params.TextDocument.URI]
@ -26,7 +27,7 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa
if entry == nil ||
entry.Separator == nil ||
entry.Key == nil ||
cursor <= entry.Key.End.Character {
entry.Key.Start.IsAfterCursorPosition(cursor) {
return handlers.GetRootCompletions(
d,
@ -36,7 +37,7 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa
)
}
if entry.Separator != nil && cursor >= entry.Separator.End.Character {
if entry.Separator != nil && entry.Separator.End.IsBeforeCursorPosition(cursor) {
return handlers.GetOptionCompletions(
d,
entry,

View File

@ -1,6 +1,7 @@
package lsp
import (
"config-lsp/common"
sshdconfig "config-lsp/handlers/sshd_config"
"config-lsp/handlers/sshd_config/handlers"
@ -10,13 +11,14 @@ import (
func TextDocumentDefinition(context *glsp.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) {
d := sshdconfig.DocumentParserMap[params.TextDocument.URI]
cursor := params.Position.Character
index := common.LSPCharacterAsIndexPosition(params.Position.Character)
line := params.Position.Line
if include, found := d.Indexes.Includes[line]; found {
relativeCursor := cursor - include.Option.LocationRange.Start.Character
return handlers.GetIncludeOptionLocation(include, relativeCursor), nil
return handlers.GetIncludeOptionLocation(
include,
index,
), nil
}
return nil, nil

View File

@ -1,6 +1,7 @@
package lsp
import (
"config-lsp/common"
sshdconfig "config-lsp/handlers/sshd_config"
"config-lsp/handlers/sshd_config/handlers"
@ -13,7 +14,7 @@ func TextDocumentHover(
params *protocol.HoverParams,
) (*protocol.Hover, error) {
line := params.Position.Line
cursor := params.Position.Character
index := common.LSPCharacterAsIndexPosition(params.Position.Character)
d := sshdconfig.DocumentParserMap[params.TextDocument.URI]
@ -28,6 +29,6 @@ func TextDocumentHover(
option,
matchBlock,
line,
cursor,
index,
)
}