Skip to content

Commit

Permalink
Merge pull request #3662 from JoeKar/fix/reload-settings
Browse files Browse the repository at this point in the history
buffer: Fix `ReloadSettings(true)` for volatile `filetype`
  • Loading branch information
JoeKar authored Feb 24, 2025
2 parents 5a62a8e + ddc6051 commit c937479
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 47 deletions.
12 changes: 6 additions & 6 deletions internal/action/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1794,24 +1794,24 @@ func (h *BufPane) HalfPageDown() bool {

// ToggleDiffGutter turns the diff gutter off and on
func (h *BufPane) ToggleDiffGutter() bool {
if !h.Buf.Settings["diffgutter"].(bool) {
h.Buf.Settings["diffgutter"] = true
diffgutter := !h.Buf.Settings["diffgutter"].(bool)
h.Buf.SetOptionNative("diffgutter", diffgutter)
if diffgutter {
h.Buf.UpdateDiff()
InfoBar.Message("Enabled diff gutter")
} else {
h.Buf.Settings["diffgutter"] = false
InfoBar.Message("Disabled diff gutter")
}
return true
}

// ToggleRuler turns line numbers off and on
func (h *BufPane) ToggleRuler() bool {
if !h.Buf.Settings["ruler"].(bool) {
h.Buf.Settings["ruler"] = true
ruler := !h.Buf.Settings["ruler"].(bool)
h.Buf.SetOptionNative("ruler", ruler)
if ruler {
InfoBar.Message("Enabled ruler")
} else {
h.Buf.Settings["ruler"] = false
InfoBar.Message("Disabled ruler")
}
return true
Expand Down
21 changes: 5 additions & 16 deletions internal/buffer/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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":
Expand Down Expand Up @@ -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)
Expand Down
38 changes: 26 additions & 12 deletions internal/buffer/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ import (

func (b *Buffer) ReloadSettings(reloadFiletype bool) {
settings := config.ParsedSettings()
config.UpdatePathGlobLocals(settings, b.AbsPath)

if _, ok := b.LocalSettings["filetype"]; !ok && reloadFiletype {
oldFiletype := b.Settings["filetype"].(string)

_, local := b.LocalSettings["filetype"]
_, volatile := config.VolatileSettings["filetype"]
if reloadFiletype && !local && !volatile {
// need to update filetype before updating other settings based on it
b.Settings["filetype"] = "unknown"
if v, ok := settings["filetype"]; ok {
Expand All @@ -23,9 +28,14 @@ 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)
curFiletype := b.Settings["filetype"].(string)
if oldFiletype != curFiletype {
b.doCallbacks("filetype", oldFiletype, curFiletype)
}

config.UpdateFileTypeLocals(settings, curFiletype)

for k, v := range config.DefaultCommonSettings() {
if k == "filetype" {
// prevent recursion
Expand Down Expand Up @@ -117,15 +127,7 @@ func (b *Buffer) DoSetOptionNative(option string, nativeValue interface{}) {
}
}

if b.OptionCallback != nil {
b.OptionCallback(option, nativeValue)
}

if err := config.RunPluginFn("onBufferOptionChanged",
luar.New(ulua.L, b), luar.New(ulua.L, option),
luar.New(ulua.L, oldValue), luar.New(ulua.L, nativeValue)); err != nil {
screen.TermMessage(err)
}
b.doCallbacks(option, oldValue, nativeValue)
}

func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
Expand All @@ -152,3 +154,15 @@ func (b *Buffer) SetOption(option, value string) error {

return b.SetOptionNative(option, nativeValue)
}

func (b *Buffer) doCallbacks(option string, oldValue interface{}, newValue interface{}) {
if b.OptionCallback != nil {
b.OptionCallback(option, newValue)
}

if err := config.RunPluginFn("onBufferOptionChanged",
luar.New(ulua.L, b), luar.New(ulua.L, option),
luar.New(ulua.L, oldValue), luar.New(ulua.L, newValue)); err != nil {
screen.TermMessage(err)
}
}
35 changes: 22 additions & 13 deletions internal/config/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,22 +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{}) {
}
}
}
}

// 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{}) {
if k1 != "filetype" {
settings[k1] = v1
}
}
Expand Down

0 comments on commit c937479

Please sign in to comment.