mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
feat: Improve root handler; Improve language detection; Bugfixes
This commit is contained in:
parent
0ed506f604
commit
67085d761e
@ -1,10 +1,21 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
type LSPError struct {
|
||||
Range LocationRange
|
||||
Err error
|
||||
}
|
||||
|
||||
func (l LSPError) ToDiagnostic() protocol.Diagnostic {
|
||||
return protocol.Diagnostic{
|
||||
Range: l.Range.ToLSPRange(),
|
||||
Message: l.Err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
type SyntaxError struct {
|
||||
Message string
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package common
|
||||
|
||||
import protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
|
||||
type Location struct {
|
||||
Line uint32
|
||||
Character uint32
|
||||
@ -10,11 +12,37 @@ type LocationRange struct {
|
||||
End Location
|
||||
}
|
||||
|
||||
func (l LocationRange) ToLSPRange() protocol.Range {
|
||||
return protocol.Range{
|
||||
Start: protocol.Position{
|
||||
Line: l.Start.Line,
|
||||
Character: l.Start.Character,
|
||||
},
|
||||
End: protocol.Position{
|
||||
Line: l.End.Line,
|
||||
Character: l.End.Character,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LocationRange) ChangeBothLines(newLine uint32) {
|
||||
l.Start.Line = newLine
|
||||
l.End.Line = newLine
|
||||
}
|
||||
|
||||
func CreateFullLineRange(line uint32) LocationRange {
|
||||
return LocationRange{
|
||||
Start: Location{
|
||||
Line: line,
|
||||
Character: 0,
|
||||
},
|
||||
End: Location{
|
||||
Line: line,
|
||||
Character: 999999,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func CreateSingleCharRange(line uint32, character uint32) LocationRange {
|
||||
return LocationRange{
|
||||
Start: Location{
|
||||
|
BIN
config-lsp
BIN
config-lsp
Binary file not shown.
@ -1 +1,32 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
"config-lsp/common"
|
||||
"config-lsp/handlers/hosts/tree"
|
||||
"config-lsp/utils"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func Analyze(parser tree.HostsParser) []protocol.Diagnostic {
|
||||
errors := analyzeEntriesAreValid(parser)
|
||||
|
||||
if len(errors) > 0 {
|
||||
return utils.Map(
|
||||
errors,
|
||||
func(err common.LSPError) protocol.Diagnostic {
|
||||
return err.ToDiagnostic()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
errors = append(errors, analyzeDoubleIPs(parser)...)
|
||||
errors = append(errors, analyzeDoubleHostNames(parser)...)
|
||||
|
||||
return utils.Map(
|
||||
errors,
|
||||
func(err common.LSPError) protocol.Diagnostic {
|
||||
return err.ToDiagnostic()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -52,11 +52,11 @@ func TestWorksWithDoubleIPs(
|
||||
t.Errorf("Expected 1 error, but got %v", len(errors))
|
||||
}
|
||||
|
||||
if !(errors[0].Range.Start.Line == 3) {
|
||||
if !(errors[0].Range.Start.Line == 2) {
|
||||
t.Errorf("Expected error on line 3, but got %v", errors[0].Range.Start.Line)
|
||||
}
|
||||
|
||||
if !(errors[0].Err.(DuplicateIPDeclaration).AlreadyFoundAt == 1) {
|
||||
if !(errors[0].Err.(DuplicateIPDeclaration).AlreadyFoundAt == 0) {
|
||||
t.Errorf("Expected error on line 1, but got %v", errors[0].Err.(DuplicateIPDeclaration).AlreadyFoundAt)
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ type hostnameEntry struct {
|
||||
HostName string
|
||||
}
|
||||
|
||||
func CreateResolverFromParser(p tree.HostsParser) (Resolver, []common.LSPError) {
|
||||
func createResolverFromParser(p tree.HostsParser) (Resolver, []common.LSPError) {
|
||||
errors := make([]common.LSPError, 0)
|
||||
resolver := Resolver{
|
||||
Entries: make(map[string]ResolverEntry),
|
||||
@ -91,3 +91,9 @@ func CreateResolverFromParser(p tree.HostsParser) (Resolver, []common.LSPError)
|
||||
|
||||
return resolver, errors
|
||||
}
|
||||
|
||||
func analyzeDoubleHostNames(p tree.HostsParser) []common.LSPError {
|
||||
_, errors := createResolverFromParser(p)
|
||||
|
||||
return errors
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func TestResolverEntriesWorksWithNonOverlapping(
|
||||
t.Fatalf("PARER FAILED! Expected no errors, but got %v", errors)
|
||||
}
|
||||
|
||||
resolver, errors := CreateResolverFromParser(parser)
|
||||
resolver, errors := createResolverFromParser(parser)
|
||||
|
||||
if len(errors) != 0 {
|
||||
t.Errorf("Expected no errors, but got %v", errors)
|
||||
@ -63,7 +63,7 @@ func TestResolverEntriesWithSimpleOverlapping(
|
||||
t.Fatalf("PARER FAILED! Expected no errors, but got %v", errors)
|
||||
}
|
||||
|
||||
resolver, errors := CreateResolverFromParser(parser)
|
||||
resolver, errors := createResolverFromParser(parser)
|
||||
|
||||
if !(len(errors) == 1) {
|
||||
t.Errorf("Expected 1 error, but got %v", len(errors))
|
||||
@ -93,7 +93,7 @@ func TestResolverEntriesWithComplexOverlapping(
|
||||
t.Fatalf("PARER FAILED! Expected no errors, but got %v", errors)
|
||||
}
|
||||
|
||||
resolver, errors := CreateResolverFromParser(parser)
|
||||
resolver, errors := createResolverFromParser(parser)
|
||||
|
||||
if !(len(errors) == 1) {
|
||||
t.Errorf("Expected 1 error, but got %v", len(errors))
|
||||
|
33
handlers/hosts/handlers/analyzer/values.go
Normal file
33
handlers/hosts/handlers/analyzer/values.go
Normal file
@ -0,0 +1,33 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
"config-lsp/common"
|
||||
"config-lsp/handlers/hosts/tree"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func analyzeEntriesAreValid(
|
||||
parser tree.HostsParser,
|
||||
) []common.LSPError {
|
||||
err := make([]common.LSPError, 0)
|
||||
|
||||
for lineNumber, entry := range parser.Tree.Entries {
|
||||
if entry.IPAddress == nil {
|
||||
err = append(err, common.LSPError{
|
||||
Range: common.CreateFullLineRange(lineNumber),
|
||||
Err: errors.New("IP Address is required"),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if entry.Hostname == nil {
|
||||
err = append(err, common.LSPError{
|
||||
Range: common.CreateFullLineRange(lineNumber),
|
||||
Err: errors.New("Hostname is required"),
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
9
handlers/hosts/lsp/shared.go
Normal file
9
handlers/hosts/lsp/shared.go
Normal file
@ -0,0 +1,9 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/hosts/tree"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
var documentParserMap = map[protocol.DocumentUri]*tree.HostsParser{}
|
12
handlers/hosts/lsp/text-document-completion.go
Normal file
12
handlers/hosts/lsp/text-document-completion.go
Normal file
@ -0,0 +1,12 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) {
|
||||
// p := documentParserMap[params.TextDocument.URI]
|
||||
|
||||
return nil, nil
|
||||
}
|
41
handlers/hosts/lsp/text-document-did-change.go
Normal file
41
handlers/hosts/lsp/text-document-did-change.go
Normal file
@ -0,0 +1,41 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/common"
|
||||
"config-lsp/handlers/hosts/handlers/analyzer"
|
||||
"config-lsp/utils"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentDidChange(
|
||||
context *glsp.Context,
|
||||
params *protocol.DidChangeTextDocumentParams,
|
||||
) error {
|
||||
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
|
||||
common.ClearDiagnostics(context, params.TextDocument.URI)
|
||||
|
||||
parser := documentParserMap[params.TextDocument.URI]
|
||||
parser.Clear()
|
||||
|
||||
diagnostics := make([]protocol.Diagnostic, 0)
|
||||
errors := parser.Parse(content)
|
||||
|
||||
if len(errors) > 0 {
|
||||
diagnostics = append(diagnostics, utils.Map(
|
||||
errors,
|
||||
func(err common.LSPError) protocol.Diagnostic {
|
||||
return err.ToDiagnostic()
|
||||
},
|
||||
)...)
|
||||
}
|
||||
|
||||
diagnostics = append(diagnostics, analyzer.Analyze(*parser)...)
|
||||
|
||||
if len(diagnostics) > 0 {
|
||||
common.SendDiagnostics(context, params.TextDocument.URI, diagnostics)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
12
handlers/hosts/lsp/text-document-did-close.go
Normal file
12
handlers/hosts/lsp/text-document-did-close.go
Normal file
@ -0,0 +1,12 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentDidClose(context *glsp.Context, params *protocol.DidCloseTextDocumentParams) error {
|
||||
delete(documentParserMap, params.TextDocument.URI)
|
||||
|
||||
return nil
|
||||
}
|
41
handlers/hosts/lsp/text-document-did-open.go
Normal file
41
handlers/hosts/lsp/text-document-did-open.go
Normal file
@ -0,0 +1,41 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/common"
|
||||
"config-lsp/handlers/hosts/handlers/analyzer"
|
||||
"config-lsp/handlers/hosts/tree"
|
||||
"config-lsp/utils"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentDidOpen(
|
||||
context *glsp.Context,
|
||||
params *protocol.DidOpenTextDocumentParams,
|
||||
) error {
|
||||
common.ClearDiagnostics(context, params.TextDocument.URI)
|
||||
|
||||
parser := tree.CreateNewHostsParser()
|
||||
documentParserMap[params.TextDocument.URI] = &parser
|
||||
|
||||
errors := parser.Parse(params.TextDocument.Text)
|
||||
|
||||
diagnostics := utils.Map(
|
||||
errors,
|
||||
func(err common.LSPError) protocol.Diagnostic {
|
||||
return err.ToDiagnostic()
|
||||
},
|
||||
)
|
||||
|
||||
diagnostics = append(
|
||||
diagnostics,
|
||||
analyzer.Analyze(parser)...,
|
||||
)
|
||||
|
||||
if len(diagnostics) > 0 {
|
||||
common.SendDiagnostics(context, params.TextDocument.URI, diagnostics)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -3,8 +3,8 @@ package tree
|
||||
import (
|
||||
"config-lsp/common"
|
||||
"config-lsp/handlers/hosts/parser"
|
||||
"config-lsp/utils"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/antlr4-go/antlr/v4"
|
||||
)
|
||||
@ -51,10 +51,10 @@ func (p *HostsParser) parseStatement(
|
||||
|
||||
func (p *HostsParser) Parse(input string) []common.LSPError {
|
||||
errors := make([]common.LSPError, 0)
|
||||
lines := strings.Split(input, "\n")
|
||||
lines := utils.SplitIntoLines(input)
|
||||
|
||||
for rawLineNumber, line := range lines {
|
||||
lineNumber := uint32(rawLineNumber + 1)
|
||||
lineNumber := uint32(rawLineNumber)
|
||||
|
||||
if commentPattern.MatchString(line) {
|
||||
p.CommentLines[lineNumber] = struct{}{}
|
||||
|
@ -24,44 +24,44 @@ func TestValidSimpleExampleWorks(
|
||||
t.Errorf("Expected 1 entry, but got %v", len(parser.Tree.Entries))
|
||||
}
|
||||
|
||||
if parser.Tree.Entries[1].IPAddress == nil {
|
||||
if parser.Tree.Entries[0].IPAddress == nil {
|
||||
t.Errorf("Expected IP address to be present, but got nil")
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].IPAddress.Value.String() == net.ParseIP("1.2.3.4").String()) {
|
||||
t.Errorf("Expected IP address to be 1.2.3.4, but got %v", parser.Tree.Entries[1].IPAddress.Value)
|
||||
if !(parser.Tree.Entries[0].IPAddress.Value.String() == net.ParseIP("1.2.3.4").String()) {
|
||||
t.Errorf("Expected IP address to be 1.2.3.4, but got %v", parser.Tree.Entries[0].IPAddress.Value)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Hostname.Value == "hello.com") {
|
||||
t.Errorf("Expected hostname to be hello.com, but got %v", parser.Tree.Entries[1].Hostname.Value)
|
||||
if !(parser.Tree.Entries[0].Hostname.Value == "hello.com") {
|
||||
t.Errorf("Expected hostname to be hello.com, but got %v", parser.Tree.Entries[0].Hostname.Value)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Aliases == nil) {
|
||||
t.Errorf("Expected no aliases, but got %v", parser.Tree.Entries[1].Aliases)
|
||||
if !(parser.Tree.Entries[0].Aliases == nil) {
|
||||
t.Errorf("Expected no aliases, but got %v", parser.Tree.Entries[0].Aliases)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Location.Start.Line == 1) {
|
||||
t.Errorf("Expected line to be 1, but got %v", parser.Tree.Entries[1].Location.Start.Line)
|
||||
if !(parser.Tree.Entries[0].Location.Start.Line == 0) {
|
||||
t.Errorf("Expected line to be 1, but got %v", parser.Tree.Entries[0].Location.Start.Line)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Location.Start.Character == 0) {
|
||||
t.Errorf("Expected start to be 0, but got %v", parser.Tree.Entries[1].Location.Start)
|
||||
if !(parser.Tree.Entries[0].Location.Start.Character == 0) {
|
||||
t.Errorf("Expected start to be 0, but got %v", parser.Tree.Entries[0].Location.Start)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Location.End.Character == 16) {
|
||||
t.Errorf("Expected end to be 16, but got %v", parser.Tree.Entries[1].Location.End.Character)
|
||||
if !(parser.Tree.Entries[0].Location.End.Character == 16) {
|
||||
t.Errorf("Expected end to be 16, but got %v", parser.Tree.Entries[0].Location.End.Character)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].IPAddress.Location.Start.Line == 1) {
|
||||
t.Errorf("Expected IP address line to be 1, but got %v", parser.Tree.Entries[1].IPAddress.Location.Start.Line)
|
||||
if !(parser.Tree.Entries[0].IPAddress.Location.Start.Line == 0) {
|
||||
t.Errorf("Expected IP address line to be 1, but got %v", parser.Tree.Entries[0].IPAddress.Location.Start.Line)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].IPAddress.Location.Start.Character == 0) {
|
||||
t.Errorf("Expected IP address start to be 0, but got %v", parser.Tree.Entries[1].IPAddress.Location.Start.Character)
|
||||
if !(parser.Tree.Entries[0].IPAddress.Location.Start.Character == 0) {
|
||||
t.Errorf("Expected IP address start to be 0, but got %v", parser.Tree.Entries[0].IPAddress.Location.Start.Character)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].IPAddress.Location.End.Character == 6) {
|
||||
t.Errorf("Expected IP address end to be 6, but got %v", parser.Tree.Entries[1].IPAddress.Location.End.Character)
|
||||
if !(parser.Tree.Entries[0].IPAddress.Location.End.Character == 6) {
|
||||
t.Errorf("Expected IP address end to be 6, but got %v", parser.Tree.Entries[0].IPAddress.Location.End.Character)
|
||||
}
|
||||
|
||||
if !(len(parser.CommentLines) == 0) {
|
||||
@ -91,11 +91,11 @@ func TestValidComplexExampleWorks(
|
||||
t.Errorf("Expected 3 entries, but got %v", len(parser.Tree.Entries))
|
||||
}
|
||||
|
||||
if parser.Tree.Entries[3].IPAddress == nil {
|
||||
if parser.Tree.Entries[2].IPAddress == nil {
|
||||
t.Errorf("Expected IP address to be present, but got nil")
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[3].IPAddress.Value.String() == net.ParseIP("1.2.3.4").String()) {
|
||||
if !(parser.Tree.Entries[2].IPAddress.Value.String() == net.ParseIP("1.2.3.4").String()) {
|
||||
t.Errorf("Expected IP address to be 1.2.3.4, but got %v", parser.Tree.Entries[2].IPAddress.Value)
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ func TestValidComplexExampleWorks(
|
||||
t.Errorf("Expected 1 comment line, but got %v", len(parser.CommentLines))
|
||||
}
|
||||
|
||||
if !(utils.KeyExists(parser.CommentLines, 2)) {
|
||||
if !(utils.KeyExists(parser.CommentLines, 1)) {
|
||||
t.Errorf("Expected comment line 2 to exist, but it does not")
|
||||
}
|
||||
}
|
||||
@ -130,15 +130,15 @@ func TestInvalidExampleWorks(
|
||||
t.Errorf("Expected no comment lines, but got %v", len(parser.CommentLines))
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].IPAddress.Value.String() == net.ParseIP("1.2.3.4").String()) {
|
||||
t.Errorf("Expected IP address to be nil, but got %v", parser.Tree.Entries[1].IPAddress)
|
||||
if !(parser.Tree.Entries[0].IPAddress.Value.String() == net.ParseIP("1.2.3.4").String()) {
|
||||
t.Errorf("Expected IP address to be nil, but got %v", parser.Tree.Entries[0].IPAddress)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Hostname == nil) {
|
||||
t.Errorf("Expected hostname to be nil, but got %v", parser.Tree.Entries[1].Hostname)
|
||||
if !(parser.Tree.Entries[0].Hostname == nil) {
|
||||
t.Errorf("Expected hostname to be nil, but got %v", parser.Tree.Entries[0].Hostname)
|
||||
}
|
||||
|
||||
if !(parser.Tree.Entries[1].Aliases == nil) {
|
||||
t.Errorf("Expected aliases to be nil, but got %v", parser.Tree.Entries[1].Aliases)
|
||||
if !(parser.Tree.Entries[0].Aliases == nil) {
|
||||
t.Errorf("Expected aliases to be nil, but got %v", parser.Tree.Entries[0].Aliases)
|
||||
}
|
||||
}
|
||||
|
@ -16,12 +16,14 @@ const (
|
||||
LanguageSSHDConfig SupportedLanguage = "sshd_config"
|
||||
LanguageFstab SupportedLanguage = "fstab"
|
||||
LanguageWireguard SupportedLanguage = "languagewireguard"
|
||||
LanguageHosts SupportedLanguage = "hosts"
|
||||
)
|
||||
|
||||
var AllSupportedLanguages = []string{
|
||||
string(LanguageSSHDConfig),
|
||||
string(LanguageFstab),
|
||||
string(LanguageWireguard),
|
||||
string(LanguageHosts),
|
||||
}
|
||||
|
||||
type FatalFileNotReadableError struct {
|
||||
@ -59,11 +61,19 @@ var valueToLanguageMap = map[string]SupportedLanguage{
|
||||
"wireguard": LanguageWireguard,
|
||||
"wg": LanguageWireguard,
|
||||
"languagewireguard": LanguageWireguard,
|
||||
"host": LanguageHosts,
|
||||
"hosts": LanguageHosts,
|
||||
"etc/hosts": LanguageHosts,
|
||||
}
|
||||
|
||||
var typeOverwriteRegex = regexp.MustCompile(`^#\?\s*lsp\.language\s*=\s*(\w+)\s*$`)
|
||||
var typeOverwriteRegex = regexp.MustCompile(`#\?\s*lsp\.language\s*=\s*(\w+)\s*`)
|
||||
var wireguardPattern = regexp.MustCompile(`/wg\d+\.conf$`)
|
||||
|
||||
var undetectableError = common.ParseError{
|
||||
Line: 0,
|
||||
Err: LanguageUndetectableError{},
|
||||
}
|
||||
|
||||
func DetectLanguage(
|
||||
content string,
|
||||
advertisedLanguage string,
|
||||
@ -99,14 +109,13 @@ func DetectLanguage(
|
||||
return LanguageSSHDConfig, nil
|
||||
case "file:///etc/fstab":
|
||||
return LanguageFstab, nil
|
||||
case "file:///etc/hosts":
|
||||
return LanguageHosts, nil
|
||||
}
|
||||
|
||||
if strings.HasPrefix(uri, "file:///etc/wireguard/") || wireguardPattern.MatchString(uri) {
|
||||
return LanguageWireguard, nil
|
||||
}
|
||||
|
||||
return "", common.ParseError{
|
||||
Line: 0,
|
||||
Err: LanguageUndetectableError{},
|
||||
}
|
||||
return "", undetectableError
|
||||
}
|
||||
|
@ -20,8 +20,14 @@ func (h *RootHandler) AddDocument(uri protocol.DocumentUri, language SupportedLa
|
||||
h.languageMap[uri] = language
|
||||
}
|
||||
|
||||
func (h *RootHandler) GetLanguageForDocument(uri protocol.DocumentUri) SupportedLanguage {
|
||||
return h.languageMap[uri]
|
||||
func (h *RootHandler) GetLanguageForDocument(uri protocol.DocumentUri) *SupportedLanguage {
|
||||
language, found := h.languageMap[uri]
|
||||
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &language
|
||||
}
|
||||
|
||||
func (h *RootHandler) RemoveDocument(uri protocol.DocumentUri) {
|
||||
|
@ -9,14 +9,26 @@ import (
|
||||
func TextDocumentCodeAction(context *glsp.Context, params *protocol.CodeActionParams) (any, error) {
|
||||
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
|
||||
|
||||
switch language {
|
||||
if language == nil {
|
||||
showParseError(
|
||||
context,
|
||||
params.TextDocument.URI,
|
||||
undetectableError,
|
||||
)
|
||||
|
||||
return nil, undetectableError.Err
|
||||
}
|
||||
|
||||
switch *language {
|
||||
case LanguageFstab:
|
||||
return nil, nil
|
||||
fallthrough
|
||||
case LanguageHosts:
|
||||
fallthrough
|
||||
case LanguageSSHDConfig:
|
||||
return nil, nil
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentCodeAction(context, params)
|
||||
}
|
||||
|
||||
panic("root-handler/TextDocumentCompletion: unexpected language" + language)
|
||||
panic("root-handler/TextDocumentCompletion: unexpected language" + *language)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package roothandler
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/fstab"
|
||||
hosts "config-lsp/handlers/hosts/lsp"
|
||||
wireguard "config-lsp/handlers/wireguard/lsp"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
@ -11,14 +12,26 @@ import (
|
||||
func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) {
|
||||
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
|
||||
|
||||
switch language {
|
||||
if language == nil {
|
||||
showParseError(
|
||||
context,
|
||||
params.TextDocument.URI,
|
||||
undetectableError,
|
||||
)
|
||||
|
||||
return nil, undetectableError.Err
|
||||
}
|
||||
|
||||
switch *language {
|
||||
case LanguageFstab:
|
||||
return fstab.TextDocumentCompletion(context, params)
|
||||
case LanguageSSHDConfig:
|
||||
return nil, nil
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentCompletion(context, params)
|
||||
case LanguageHosts:
|
||||
return hosts.TextDocumentCompletion(context, params)
|
||||
}
|
||||
|
||||
panic("root-handler/TextDocumentCompletion: unexpected language" + language)
|
||||
panic("root-handler/TextDocumentCompletion: unexpected language" + *language)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package roothandler
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/fstab"
|
||||
hosts "config-lsp/handlers/hosts/lsp"
|
||||
wireguard "config-lsp/handlers/wireguard/lsp"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
@ -11,14 +12,52 @@ import (
|
||||
func TextDocumentDidChange(context *glsp.Context, params *protocol.DidChangeTextDocumentParams) error {
|
||||
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
|
||||
|
||||
switch language {
|
||||
if language == nil {
|
||||
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
|
||||
newLanguage, err := initFile(
|
||||
context,
|
||||
content,
|
||||
params.TextDocument.URI,
|
||||
"",
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
language = newLanguage
|
||||
|
||||
params := &protocol.DidOpenTextDocumentParams{
|
||||
TextDocument: protocol.TextDocumentItem{
|
||||
URI: params.TextDocument.URI,
|
||||
Text: content,
|
||||
Version: params.TextDocument.Version,
|
||||
LanguageID: string(*language),
|
||||
},
|
||||
}
|
||||
|
||||
switch *language {
|
||||
case LanguageFstab:
|
||||
return fstab.TextDocumentDidOpen(context, params)
|
||||
case LanguageSSHDConfig:
|
||||
break
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentDidOpen(context, params)
|
||||
case LanguageHosts:
|
||||
return hosts.TextDocumentDidOpen(context, params)
|
||||
}
|
||||
}
|
||||
|
||||
switch *language {
|
||||
case LanguageFstab:
|
||||
return fstab.TextDocumentDidChange(context, params)
|
||||
case LanguageSSHDConfig:
|
||||
return nil
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentDidChange(context, params)
|
||||
case LanguageHosts:
|
||||
return hosts.TextDocumentDidChange(context, params)
|
||||
}
|
||||
|
||||
panic("root-handler/TextDocumentDidChange: unexpected language" + language)
|
||||
panic("root-handler/TextDocumentDidChange: unexpected language" + *language)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package roothandler
|
||||
|
||||
import (
|
||||
hosts "config-lsp/handlers/hosts/lsp"
|
||||
wireguard "config-lsp/handlers/wireguard/lsp"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
@ -10,14 +11,26 @@ import (
|
||||
func TextDocumentDidClose(context *glsp.Context, params *protocol.DidCloseTextDocumentParams) error {
|
||||
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
|
||||
|
||||
if language == nil {
|
||||
showParseError(
|
||||
context,
|
||||
params.TextDocument.URI,
|
||||
undetectableError,
|
||||
)
|
||||
|
||||
return undetectableError.Err
|
||||
}
|
||||
|
||||
delete(openedFiles, params.TextDocument.URI)
|
||||
rootHandler.RemoveDocument(params.TextDocument.URI)
|
||||
|
||||
switch language {
|
||||
switch *language {
|
||||
case LanguageFstab:
|
||||
case LanguageSSHDConfig:
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentDidClose(context, params)
|
||||
case LanguageHosts:
|
||||
return hosts.TextDocumentDidClose(context, params)
|
||||
default:
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package roothandler
|
||||
import (
|
||||
"config-lsp/common"
|
||||
fstab "config-lsp/handlers/fstab"
|
||||
hosts "config-lsp/handlers/hosts/lsp"
|
||||
wireguard "config-lsp/handlers/wireguard/lsp"
|
||||
"fmt"
|
||||
|
||||
@ -15,31 +16,26 @@ func TextDocumentDidOpen(context *glsp.Context, params *protocol.DidOpenTextDocu
|
||||
|
||||
// Find the file type
|
||||
content := params.TextDocument.Text
|
||||
language, err := DetectLanguage(content, params.TextDocument.LanguageID, params.TextDocument.URI)
|
||||
|
||||
if err != nil {
|
||||
parseError := err.(common.ParseError)
|
||||
showParseError(
|
||||
language, err := initFile(
|
||||
context,
|
||||
content,
|
||||
params.TextDocument.URI,
|
||||
parseError,
|
||||
params.TextDocument.LanguageID,
|
||||
)
|
||||
|
||||
return parseError.Err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
openedFiles[params.TextDocument.URI] = struct{}{}
|
||||
|
||||
// Everything okay, now we can handle the file
|
||||
rootHandler.AddDocument(params.TextDocument.URI, language)
|
||||
|
||||
switch language {
|
||||
switch *language {
|
||||
case LanguageFstab:
|
||||
return fstab.TextDocumentDidOpen(context, params)
|
||||
case LanguageSSHDConfig:
|
||||
break
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentDidOpen(context, params)
|
||||
case LanguageHosts:
|
||||
return hosts.TextDocumentDidOpen(context, params)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unexpected roothandler.SupportedLanguage: %#v", language))
|
||||
@ -73,3 +69,30 @@ func showParseError(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func initFile(
|
||||
context *glsp.Context,
|
||||
content string,
|
||||
uri protocol.DocumentUri,
|
||||
advertisedLanguage string,
|
||||
) (*SupportedLanguage, error) {
|
||||
language, err := DetectLanguage(content, advertisedLanguage, uri)
|
||||
|
||||
if err != nil {
|
||||
parseError := err.(common.ParseError)
|
||||
showParseError(
|
||||
context,
|
||||
uri,
|
||||
parseError,
|
||||
)
|
||||
|
||||
return nil, parseError.Err
|
||||
}
|
||||
|
||||
openedFiles[uri] = struct{}{}
|
||||
|
||||
// Everything okay, now we can handle the file
|
||||
rootHandler.AddDocument(uri, language)
|
||||
|
||||
return &language, nil
|
||||
}
|
||||
|
@ -11,14 +11,26 @@ import (
|
||||
func TextDocumentHover(context *glsp.Context, params *protocol.HoverParams) (*protocol.Hover, error) {
|
||||
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
|
||||
|
||||
switch language {
|
||||
case LanguageFstab:
|
||||
return fstab.TextDocumentHover(context, params)
|
||||
if language == nil {
|
||||
showParseError(
|
||||
context,
|
||||
params.TextDocument.URI,
|
||||
undetectableError,
|
||||
)
|
||||
|
||||
return nil, undetectableError.Err
|
||||
}
|
||||
|
||||
switch *language {
|
||||
case LanguageHosts:
|
||||
fallthrough
|
||||
case LanguageSSHDConfig:
|
||||
return nil, nil
|
||||
case LanguageFstab:
|
||||
return fstab.TextDocumentHover(context, params)
|
||||
case LanguageWireguard:
|
||||
return wireguard.TextDocumentHover(context, params)
|
||||
}
|
||||
|
||||
panic("root-handler/TextDocumentHover: unexpected language" + language)
|
||||
panic("root-handler/TextDocumentHover: unexpected language" + *language)
|
||||
}
|
||||
|
@ -15,3 +15,7 @@ func GetTrimIndex(s string) []int {
|
||||
|
||||
return indexes[2:4]
|
||||
}
|
||||
|
||||
func SplitIntoLines(s string) []string {
|
||||
return regexp.MustCompile("\r?\n").Split(s, -1)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user