diff --git a/common-documentation/filesystems/mountoptions/adfs.go b/common-documentation/filesystems/mountoptions/adfs.go new file mode 100644 index 0000000..cccb4b2 --- /dev/null +++ b/common-documentation/filesystems/mountoptions/adfs.go @@ -0,0 +1,28 @@ +package commondocumentation + +import docvalues "config-lsp/doc-values" + +var AdfsDocumentationAssignable = map[docvalues.EnumString]docvalues.Value{ + docvalues.CreateEnumStringWithDoc( + "uid", + "Set the owner of the files in the filesystem (default: uid=0).", + ): docvalues.UIDValue{ + EnforceUsingExisting: true, + }, + docvalues.CreateEnumStringWithDoc( + "gid", + "Set the group of the files in the filesystem (default: gid=0).", + ): docvalues.GIDValue{ + EnforceUsingExisting: true, + }, + docvalues.CreateEnumStringWithDoc( + "ownmask", + "Set the permission mask for ADFS 'owner' permissions (default: 0700).", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "othmask", + "Set the permission mask for ADFS 'other' permissions (default: 0077).", + ): docvalues.StringValue{}, +} + +var AdfsDocumentationEnums = []docvalues.EnumString{} diff --git a/common-documentation/filesystems/mountoptions/affs.go b/common-documentation/filesystems/mountoptions/affs.go new file mode 100644 index 0000000..1a0f6e6 --- /dev/null +++ b/common-documentation/filesystems/mountoptions/affs.go @@ -0,0 +1,91 @@ +package commondocumentation + +import docvalues "config-lsp/doc-values" + +var prefixMaxLength = uint32(30) + +var AffsDocumentationAssignable = map[docvalues.EnumString]docvalues.Value{ + docvalues.CreateEnumStringWithDoc( + "uid", + "Set the owner and group of the root of the filesystem (default: uid=gid=0, but with option uid or gid without specified value, the UID and GID of the current process are taken).", + ): docvalues.UIDValue{ + EnforceUsingExisting: true, + }, + docvalues.CreateEnumStringWithDoc( + "gid", + "Set the owner and group of the root of the filesystem (default: uid=gid=0, but with option uid or gid without specified value, the UID and GID of the current process are taken).", + ): docvalues.GIDValue{ + EnforceUsingExisting: true, + }, + docvalues.CreateEnumStringWithDoc( + "setuid", + "Set the owner of all files.", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "setgid", + "Set the group of all files.", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "mode", + "Set the mode of all files to value & 0777 disregarding the original permissions. Add search permission to directories that have read permission. The value is given in octal.", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "prefix", + "Prefix used before volume name, when following a link.", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "volume", + "Prefix (of length at most 30) used before '/' when following a symbolic link.", + ): docvalues.StringValue{MaxLength: &prefixMaxLength}, + docvalues.CreateEnumStringWithDoc( + "reserved", + "(Default: 2.) Number of unused blocks at the start of the device.", + ): docvalues.NumberValue{Min: &zero}, + docvalues.CreateEnumStringWithDoc( + "root", + "Give explicitly the location of the root block.", + ): docvalues.NumberValue{Min: &zero}, + docvalues.CreateEnumStringWithDoc( + "bs", + "Give blocksize. Allowed values are 512, 1024, 2048, 4096.", + ): docvalues.EnumValue{ + EnforceValues: true, + Values: []docvalues.EnumString{ + docvalues.CreateEnumString("512"), + docvalues.CreateEnumString("1024"), + docvalues.CreateEnumString("2048"), + docvalues.CreateEnumString("4096"), + }, + }, + docvalues.CreateEnumStringWithDoc( + "grpquota", + "These options are accepted but ignored. (However, quota utilities may react to such strings in /etc/fstab.)", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "noquota", + "These options are accepted but ignored. (However, quota utilities may react to such strings in /etc/fstab.)", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "quota", + "These options are accepted but ignored. (However, quota utilities may react to such strings in /etc/fstab.)", + ): docvalues.StringValue{}, + docvalues.CreateEnumStringWithDoc( + "usrquota", + "These options are accepted but ignored. (However, quota utilities may react to such strings in /etc/fstab.)", + ): docvalues.StringValue{}, +} + +var AffsDocumentationEnums = []docvalues.EnumString{ + docvalues.CreateEnumStringWithDoc( + "protect", + "Do not allow any changes to the protection bits on the filesystem.", + ), + docvalues.CreateEnumStringWithDoc( + "usemp", + "Set UID and GID of the root of the filesystem to the UID and GID of the mount point upon the first sync or umount, and then clear this option. Strange...", + ), + docvalues.CreateEnumStringWithDoc( + "verbose", + "Print an informational message for each successful mount.", + ), +} diff --git a/common-documentation/filesystems/mountoptions/debugfs.go b/common-documentation/filesystems/mountoptions/debugfs.go new file mode 100644 index 0000000..c425e8f --- /dev/null +++ b/common-documentation/filesystems/mountoptions/debugfs.go @@ -0,0 +1,24 @@ +package commondocumentation + +import docvalues "config-lsp/doc-values" + +var DebugfsDocumentationAssignable = map[docvalues.EnumString]docvalues.Value{ + docvalues.CreateEnumStringWithDoc( + "uid", + "Set the owner of the mountpoint.", + ): docvalues.UIDValue{ + EnforceUsingExisting: true, + }, + docvalues.CreateEnumStringWithDoc( + "gid", + "Set the group of the mountpoint.", + ): docvalues.GIDValue{ + EnforceUsingExisting: true, + }, + docvalues.CreateEnumStringWithDoc( + "mode", + "Sets the mode of the mountpoint.", + ): docvalues.StringValue{}, +} + +var DebugfsDocumentationEnums = []docvalues.EnumString{} diff --git a/doc-values/extra-values.go b/doc-values/extra-values.go index 4b224f2..3a47e9c 100644 --- a/doc-values/extra-values.go +++ b/doc-values/extra-values.go @@ -159,6 +159,12 @@ func PositiveNumberValue() Value { } } +func MaskValue() Value { + min := 0 + max := 777 + return NumberValue{Min: &min, Max: &max} +} + func SingleEnumValue(value string) EnumValue { return EnumValue{ EnforceValues: true, diff --git a/doc-values/utils.go b/doc-values/utils.go index 772e215..68e7326 100644 --- a/doc-values/utils.go +++ b/doc-values/utils.go @@ -29,7 +29,7 @@ func MergeKeyEnumAssignmentMaps(maps ...map[EnumString]Value) map[EnumString]Val for _, m := range maps { for key, value := range m { - if _, ok := existingEnums[key.InsertText]; !ok { + if _, ok := existingEnums[key.InsertText]; ok { continue } diff --git a/doc-values/value-array.go b/doc-values/value-array.go index 23fc486..94a59ff 100644 --- a/doc-values/value-array.go +++ b/doc-values/value-array.go @@ -122,8 +122,8 @@ func (v ArrayValue) FetchCompletions(line string, cursor uint32) []protocol.Comp relativePosition, found := utils.FindPreviousCharacter(line, v.Separator, int(cursor-1)) if found { - line = line[uint32(relativePosition):] - cursor -= uint32(relativePosition) + line = line[uint32(relativePosition+1):] + cursor -= uint32(relativePosition + 1) } return v.SubValue.FetchCompletions(line, cursor) diff --git a/doc-values/value-enum.go b/doc-values/value-enum.go index b180bf9..8e5cd98 100644 --- a/doc-values/value-enum.go +++ b/doc-values/value-enum.go @@ -30,6 +30,17 @@ type EnumString struct { Documentation string } +func (v EnumString) ToCompletionItem() protocol.CompletionItem { + textFormat := protocol.InsertTextFormatPlainText + kind := protocol.CompletionItemKindEnum + return protocol.CompletionItem{ + Label: v.InsertText, + InsertTextFormat: &textFormat, + Kind: &kind, + Documentation: &v.Documentation, + } +} + func CreateEnumString(value string) EnumString { return EnumString{ InsertText: value, diff --git a/doc-values/value-gid.go b/doc-values/value-gid.go new file mode 100644 index 0000000..5fca78c --- /dev/null +++ b/doc-values/value-gid.go @@ -0,0 +1,128 @@ +package docvalues + +import ( + "config-lsp/utils" + "strconv" + + protocol "github.com/tliron/glsp/protocol_3_16" +) + +type GIDNotInPasswdErr struct{} + +func (e GIDNotInPasswdErr) Error() string { + return "This UID does not exist" +} + +type InvalidGIDError struct{} + +func (e InvalidGIDError) Error() string { + return "This UID is invalid" +} + +type GIDNotInRangeError struct{} + +func (e GIDNotInRangeError) Error() string { + return "UIDs must be between 0 and 65535" +} + +type GIDValue struct { + EnforceUsingExisting bool +} + +func (v GIDValue) GetTypeDescription() []string { + return []string{"Group ID"} +} + +func (v GIDValue) CheckIsValid(value string) []*InvalidValue { + uid, err := strconv.Atoi(value) + + if err != nil { + return []*InvalidValue{{ + Err: InvalidGIDError{}, + Start: 0, + End: uint32(len(value)), + }} + } + + if uid < 0 || uid > 65535 { + return []*InvalidValue{{ + Err: GIDNotInRangeError{}, + Start: 0, + End: uint32(len(value)), + }} + } + + if v.EnforceUsingExisting { + infos, err := fetchPasswdInfo() + + if err != nil { + return []*InvalidValue{} + } + + found := false + + for _, info := range infos { + if info.GID == value { + found = true + break + } + } + + if !found { + return []*InvalidValue{{ + Err: GIDNotInPasswdErr{}, + Start: 0, + End: uint32(len(value)), + }} + } + } + + return []*InvalidValue{} +} + +var defaultGIDsExplanation = []EnumString{ + { + InsertText: "0", + DescriptionText: "root", + Documentation: "The group of the root user", + }, +} + +func (v GIDValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem { + infos, err := fetchGroupInfo() + + if err != nil { + return utils.Map(defaultUIDsExplanation, func(enum EnumString) protocol.CompletionItem { + return enum.ToCompletionItem() + }) + } + + textFormat := protocol.InsertTextFormatPlainText + kind := protocol.CompletionItemKindValue + completions := make([]protocol.CompletionItem, len(infos)) + + for index, info := range infos { + // Find default gids + var existingGID *EnumString + + for _, defaultGID := range defaultUIDsExplanation { + if defaultGID.InsertText == info.GID { + existingGID = &defaultGID + break + } + } + + if existingGID != nil { + completions[index] = existingGID.ToCompletionItem() + } else { + completions[index] = protocol.CompletionItem{ + InsertTextFormat: &textFormat, + Kind: &kind, + InsertText: &info.GID, + Documentation: info.Name, + } + } + } + + return completions +} diff --git a/doc-values/value-key-enum-assignment.go b/doc-values/value-key-enum-assignment.go index 226583d..3f69a13 100644 --- a/doc-values/value-key-enum-assignment.go +++ b/doc-values/value-key-enum-assignment.go @@ -111,13 +111,23 @@ func (v KeyEnumAssignmentValue) FetchEnumCompletions() []protocol.CompletionItem for enumKey := range v.Values { textFormat := protocol.InsertTextFormatPlainText - kind := protocol.CompletionItemKindEnum + kind := protocol.CompletionItemKindField + val := v.Values[enumKey] + description := val.GetTypeDescription() + + var documentation string + + if len(description) == 1 { + documentation = fmt.Sprintf("%s%s<%s> \n\n%s", enumKey.InsertText, v.Separator, description[0], enumKey.Documentation) + } else { + documentation = fmt.Sprintf("%s%s \n\n%s", enumKey.InsertText, v.Separator, enumKey.Documentation) + } completions = append(completions, protocol.CompletionItem{ Label: enumKey.InsertText, InsertTextFormat: &textFormat, Kind: &kind, - Documentation: &enumKey.Documentation, + Documentation: documentation, }) } diff --git a/doc-values/value-or.go b/doc-values/value-or.go index 296d7eb..0e9a6e5 100644 --- a/doc-values/value-or.go +++ b/doc-values/value-or.go @@ -1,6 +1,7 @@ package docvalues import ( + "config-lsp/utils" "strings" protocol "github.com/tliron/glsp/protocol_3_16" @@ -49,6 +50,26 @@ func (v OrValue) CheckIsValid(value string) []*InvalidValue { return errors } func (v OrValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem { + // Check for special cases + if len(v.Values) == 2 { + switch v.Values[0].(type) { + case KeyEnumAssignmentValue: + if cursor > 0 { + // KeyEnumAssignment + other values + // If there is an separator, we only want to show + // the values of the KeyEnumAssignment + keyEnumValue := v.Values[0].(KeyEnumAssignmentValue) + + println("line eta cursor", line, cursor) + _, found := utils.FindPreviousCharacter(line, keyEnumValue.Separator, int(cursor-1)) + + if found { + return keyEnumValue.FetchCompletions(line, cursor) + } + } + } + } + completions := make([]protocol.CompletionItem, 0) for _, subValue := range v.Values { diff --git a/doc-values/value-power-of-two.go b/doc-values/value-power-of-two.go index 8cf1d12..75bba30 100644 --- a/doc-values/value-power-of-two.go +++ b/doc-values/value-power-of-two.go @@ -62,7 +62,7 @@ var powers = []int{1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 func (v PowerOfTwoValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem { textFormat := protocol.InsertTextFormatPlainText - kind := protocol.CompletionItemKindEnum + kind := protocol.CompletionItemKindValue return utils.Map( powers, diff --git a/doc-values/value-regex.go b/doc-values/value-regex.go index 2d5fbfc..2be9481 100644 --- a/doc-values/value-regex.go +++ b/doc-values/value-regex.go @@ -26,16 +26,15 @@ func (v RegexValue) GetTypeDescription() []string { } func (v RegexValue) CheckIsValid(value string) []*InvalidValue { - if value == "" { + if !v.Regex.MatchString(value) { return []*InvalidValue{{ - Err: EmptyStringError{}, + Err: RegexInvalidError{Regex: v.Regex.String()}, Start: 0, End: uint32(len(value)), - }, - } + }} } - return nil + return []*InvalidValue{} } func (v RegexValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem { diff --git a/doc-values/value-string.go b/doc-values/value-string.go index f5f8b7c..67b163e 100644 --- a/doc-values/value-string.go +++ b/doc-values/value-string.go @@ -10,7 +10,15 @@ func (e EmptyStringError) Error() string { return "This setting may not be empty" } -type StringValue struct{} +type StringTooLongError struct{} + +func (e StringTooLongError) Error() string { + return "This setting is too long" +} + +type StringValue struct { + MaxLength *uint32 +} func (v StringValue) GetTypeDescription() []string { return []string{"String"} @@ -26,6 +34,14 @@ func (v StringValue) CheckIsValid(value string) []*InvalidValue { } } + if v.MaxLength != nil && uint32(len(value)) > *v.MaxLength { + return []*InvalidValue{{ + Err: StringTooLongError{}, + Start: 0, + End: uint32(len(value)), + }} + } + return nil } diff --git a/doc-values/value-uid.go b/doc-values/value-uid.go new file mode 100644 index 0000000..bfc436e --- /dev/null +++ b/doc-values/value-uid.go @@ -0,0 +1,129 @@ +package docvalues + +import ( + "config-lsp/utils" + "fmt" + "strconv" + + protocol "github.com/tliron/glsp/protocol_3_16" +) + +type UIDNotInPasswdErr struct{} + +func (e UIDNotInPasswdErr) Error() string { + return "This UID does not exist" +} + +type InvalidUIDError struct{} + +func (e InvalidUIDError) Error() string { + return "This UID is invalid" +} + +type UIDNotInRangeError struct{} + +func (e UIDNotInRangeError) Error() string { + return "UIDs must be between 0 and 65535" +} + +type UIDValue struct { + EnforceUsingExisting bool +} + +func (v UIDValue) GetTypeDescription() []string { + return []string{"User ID"} +} + +func (v UIDValue) CheckIsValid(value string) []*InvalidValue { + uid, err := strconv.Atoi(value) + + if err != nil { + return []*InvalidValue{{ + Err: InvalidUIDError{}, + Start: 0, + End: uint32(len(value)), + }} + } + + if uid < 0 || uid > 65535 { + return []*InvalidValue{{ + Err: UIDNotInRangeError{}, + Start: 0, + End: uint32(len(value)), + }} + } + + if v.EnforceUsingExisting { + infos, err := fetchPasswdInfo() + + if err != nil { + return []*InvalidValue{} + } + + found := false + + for _, info := range infos { + if info.UID == value { + found = true + break + } + } + + if !found { + return []*InvalidValue{{ + Err: UIDNotInPasswdErr{}, + Start: 0, + End: uint32(len(value)), + }} + } + } + + return []*InvalidValue{} +} + +var defaultUIDsExplanation = []EnumString{ + { + InsertText: "0", + DescriptionText: "root", + Documentation: "The root user", + }, +} + +func (v UIDValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem { + infos, err := fetchPasswdInfo() + + if err != nil { + return utils.Map(defaultUIDsExplanation, func(enum EnumString) protocol.CompletionItem { + return enum.ToCompletionItem() + }) + } + + textFormat := protocol.InsertTextFormatPlainText + kind := protocol.CompletionItemKindValue + completions := make([]protocol.CompletionItem, len(infos)) + + for index, info := range infos { + // Find default uids + var existingUID *EnumString + + for _, defaultUID := range defaultUIDsExplanation { + if defaultUID.InsertText == info.UID { + existingUID = &defaultUID + break + } + } + + if existingUID != nil { + completions[index] = existingUID.ToCompletionItem() + } else { + completions[index] = protocol.CompletionItem{ + InsertTextFormat: &textFormat, + Kind: &kind, + InsertText: &info.UID, + Documentation: fmt.Sprintf("User %s; Home: %s", info.Name, info.HomePath), + } + } + } + + return completions +} diff --git a/handlers/fstab/documentation/documentation-mountoptions.go b/handlers/fstab/documentation/documentation-mountoptions.go index fe3018a..cc17c9d 100644 --- a/handlers/fstab/documentation/documentation-mountoptions.go +++ b/handlers/fstab/documentation/documentation-mountoptions.go @@ -245,25 +245,18 @@ func createMountOptionField( var DefaultMountOptionsField = createMountOptionField([]docvalues.EnumString{}, map[docvalues.EnumString]docvalues.Value{}) var MountOptionsMapField = map[string]docvalues.Value{ - // "adfs": createMountOptionField( - // []docvalues.EnumString{}, - // map[string]commondocumentation.AssignableOption{ - // "uid": { - // Documentation: "Set the owner of the files in the filesystem", - // Handler: func(context docvalues.KeyValueAssignmentContext) docvalues.Value { - // min := 0 - // return docvalues.NumberValue{Min: &min} - // }, - // }, - // "gid": { - // Documentation: "Set the group of the files in the filesystem", - // Handler: func(context docvalues.KeyValueAssignmentContext) docvalues.Value { - // min := 0 - // return docvalues.NumberValue{Min: &min} - // }, - // }, - // }, - // ), + "adfs": createMountOptionField( + commondocumentation.AdfsDocumentationEnums, + commondocumentation.AdfsDocumentationAssignable, + ), + "affs": createMountOptionField( + commondocumentation.AffsDocumentationEnums, + commondocumentation.AffsDocumentationAssignable, + ), + "debugfs": createMountOptionField( + commondocumentation.DebugfsDocumentationEnums, + commondocumentation.DebugfsDocumentationAssignable, + ), "ext2": createMountOptionField( commondocumentation.Ext2DocumentationEnums, commondocumentation.Ext2DocumentationAssignable, diff --git a/handlers/fstab/documentation/documentation-type.go b/handlers/fstab/documentation/documentation-type.go index c159b62..8a6f8f8 100644 --- a/handlers/fstab/documentation/documentation-type.go +++ b/handlers/fstab/documentation/documentation-type.go @@ -1,108 +1,20 @@ package fstabdocumentation -import docvalues "config-lsp/doc-values" +import ( + docvalues "config-lsp/doc-values" + "config-lsp/utils" +) var FileSystemTypeField = docvalues.ArrayValue{ Separator: ",", DuplicatesExtractor: &docvalues.SimpleDuplicatesExtractor, SubValue: docvalues.EnumValue{ EnforceValues: false, - Values: []docvalues.EnumString{ - { - InsertText: "none", - DescriptionText: "none", - Documentation: "An entry _none_ is useful for bind or move mounts.", + Values: utils.Map( + utils.KeysOfMap(MountOptionsMapField), + func(key string) docvalues.EnumString { + return docvalues.CreateEnumString(key) }, - { - InsertText: "swap", - DescriptionText: "swap", - Documentation: "An entry _swap_ denotes a file or partition to be used for swapping, cf. swapon(8)", - }, - { - InsertText: "ext2", - DescriptionText: "ext2", - Documentation: "Mount as ext2 filesystem", - }, - { - InsertText: "ext3", - DescriptionText: "ext3", - Documentation: "Mount as ext2 filesystem", - }, - { - InsertText: "ext4", - DescriptionText: "ext4", - Documentation: "Mount as ext4 filesystem", - }, - { - InsertText: "xfs", - DescriptionText: "xfs", - Documentation: "Mount as xfs filesystem", - }, - { - InsertText: "btrfs", - DescriptionText: "btrfs", - Documentation: "Mount as btrfs filesystem", - }, - { - InsertText: "f2fs", - DescriptionText: "f2fs", - Documentation: "Mount as f2fs filesystem", - }, - { - InsertText: "vfat", - DescriptionText: "vfat", - Documentation: "Mount as vfat filesystem", - }, - { - InsertText: "ntfs", - DescriptionText: "ntfs", - Documentation: "Mount as ntfs filesystem", - }, - { - InsertText: "hfsplus", - DescriptionText: "hfsplus", - Documentation: "Mount as hfsplus filesystem", - }, - { - InsertText: "tmpfs", - DescriptionText: "tmpfs", - Documentation: "Mount as tmpfs filesystem", - }, - { - InsertText: "sysfs", - DescriptionText: "sysfs", - Documentation: "Mount as sysfs filesystem", - }, - { - InsertText: "proc", - DescriptionText: "proc", - Documentation: "Mount as proc filesystem", - }, - { - InsertText: "iso9660", - DescriptionText: "iso9660", - Documentation: "Mount as iso9660 filesystem", - }, - { - InsertText: "udf", - DescriptionText: "udf", - Documentation: "Mount as udf filesystem", - }, - { - InsertText: "squashfs", - DescriptionText: "squashfs", - Documentation: "Mount as squashfs filesystem", - }, - { - InsertText: "nfs", - DescriptionText: "nfs", - Documentation: "Mount as nfs filesystem", - }, - { - InsertText: "cifs", - DescriptionText: "cifs", - Documentation: "Mount as cifs filesystem", - }, - }, + ), }, } diff --git a/handlers/fstab/text-document-completion.go b/handlers/fstab/text-document-completion.go index ff800cf..0378f68 100644 --- a/handlers/fstab/text-document-completion.go +++ b/handlers/fstab/text-document-completion.go @@ -3,7 +3,6 @@ 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" @@ -25,8 +24,6 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa 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) @@ -43,9 +40,7 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa 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, @@ -64,10 +59,12 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa value, cursor := GetFieldSafely(entry.Fields.Options, cursor) - return optionsField.FetchCompletions( + completions := optionsField.FetchCompletions( value, cursor, - ), nil + ) + + return completions, nil case FstabFieldFreq: value, cursor := GetFieldSafely(entry.Fields.Freq, cursor) diff --git a/handlers/openssh/text-document-did-open.go b/handlers/openssh/text-document-did-open.go index 652cfba..7c533e3 100644 --- a/handlers/openssh/text-document-did-open.go +++ b/handlers/openssh/text-document-did-open.go @@ -11,8 +11,6 @@ import ( func TextDocumentDidOpen(context *glsp.Context, params *protocol.DidOpenTextDocumentParams) error { readBytes, err := os.ReadFile(params.TextDocument.URI[len("file://"):]) - println("opened i la language eta", params.TextDocument.LanguageID) - if err != nil { return err }