fix(fstab): Improve handler

This commit is contained in:
Myzel394 2024-08-05 22:50:47 +02:00
parent 433cd9ee4c
commit f6eb74f638
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
4 changed files with 170 additions and 53 deletions

View File

@ -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,
},
},
},

View File

@ -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() {

View 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
}

View File

@ -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)