diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index 1172dac8..092a5dcc 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -325,28 +325,17 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT b.AbsPath = absPath b.Path = path - // this is a little messy since we need to know some settings to read - // the file properly, but some settings depend on the filetype, which - // we don't know until reading the file. We first read the settings - // into a local variable and then use that to determine the encoding, - // readonly, and fileformat necessary for reading the file and - // assigning the filetype. - settings := config.DefaultCommonSettings() b.Settings = config.DefaultCommonSettings() b.LocalSettings = make(map[string]bool) for k, v := range config.GlobalSettings { if _, ok := config.DefaultGlobalOnlySettings[k]; !ok { // make sure setting is not global-only - settings[k] = v b.Settings[k] = v } } - config.InitLocalSettings(settings, absPath) - b.Settings["readonly"] = settings["readonly"] - b.Settings["filetype"] = settings["filetype"] - b.Settings["syntax"] = settings["syntax"] + config.UpdatePathGlobLocals(b.Settings, absPath) - enc, err := htmlindex.Get(settings["encoding"].(string)) + enc, err := htmlindex.Get(b.Settings["encoding"].(string)) if err != nil { enc = unicode.UTF8 b.Settings["encoding"] = "utf-8" @@ -366,7 +355,7 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT if size == 0 { // for empty files, use the fileformat setting instead of // autodetection - switch settings["fileformat"] { + switch b.Settings["fileformat"] { case "unix": ff = FFUnix case "dos": @@ -397,8 +386,8 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT } b.UpdateRules() - // init local settings again now that we know the filetype - config.InitLocalSettings(b.Settings, b.Path) + // we know the filetype now, so update per-filetype settings + config.UpdateFileTypeLocals(b.Settings, b.Settings["filetype"].(string)) if _, err := os.Stat(filepath.Join(config.ConfigDir, "buffers")); os.IsNotExist(err) { os.Mkdir(filepath.Join(config.ConfigDir, "buffers"), os.ModePerm) diff --git a/internal/buffer/settings.go b/internal/buffer/settings.go index fe794550..2e9005b2 100644 --- a/internal/buffer/settings.go +++ b/internal/buffer/settings.go @@ -25,9 +25,9 @@ func (b *Buffer) ReloadSettings(reloadFiletype bool) { // update syntax rules, which will also update filetype if needed b.UpdateRules() - settings["filetype"] = b.Settings["filetype"] - config.InitLocalSettings(settings, b.Path) + config.UpdatePathGlobLocals(settings, b.AbsPath) + config.UpdateFileTypeLocals(settings, b.Settings["filetype"].(string)) for k, v := range config.DefaultCommonSettings() { if k == "filetype" { // prevent recursion diff --git a/internal/config/settings.go b/internal/config/settings.go index a72f5025..ddffb72f 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -288,24 +288,31 @@ func InitGlobalSettings() error { return err } -// InitLocalSettings scans the json in settings.json and sets the options locally based -// on whether the filetype or path matches ft or glob local settings +// UpdatePathGlobLocals scans the already parsed settings and sets the options locally +// based on whether the path matches a glob // Must be called after ReadSettings -func InitLocalSettings(settings map[string]interface{}, path string) { +func UpdatePathGlobLocals(settings map[string]interface{}, path string) { for k, v := range parsedSettings { - if strings.HasPrefix(reflect.TypeOf(v).String(), "map") { - if strings.HasPrefix(k, "ft:") { - if settings["filetype"].(string) == k[3:] { - for k1, v1 := range v.(map[string]interface{}) { - settings[k1] = v1 - } + if strings.HasPrefix(reflect.TypeOf(v).String(), "map") && !strings.HasPrefix(k, "ft:") { + g, _ := glob.Compile(k) + if g.MatchString(path) { + for k1, v1 := range v.(map[string]interface{}) { + settings[k1] = v1 } - } else { - g, _ := glob.Compile(k) - if g.MatchString(path) { - for k1, v1 := range v.(map[string]interface{}) { - settings[k1] = v1 - } + } + } + } +} + +// UpdateFileTypeLocals scans the already parsed settings and sets the options locally +// based on whether the filetype matches to "ft:" +// Must be called after ReadSettings +func UpdateFileTypeLocals(settings map[string]interface{}, filetype string) { + for k, v := range parsedSettings { + if strings.HasPrefix(reflect.TypeOf(v).String(), "map") && strings.HasPrefix(k, "ft:") { + if filetype == k[3:] { + for k1, v1 := range v.(map[string]interface{}) { + settings[k1] = v1 } } }