Skip to content

Commit

Permalink
Reduce the available string option validators and add autocompletion …
Browse files Browse the repository at this point in the history
…for them (#3021)

* settings: Move all options to the start of the file

This will help with the overview of all available options and their optional
validators.

* settings: Add generic string option validator

* settings: Autocomplete string options
  • Loading branch information
JoeKar authored Mar 15, 2024
1 parent 4a53419 commit 8724709
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 199 deletions.
30 changes: 7 additions & 23 deletions internal/action/infocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,36 +192,20 @@ func OptionValueComplete(b *buffer.Buffer) ([]string, []string) {
_, suggestions = colorschemeComplete(input)
case "filetype":
_, suggestions = filetypeComplete(input)
case "fileformat":
if strings.HasPrefix("unix", input) {
suggestions = append(suggestions, "unix")
}
if strings.HasPrefix("dos", input) {
suggestions = append(suggestions, "dos")
}
case "sucmd":
if strings.HasPrefix("sudo", input) {
suggestions = append(suggestions, "sudo")
}
if strings.HasPrefix("doas", input) {
suggestions = append(suggestions, "doas")
}
case "clipboard":
if strings.HasPrefix("external", input) {
suggestions = append(suggestions, "external")
}
if strings.HasPrefix("internal", input) {
suggestions = append(suggestions, "internal")
}
if strings.HasPrefix("terminal", input) {
suggestions = append(suggestions, "terminal")
}
case "matchbracestyle":
if strings.HasPrefix("underline", input) {
suggestions = append(suggestions, "underline")
}
if strings.HasPrefix("highlight", input) {
suggestions = append(suggestions, "highlight")
default:
if choices, ok := config.OptionChoices[inputOpt]; ok {
for _, choice := range choices {
if strings.HasPrefix(choice, input) {
suggestions = append(suggestions, choice)
}
}
}
}
}
Expand Down
305 changes: 129 additions & 176 deletions internal/config/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,116 @@ import (

type optionValidator func(string, interface{}) error

// a list of settings that need option validators
var optionValidators = map[string]optionValidator{
"autosave": validateNonNegativeValue,
"clipboard": validateChoice,
"colorcolumn": validateNonNegativeValue,
"colorscheme": validateColorscheme,
"detectlimit": validateNonNegativeValue,
"encoding": validateEncoding,
"fileformat": validateChoice,
"matchbracestyle": validateChoice,
"multiopen": validateChoice,
"reload": validateChoice,
"scrollmargin": validateNonNegativeValue,
"scrollspeed": validateNonNegativeValue,
"tabsize": validatePositiveValue,
}

// a list of settings with pre-defined choices
var OptionChoices = map[string][]string{
"clipboard": {"internal", "external", "terminal"},
"fileformat": {"unix", "dos"},
"matchbracestyle": {"underline", "highlight"},
"multiopen": {"tab", "hsplit", "vsplit"},
"reload": {"prompt", "auto", "disabled"},
}

// a list of settings that can be globally and locally modified and their
// default values
var defaultCommonSettings = map[string]interface{}{
"autoindent": true,
"autosu": false,
"backup": true,
"backupdir": "",
"basename": false,
"colorcolumn": float64(0),
"cursorline": true,
"detectlimit": float64(100),
"diffgutter": false,
"encoding": "utf-8",
"eofnewline": true,
"fastdirty": false,
"fileformat": defaultFileFormat(),
"filetype": "unknown",
"hlsearch": false,
"hltaberrors": false,
"hltrailingws": false,
"incsearch": true,
"ignorecase": true,
"indentchar": " ",
"keepautoindent": false,
"matchbrace": true,
"matchbracestyle": "underline",
"mkparents": false,
"permbackup": false,
"readonly": false,
"reload": "prompt",
"rmtrailingws": false,
"ruler": true,
"relativeruler": false,
"savecursor": false,
"saveundo": false,
"scrollbar": false,
"scrollmargin": float64(3),
"scrollspeed": float64(2),
"smartpaste": true,
"softwrap": false,
"splitbottom": true,
"splitright": true,
"statusformatl": "$(filename) $(modified)($(line),$(col)) $(status.paste)| ft:$(opt:filetype) | $(opt:fileformat) | $(opt:encoding)",
"statusformatr": "$(bind:ToggleKeyMenu): bindings, $(bind:ToggleHelp): help",
"statusline": true,
"syntax": true,
"tabmovement": false,
"tabsize": float64(4),
"tabstospaces": false,
"useprimary": true,
"wordwrap": false,
}

// a list of settings that should only be globally modified and their
// default values
var DefaultGlobalOnlySettings = map[string]interface{}{
"autosave": float64(0),
"clipboard": "external",
"colorscheme": "default",
"divchars": "|-",
"divreverse": true,
"fakecursor": false,
"infobar": true,
"keymenu": false,
"mouse": true,
"multiopen": "tab",
"parsecursor": false,
"paste": false,
"pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"},
"pluginrepos": []string{},
"savehistory": true,
"scrollbarchar": "|",
"sucmd": "sudo",
"tabhighlight": false,
"tabreverse": true,
"xterm": false,
}

// a list of settings that should never be globally modified
var LocalSettings = []string{
"filetype",
"readonly",
}

var (
ErrInvalidOption = errors.New("Invalid option")
ErrInvalidValue = errors.New("Invalid value")
Expand All @@ -46,23 +156,6 @@ func init() {
parsedSettings = make(map[string]interface{})
}

// Options with validators
var optionValidators = map[string]optionValidator{
"autosave": validateNonNegativeValue,
"clipboard": validateClipboard,
"detectlimit": validateNonNegativeValue,
"tabsize": validatePositiveValue,
"scrollmargin": validateNonNegativeValue,
"scrollspeed": validateNonNegativeValue,
"colorscheme": validateColorscheme,
"colorcolumn": validateNonNegativeValue,
"fileformat": validateLineEnding,
"encoding": validateEncoding,
"multiopen": validateMultiOpen,
"reload": validateReload,
"matchbracestyle": validateMatchBraceStyle,
}

func ReadSettings() error {
filename := filepath.Join(ConfigDir, "settings.json")
if _, e := os.Stat(filename); e == nil {
Expand Down Expand Up @@ -258,57 +351,6 @@ func GetGlobalOption(name string) interface{} {
return GlobalSettings[name]
}

var defaultCommonSettings = map[string]interface{}{
"autoindent": true,
"autosu": false,
"backup": true,
"backupdir": "",
"basename": false,
"colorcolumn": float64(0),
"cursorline": true,
"detectlimit": float64(100),
"diffgutter": false,
"encoding": "utf-8",
"eofnewline": true,
"fastdirty": false,
"fileformat": defaultFileFormat(),
"filetype": "unknown",
"hlsearch": false,
"hltaberrors": false,
"hltrailingws": false,
"incsearch": true,
"ignorecase": true,
"indentchar": " ",
"keepautoindent": false,
"matchbrace": true,
"matchbracestyle": "underline",
"mkparents": false,
"permbackup": false,
"readonly": false,
"reload": "prompt",
"rmtrailingws": false,
"ruler": true,
"relativeruler": false,
"savecursor": false,
"saveundo": false,
"scrollbar": false,
"scrollmargin": float64(3),
"scrollspeed": float64(2),
"smartpaste": true,
"softwrap": false,
"splitbottom": true,
"splitright": true,
"statusformatl": "$(filename) $(modified)($(line),$(col)) $(status.paste)| ft:$(opt:filetype) | $(opt:fileformat) | $(opt:encoding)",
"statusformatr": "$(bind:ToggleKeyMenu): bindings, $(bind:ToggleHelp): help",
"statusline": true,
"syntax": true,
"tabmovement": false,
"tabsize": float64(4),
"tabstospaces": false,
"useprimary": true,
"wordwrap": false,
}

func defaultFileFormat() string {
if runtime.GOOS == "windows" {
return "dos"
Expand Down Expand Up @@ -337,37 +379,6 @@ func DefaultCommonSettings() map[string]interface{} {
return commonsettings
}

// a list of settings that should only be globally modified and their
// default values
var DefaultGlobalOnlySettings = map[string]interface{}{
"autosave": float64(0),
"clipboard": "external",
"colorscheme": "default",
"divchars": "|-",
"divreverse": true,
"fakecursor": false,
"infobar": true,
"keymenu": false,
"mouse": true,
"multiopen": "tab",
"parsecursor": false,
"paste": false,
"pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"},
"pluginrepos": []string{},
"savehistory": true,
"scrollbarchar": "|",
"sucmd": "sudo",
"tabhighlight": false,
"tabreverse": true,
"xterm": false,
}

// a list of settings that should never be globally modified
var LocalSettings = []string{
"filetype",
"readonly",
}

// DefaultGlobalSettings returns the default global settings for micro
// Note that colorscheme is a global only option
func DefaultGlobalSettings() map[string]interface{} {
Expand Down Expand Up @@ -461,45 +472,35 @@ func validateNonNegativeValue(option string, value interface{}) error {
return nil
}

func validateColorscheme(option string, value interface{}) error {
colorscheme, ok := value.(string)

if !ok {
return errors.New("Expected string type for colorscheme")
}

if !ColorschemeExists(colorscheme) {
return errors.New(colorscheme + " is not a valid colorscheme")
}

return nil
}

func validateClipboard(option string, value interface{}) error {
val, ok := value.(string)
func validateChoice(option string, value interface{}) error {
if choices, ok := OptionChoices[option]; ok {
val, ok := value.(string)
if !ok {
return errors.New("Expected string type for " + option)
}

if !ok {
return errors.New("Expected string type for clipboard")
}
for _, v := range choices {
if val == v {
return nil
}
}

switch val {
case "internal", "external", "terminal":
default:
return errors.New(option + " must be 'internal', 'external', or 'terminal'")
choicesStr := strings.Join(choices, ", ")
return errors.New(option + " must be one of: " + choicesStr)
}

return nil
return errors.New("Option has no pre-defined choices")
}

func validateLineEnding(option string, value interface{}) error {
endingType, ok := value.(string)
func validateColorscheme(option string, value interface{}) error {
colorscheme, ok := value.(string)

if !ok {
return errors.New("Expected string type for file format")
return errors.New("Expected string type for colorscheme")
}

if endingType != "unix" && endingType != "dos" {
return errors.New("File format must be either 'unix' or 'dos'")
if !ColorschemeExists(colorscheme) {
return errors.New(colorscheme + " is not a valid colorscheme")
}

return nil
Expand All @@ -509,51 +510,3 @@ func validateEncoding(option string, value interface{}) error {
_, err := htmlindex.Get(value.(string))
return err
}

func validateMultiOpen(option string, value interface{}) error {
val, ok := value.(string)

if !ok {
return errors.New("Expected string type for multiopen")
}

switch val {
case "tab", "hsplit", "vsplit":
default:
return errors.New(option + " must be 'tab', 'hsplit', or 'vsplit'")
}

return nil
}

func validateReload(option string, value interface{}) error {
val, ok := value.(string)

if !ok {
return errors.New("Expected string type for reload")
}

switch val {
case "prompt", "auto", "disabled":
default:
return errors.New(option + " must be 'prompt', 'auto' or 'disabled'")
}

return nil
}

func validateMatchBraceStyle(option string, value interface{}) error {
val, ok := value.(string)

if !ok {
errors.New("Expected string type for matchbracestyle")
}

switch val {
case "underline", "highlight":
default:
return errors.New(option + " must be 'underline' or 'highlight'")
}

return nil
}

0 comments on commit 8724709

Please sign in to comment.