mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-19 07:25:27 +02:00
fix(fstab): Improve handler
This commit is contained in:
parent
433cd9ee4c
commit
f6eb74f638
@ -17,33 +17,14 @@ var SpecField = docvalues.OrValue{
|
||||
// docvalues.PathValue{
|
||||
// RequiredType: docvalues.PathTypeFile & docvalues.PathTypeExistenceOptional,
|
||||
// },
|
||||
docvalues.KeyValueAssignmentValue{
|
||||
docvalues.KeyEnumAssignmentValue{
|
||||
Separator: "=",
|
||||
ValueIsOptional: false,
|
||||
Key: docvalues.EnumValue{
|
||||
EnforceValues: true,
|
||||
Values: []docvalues.EnumString{
|
||||
docvalues.CreateEnumString("UUID"),
|
||||
docvalues.CreateEnumString("LABEL"),
|
||||
docvalues.CreateEnumString("PARTUUID"),
|
||||
docvalues.CreateEnumString("PARTLABEL"),
|
||||
},
|
||||
},
|
||||
Value: docvalues.CustomValue{
|
||||
FetchValue: func(rawContext docvalues.CustomValueContext) docvalues.Value {
|
||||
context := rawContext.(docvalues.KeyValueAssignmentContext)
|
||||
|
||||
switch context.SelectedKey {
|
||||
case "UUID":
|
||||
case "PARTUUID":
|
||||
return UuidField
|
||||
case "LABEL":
|
||||
case "PARTLABEL":
|
||||
return LabelField
|
||||
}
|
||||
|
||||
return docvalues.StringValue{}
|
||||
},
|
||||
Values: map[docvalues.EnumString]docvalues.Value{
|
||||
docvalues.CreateEnumString("UUID"): UuidField,
|
||||
docvalues.CreateEnumString("PARTUUID"): UuidField,
|
||||
docvalues.CreateEnumString("LABEL"): LabelField,
|
||||
docvalues.CreateEnumString("PARTLABEL"): LabelField,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -44,6 +44,17 @@ func (f *Field) CreateRange(fieldLine uint32) protocol.Range {
|
||||
}
|
||||
}
|
||||
|
||||
type FstabField string
|
||||
|
||||
const (
|
||||
FstabFieldSpec FstabField = "spec"
|
||||
FstabFieldMountPoint FstabField = "mountpoint"
|
||||
FstabFieldFileSystemType FstabField = "filesystemtype"
|
||||
FstabFieldOptions FstabField = "options"
|
||||
FstabFieldFreq FstabField = "freq"
|
||||
FstabFieldPass FstabField = "pass"
|
||||
)
|
||||
|
||||
type FstabFields struct {
|
||||
Spec *Field
|
||||
MountPoint *Field
|
||||
@ -146,6 +157,30 @@ func (e *FstabEntry) CheckIsValid() []protocol.Diagnostic {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
func (e FstabEntry) GetFieldAtPosition(cursor uint32) FstabField {
|
||||
if e.Fields.Spec == nil || (cursor >= e.Fields.Spec.Start && cursor <= e.Fields.Spec.End) {
|
||||
return FstabFieldSpec
|
||||
}
|
||||
|
||||
if e.Fields.MountPoint == nil || (cursor >= e.Fields.MountPoint.Start && cursor <= e.Fields.MountPoint.End) {
|
||||
return FstabFieldMountPoint
|
||||
}
|
||||
|
||||
if e.Fields.FilesystemType == nil || (cursor >= e.Fields.FilesystemType.Start && cursor <= e.Fields.FilesystemType.End) {
|
||||
return FstabFieldFileSystemType
|
||||
}
|
||||
|
||||
if e.Fields.Options == nil || (cursor >= e.Fields.Options.Start && cursor <= e.Fields.Options.End) {
|
||||
return FstabFieldOptions
|
||||
}
|
||||
|
||||
if e.Fields.Freq == nil || (cursor >= e.Fields.Freq.Start && cursor <= e.Fields.Freq.End) {
|
||||
return FstabFieldFreq
|
||||
}
|
||||
|
||||
return FstabFieldPass
|
||||
}
|
||||
|
||||
type FstabParser struct {
|
||||
entries []FstabEntry
|
||||
}
|
||||
@ -157,83 +192,83 @@ func (p *FstabParser) AddLine(line string, lineNumber int) error {
|
||||
return MalformedLineError{}
|
||||
}
|
||||
|
||||
var spec Field
|
||||
var mountPoint Field
|
||||
var filesystemType Field
|
||||
var options Field
|
||||
var freq Field
|
||||
var pass Field
|
||||
var spec *Field
|
||||
var mountPoint *Field
|
||||
var filesystemType *Field
|
||||
var options *Field
|
||||
var freq *Field
|
||||
var pass *Field
|
||||
|
||||
switch len(fields) {
|
||||
case 6:
|
||||
value := fields[5]
|
||||
start := uint32(strings.Index(line, value))
|
||||
pass = Field{
|
||||
pass = &Field{
|
||||
Value: fields[5],
|
||||
Start: start,
|
||||
End: start + uint32(len(value)),
|
||||
End: start + uint32(len(value)) - 1,
|
||||
}
|
||||
fallthrough
|
||||
case 5:
|
||||
value := fields[4]
|
||||
start := uint32(strings.Index(line, value))
|
||||
|
||||
freq = Field{
|
||||
freq = &Field{
|
||||
Value: value,
|
||||
Start: start,
|
||||
End: start + uint32(len(value)),
|
||||
End: start + uint32(len(value)) - 1,
|
||||
}
|
||||
fallthrough
|
||||
case 4:
|
||||
value := fields[3]
|
||||
start := uint32(strings.Index(line, value))
|
||||
|
||||
options = Field{
|
||||
options = &Field{
|
||||
Value: value,
|
||||
Start: start,
|
||||
End: start + uint32(len(value)),
|
||||
End: start + uint32(len(value)) - 1,
|
||||
}
|
||||
fallthrough
|
||||
case 3:
|
||||
value := fields[2]
|
||||
start := uint32(strings.Index(line, value))
|
||||
|
||||
filesystemType = Field{
|
||||
filesystemType = &Field{
|
||||
Value: value,
|
||||
Start: start,
|
||||
End: start + uint32(len(value)),
|
||||
End: start + uint32(len(value)) - 1,
|
||||
}
|
||||
fallthrough
|
||||
case 2:
|
||||
value := fields[1]
|
||||
start := uint32(strings.Index(line, value))
|
||||
|
||||
mountPoint = Field{
|
||||
mountPoint = &Field{
|
||||
Value: value,
|
||||
Start: start,
|
||||
End: start + uint32(len(value)),
|
||||
End: start + uint32(len(value)) - 1,
|
||||
}
|
||||
fallthrough
|
||||
case 1:
|
||||
value := fields[0]
|
||||
start := uint32(strings.Index(line, value))
|
||||
|
||||
spec = Field{
|
||||
spec = &Field{
|
||||
Value: value,
|
||||
Start: start,
|
||||
End: start + uint32(len(value)),
|
||||
End: start + uint32(len(value)) - 1,
|
||||
}
|
||||
}
|
||||
|
||||
entry := FstabEntry{
|
||||
Line: uint32(lineNumber),
|
||||
Fields: FstabFields{
|
||||
Spec: &spec,
|
||||
MountPoint: &mountPoint,
|
||||
FilesystemType: &filesystemType,
|
||||
Options: &options,
|
||||
Freq: &freq,
|
||||
Pass: &pass,
|
||||
Spec: spec,
|
||||
MountPoint: mountPoint,
|
||||
FilesystemType: filesystemType,
|
||||
Options: options,
|
||||
Freq: freq,
|
||||
Pass: pass,
|
||||
},
|
||||
}
|
||||
p.entries = append(p.entries, entry)
|
||||
@ -263,7 +298,7 @@ func (p *FstabParser) ParseFromContent(content string) []common.ParseError {
|
||||
return errors
|
||||
}
|
||||
|
||||
func (p *FstabParser) GetEntry(line uint32) (FstabEntry, bool) {
|
||||
func (p *FstabParser) GetEntry(line uint32) (*FstabEntry, bool) {
|
||||
index, found := slices.BinarySearchFunc(p.entries, line, func(entry FstabEntry, line uint32) int {
|
||||
if entry.Line < line {
|
||||
return -1
|
||||
@ -277,10 +312,10 @@ func (p *FstabParser) GetEntry(line uint32) (FstabEntry, bool) {
|
||||
})
|
||||
|
||||
if !found {
|
||||
return FstabEntry{}, false
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return p.entries[index], true
|
||||
return &p.entries[index], true
|
||||
}
|
||||
|
||||
func (p *FstabParser) Clear() {
|
||||
|
102
handlers/fstab/text-document-completion.go
Normal file
102
handlers/fstab/text-document-completion.go
Normal file
@ -0,0 +1,102 @@
|
||||
package fstab
|
||||
|
||||
import (
|
||||
docvalues "config-lsp/doc-values"
|
||||
fstabdocumentation "config-lsp/handlers/fstab/documentation"
|
||||
"fmt"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) {
|
||||
parser := documentParserMap[params.TextDocument.URI]
|
||||
|
||||
entry, found := parser.GetEntry(params.Position.Line)
|
||||
|
||||
if !found {
|
||||
// Empty line, return spec completions
|
||||
return fstabdocumentation.SpecField.FetchCompletions(
|
||||
"",
|
||||
params.Position.Character,
|
||||
), nil
|
||||
}
|
||||
|
||||
cursor := params.Position.Character
|
||||
targetField := entry.GetFieldAtPosition(cursor - 1)
|
||||
|
||||
println("cursor at", cursor, "target field", targetField)
|
||||
|
||||
switch targetField {
|
||||
case FstabFieldSpec:
|
||||
value, cursor := GetFieldSafely(entry.Fields.Spec, cursor)
|
||||
|
||||
return fstabdocumentation.SpecField.FetchCompletions(
|
||||
value,
|
||||
cursor,
|
||||
), nil
|
||||
case FstabFieldMountPoint:
|
||||
value, cursor := GetFieldSafely(entry.Fields.MountPoint, cursor)
|
||||
|
||||
return fstabdocumentation.MountPointField.FetchCompletions(
|
||||
value,
|
||||
cursor,
|
||||
), nil
|
||||
case FstabFieldFileSystemType:
|
||||
println(fmt.Sprintf("file system type: %s", entry.Fields.FilesystemType))
|
||||
value, cursor := GetFieldSafely(entry.Fields.FilesystemType, cursor)
|
||||
println("CURSOR", cursor)
|
||||
|
||||
return fstabdocumentation.FileSystemTypeField.FetchCompletions(
|
||||
value,
|
||||
cursor,
|
||||
), nil
|
||||
case FstabFieldOptions:
|
||||
fileSystemType := entry.Fields.FilesystemType.Value
|
||||
|
||||
var optionsField docvalues.Value
|
||||
|
||||
if foundField, found := fstabdocumentation.MountOptionsMapField[fileSystemType]; found {
|
||||
optionsField = foundField
|
||||
} else {
|
||||
optionsField = fstabdocumentation.DefaultMountOptionsField
|
||||
}
|
||||
|
||||
value, cursor := GetFieldSafely(entry.Fields.Options, cursor)
|
||||
|
||||
return optionsField.FetchCompletions(
|
||||
value,
|
||||
cursor,
|
||||
), nil
|
||||
case FstabFieldFreq:
|
||||
value, cursor := GetFieldSafely(entry.Fields.Freq, cursor)
|
||||
|
||||
return fstabdocumentation.FreqField.FetchCompletions(
|
||||
value,
|
||||
cursor,
|
||||
), nil
|
||||
case FstabFieldPass:
|
||||
value, cursor := GetFieldSafely(entry.Fields.Pass, cursor)
|
||||
|
||||
return fstabdocumentation.PassField.FetchCompletions(
|
||||
value,
|
||||
cursor,
|
||||
), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Safely get value and new cursor position
|
||||
// If field is nil, return empty string and 0
|
||||
func GetFieldSafely(field *Field, character uint32) (string, uint32) {
|
||||
if field == nil {
|
||||
return "", 0
|
||||
}
|
||||
|
||||
if field.Value == "" {
|
||||
return "", 0
|
||||
}
|
||||
|
||||
return field.Value, character - field.Start
|
||||
}
|
@ -15,7 +15,6 @@ func TextDocumentDidOpen(
|
||||
common.ClearDiagnostics(context, params.TextDocument.URI)
|
||||
|
||||
parser := FstabParser{}
|
||||
|
||||
documentParserMap[params.TextDocument.URI] = &parser
|
||||
|
||||
errors := parser.ParseFromContent(params.TextDocument.Text)
|
||||
|
Loading…
x
Reference in New Issue
Block a user