mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
feat: Add simple diagnostics; Improvements
This commit is contained in:
parent
da4577ac22
commit
184cf63411
35
common/errors.go
Normal file
35
common/errors.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ParserError interface {}
|
||||||
|
|
||||||
|
type OptionAlreadyExistsError struct {
|
||||||
|
Option string
|
||||||
|
FoundOnLine uint32
|
||||||
|
}
|
||||||
|
func (e OptionAlreadyExistsError) Error() string {
|
||||||
|
return fmt.Sprintf("Option %s already exists", e.Option)
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionUnknownError struct {
|
||||||
|
Option string
|
||||||
|
}
|
||||||
|
func (e OptionUnknownError) Error() string {
|
||||||
|
return fmt.Sprintf("Option '%s' does not exist", e.Option)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MalformedLineError struct {
|
||||||
|
Line string
|
||||||
|
}
|
||||||
|
func (e MalformedLineError) Error() string {
|
||||||
|
return fmt.Sprintf("Malformed line: %s", e.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
type LineNotFoundError struct {}
|
||||||
|
func (e LineNotFoundError) Error() string {
|
||||||
|
return "Line not found"
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -34,29 +33,6 @@ type SimpleConfigParser struct {
|
|||||||
Options SimpleConfigOptions
|
Options SimpleConfigOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionAlreadyExistsError struct {
|
|
||||||
Option string
|
|
||||||
}
|
|
||||||
func (e OptionAlreadyExistsError) Error() string {
|
|
||||||
return fmt.Sprintf("Option %s already exists", e.Option)
|
|
||||||
}
|
|
||||||
type OptionUnknownError struct {
|
|
||||||
Option string
|
|
||||||
}
|
|
||||||
func (e OptionUnknownError) Error() string {
|
|
||||||
return fmt.Sprintf("Option '%s' does not exist", e.Option)
|
|
||||||
}
|
|
||||||
type MalformedLineError struct {
|
|
||||||
Line string
|
|
||||||
}
|
|
||||||
func (e MalformedLineError) Error() string {
|
|
||||||
return fmt.Sprintf("Malformed line: %s", e.Line)
|
|
||||||
}
|
|
||||||
type LineNotFoundError struct {}
|
|
||||||
func (e LineNotFoundError) Error() string {
|
|
||||||
return "Line not found"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *SimpleConfigParser) AddLine(line string, lineNumber int) error {
|
func (p *SimpleConfigParser) AddLine(line string, lineNumber int) error {
|
||||||
parts := strings.SplitN(line, p.Options.Separator, 2)
|
parts := strings.SplitN(line, p.Options.Separator, 2)
|
||||||
|
|
||||||
@ -83,6 +59,7 @@ func (p *SimpleConfigParser) AddLine(line string, lineNumber int) error {
|
|||||||
if _, exists := p.Lines[option]; exists {
|
if _, exists := p.Lines[option]; exists {
|
||||||
return OptionAlreadyExistsError{
|
return OptionAlreadyExistsError{
|
||||||
Option: option,
|
Option: option,
|
||||||
|
FoundOnLine: uint32(lineNumber),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +95,22 @@ func (p *SimpleConfigParser) UpsertOption(option string, value string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *SimpleConfigParser) GetOption(option string) (SimpleConfigLine, error) {
|
||||||
|
if _, exists := p.Lines[option]; exists {
|
||||||
|
return p.Lines[option], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return SimpleConfigLine{
|
||||||
|
Value: "",
|
||||||
|
Position: SimpleConfigPosition{
|
||||||
|
Line: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OptionUnknownError{
|
||||||
|
Option: option,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *SimpleConfigParser) ParseFromFile(content string) []error {
|
func (p *SimpleConfigParser) ParseFromFile(content string) []error {
|
||||||
lines := strings.Split(content, "\n")
|
lines := strings.Split(content, "\n")
|
||||||
errors := make([]error, 0)
|
errors := make([]error, 0)
|
||||||
@ -142,7 +135,7 @@ func (p *SimpleConfigParser) Clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use better approach: Store an extra array of lines in order; with references to the SimpleConfigLine
|
// TODO: Use better approach: Store an extra array of lines in order; with references to the SimpleConfigLine
|
||||||
func (p SimpleConfigParser) FindByLineNumber(lineNumber int) (string, SimpleConfigLine, error) {
|
func (p *SimpleConfigParser) FindByLineNumber(lineNumber int) (string, SimpleConfigLine, error) {
|
||||||
for option, line := range p.Lines {
|
for option, line := range p.Lines {
|
||||||
if line.Position.Line == lineNumber {
|
if line.Position.Line == lineNumber {
|
||||||
return option, line, nil
|
return option, line, nil
|
||||||
|
56
handlers/openssh/diagnostics.go
Normal file
56
handlers/openssh/diagnostics.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
"fmt"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/tliron/glsp"
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ClearDiagnostics(context *glsp.Context, uri protocol.DocumentUri) {
|
||||||
|
context.Notify(
|
||||||
|
"textDocument/publishDiagnostics",
|
||||||
|
protocol.PublishDiagnosticsParams{
|
||||||
|
URI: uri,
|
||||||
|
Diagnostics: []protocol.Diagnostic{},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendDiagnosticsFromParserErrors(context *glsp.Context, uri protocol.DocumentUri, parserErrors []error) {
|
||||||
|
diagnosticErrors := make([]protocol.Diagnostic, 0)
|
||||||
|
|
||||||
|
for _, parserError := range parserErrors {
|
||||||
|
switch parserError.(type) {
|
||||||
|
case common.OptionAlreadyExistsError: {
|
||||||
|
err := parserError.(common.OptionAlreadyExistsError)
|
||||||
|
existingOption, _ := Parser.GetOption(err.Option)
|
||||||
|
|
||||||
|
diagnosticErrors = append(diagnosticErrors, protocol.Diagnostic{
|
||||||
|
Range: protocol.Range{
|
||||||
|
Start: protocol.Position{
|
||||||
|
Line: err.FoundOnLine,
|
||||||
|
Character: 0,
|
||||||
|
},
|
||||||
|
End: protocol.Position{
|
||||||
|
Line: err.FoundOnLine,
|
||||||
|
Character: uint32(utf8.RuneCountInString(err.Option)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Message: fmt.Sprintf("Option '%s' has already been declared on line %v", err.Option, existingOption.Position.Line + 1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Notify(
|
||||||
|
"textDocument/publishDiagnostics",
|
||||||
|
protocol.PublishDiagnosticsParams{
|
||||||
|
URI: uri,
|
||||||
|
Diagnostics: diagnosticErrors,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -7,10 +7,17 @@ import (
|
|||||||
|
|
||||||
// Todo: Implement incremental parsing
|
// Todo: Implement incremental parsing
|
||||||
func TextDocumentDidChange(context *glsp.Context, params *protocol.DidChangeTextDocumentParams) error {
|
func TextDocumentDidChange(context *glsp.Context, params *protocol.DidChangeTextDocumentParams) error {
|
||||||
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
|
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
|
||||||
|
|
||||||
Parser.Clear()
|
Parser.Clear()
|
||||||
Parser.ParseFromFile(content)
|
errors := Parser.ParseFromFile(content)
|
||||||
|
|
||||||
return nil
|
if len(errors) > 0 {
|
||||||
|
SendDiagnosticsFromParserErrors(context, params.TextDocument.URI, errors)
|
||||||
|
} else {
|
||||||
|
ClearDiagnostics(context, params.TextDocument.URI)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ func TextDocumentDidOpen(context *glsp.Context, params *protocol.DidOpenTextDocu
|
|||||||
errors := Parser.ParseFromFile(string(readBytes))
|
errors := Parser.ParseFromFile(string(readBytes))
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return errors[0]
|
SendDiagnosticsFromParserErrors(context, params.TextDocument.URI, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user