Skip to content

Commit 7dc78b7

Browse files
authored
Merge pull request zyedidia#3343 from JoeKar/fix/volatile-after-reinit
Rework `filetype` change, `reload` command and `autosave`
2 parents fd3a002 + b80ea93 commit 7dc78b7

File tree

7 files changed

+243
-128
lines changed

7 files changed

+243
-128
lines changed

cmd/micro/micro.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ func main() {
273273
screen.TermMessage(err)
274274
continue
275275
}
276+
if err = config.OptionIsValid(k, nativeValue); err != nil {
277+
screen.TermMessage(err)
278+
continue
279+
}
276280
config.GlobalSettings[k] = nativeValue
277281
config.VolatileSettings[k] = true
278282
}
@@ -352,9 +356,9 @@ func main() {
352356
log.Println(clipErr, " or change 'clipboard' option")
353357
}
354358

359+
config.StartAutoSave()
355360
if a := config.GetGlobalOption("autosave").(float64); a > 0 {
356-
config.SetAutoTime(int(a))
357-
config.StartAutoSave()
361+
config.SetAutoTime(a)
358362
}
359363

360364
screen.Events = make(chan tcell.Event)

internal/action/command.go

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"os/exec"
99
"path/filepath"
10+
"reflect"
1011
"regexp"
1112
"strconv"
1213
"strings"
@@ -357,10 +358,24 @@ func reloadRuntime(reloadPlugins bool) {
357358
err := config.ReadSettings()
358359
if err != nil {
359360
screen.TermMessage(err)
360-
}
361-
err = config.InitGlobalSettings()
362-
if err != nil {
363-
screen.TermMessage(err)
361+
} else {
362+
parsedSettings := config.ParsedSettings()
363+
defaultSettings := config.DefaultAllSettings()
364+
for k := range defaultSettings {
365+
if _, ok := config.VolatileSettings[k]; ok {
366+
// reload should not override volatile settings
367+
continue
368+
}
369+
370+
if _, ok := parsedSettings[k]; ok {
371+
err = doSetGlobalOptionNative(k, parsedSettings[k])
372+
} else {
373+
err = doSetGlobalOptionNative(k, defaultSettings[k])
374+
}
375+
if err != nil {
376+
screen.TermMessage(err)
377+
}
378+
}
364379
}
365380

366381
if reloadPlugins {
@@ -393,7 +408,7 @@ func reloadRuntime(reloadPlugins bool) {
393408
screen.TermMessage(err)
394409
}
395410
for _, b := range buffer.OpenBuffers {
396-
b.UpdateRules()
411+
b.ReloadSettings(true)
397412
}
398413
}
399414

@@ -512,16 +527,11 @@ func (h *BufPane) NewTabCmd(args []string) {
512527
}
513528
}
514529

515-
func SetGlobalOptionNative(option string, nativeValue interface{}) error {
516-
// check for local option first...
517-
for _, s := range config.LocalSettings {
518-
if s == option {
519-
MainTab().CurPane().Buf.SetOptionNative(option, nativeValue)
520-
return nil
521-
}
530+
func doSetGlobalOptionNative(option string, nativeValue interface{}) error {
531+
if reflect.DeepEqual(config.GlobalSettings[option], nativeValue) {
532+
return nil
522533
}
523534

524-
// ...if it's not local continue with the globals
525535
config.GlobalSettings[option] = nativeValue
526536
config.ModifiedSettings[option] = true
527537
delete(config.VolatileSettings, option)
@@ -542,8 +552,7 @@ func SetGlobalOptionNative(option string, nativeValue interface{}) error {
542552
}
543553
} else if option == "autosave" {
544554
if nativeValue.(float64) > 0 {
545-
config.SetAutoTime(int(nativeValue.(float64)))
546-
config.StartAutoSave()
555+
config.SetAutoTime(nativeValue.(float64))
547556
} else {
548557
config.SetAutoTime(0)
549558
}
@@ -574,8 +583,30 @@ func SetGlobalOptionNative(option string, nativeValue interface{}) error {
574583
}
575584
}
576585

586+
return nil
587+
}
588+
589+
func SetGlobalOptionNative(option string, nativeValue interface{}) error {
590+
if err := config.OptionIsValid(option, nativeValue); err != nil {
591+
return err
592+
}
593+
594+
// check for local option first...
595+
for _, s := range config.LocalSettings {
596+
if s == option {
597+
return MainTab().CurPane().Buf.SetOptionNative(option, nativeValue)
598+
}
599+
}
600+
601+
// ...if it's not local continue with the globals...
602+
if err := doSetGlobalOptionNative(option, nativeValue); err != nil {
603+
return err
604+
}
605+
606+
// ...at last check the buffer locals
577607
for _, b := range buffer.OpenBuffers {
578-
b.SetOptionNative(option, nativeValue)
608+
b.DoSetOptionNative(option, nativeValue)
609+
delete(b.LocalSettings, option)
579610
}
580611

581612
return config.WriteSettings(filepath.Join(config.ConfigDir, "settings.json"))
@@ -602,16 +633,10 @@ func (h *BufPane) ResetCmd(args []string) {
602633
}
603634

604635
option := args[0]
636+
defaults := config.DefaultAllSettings()
605637

606-
defaultGlobals := config.DefaultGlobalSettings()
607-
defaultLocals := config.DefaultCommonSettings()
608-
609-
if _, ok := defaultGlobals[option]; ok {
610-
SetGlobalOptionNative(option, defaultGlobals[option])
611-
return
612-
}
613-
if _, ok := defaultLocals[option]; ok {
614-
h.Buf.SetOptionNative(option, defaultLocals[option])
638+
if _, ok := defaults[option]; ok {
639+
SetGlobalOptionNative(option, defaults[option])
615640
return
616641
}
617642
InfoBar.Error(config.ErrInvalidOption)

internal/buffer/buffer.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ type SharedBuffer struct {
8686

8787
// Settings customized by the user
8888
Settings map[string]interface{}
89+
// LocalSettings customized by the user for this buffer only
90+
LocalSettings map[string]bool
8991

9092
Suggestions []string
9193
Completions []string
@@ -326,6 +328,7 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
326328
// assigning the filetype.
327329
settings := config.DefaultCommonSettings()
328330
b.Settings = config.DefaultCommonSettings()
331+
b.LocalSettings = make(map[string]bool)
329332
for k, v := range config.GlobalSettings {
330333
if _, ok := config.DefaultGlobalOnlySettings[k]; !ok {
331334
// make sure setting is not global-only
@@ -364,6 +367,9 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT
364367
case "dos":
365368
ff = FFDos
366369
}
370+
} else {
371+
// in case of autodetection treat as locally set
372+
b.LocalSettings["fileformat"] = true
367373
}
368374

369375
b.LineArray = NewLineArray(uint64(size), ff, reader)

internal/buffer/settings.go

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,54 @@ package buffer
22

33
import (
44
"crypto/md5"
5+
"reflect"
56

67
"github.com/zyedidia/micro/v2/internal/config"
78
"github.com/zyedidia/micro/v2/internal/screen"
89
)
910

10-
func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
11+
func (b *Buffer) ReloadSettings(reloadFiletype bool) {
12+
settings := config.ParsedSettings()
13+
14+
if _, ok := b.LocalSettings["filetype"]; !ok && reloadFiletype {
15+
// need to update filetype before updating other settings based on it
16+
b.Settings["filetype"] = "unknown"
17+
if v, ok := settings["filetype"]; ok {
18+
b.Settings["filetype"] = v
19+
}
20+
}
21+
22+
// update syntax rules, which will also update filetype if needed
23+
b.UpdateRules()
24+
settings["filetype"] = b.Settings["filetype"]
25+
26+
config.InitLocalSettings(settings, b.Path)
27+
for k, v := range config.DefaultCommonSettings() {
28+
if k == "filetype" {
29+
// prevent recursion
30+
continue
31+
}
32+
if _, ok := config.VolatileSettings[k]; ok {
33+
// reload should not override volatile settings
34+
continue
35+
}
36+
if _, ok := b.LocalSettings[k]; ok {
37+
// reload should not override local settings
38+
continue
39+
}
40+
if _, ok := settings[k]; ok {
41+
b.DoSetOptionNative(k, settings[k])
42+
} else {
43+
b.DoSetOptionNative(k, v)
44+
}
45+
}
46+
}
47+
48+
func (b *Buffer) DoSetOptionNative(option string, nativeValue interface{}) {
49+
if reflect.DeepEqual(b.Settings[option], nativeValue) {
50+
return
51+
}
52+
1153
b.Settings[option] = nativeValue
1254

1355
if option == "fastdirty" {
@@ -26,17 +68,7 @@ func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
2668
} else if option == "statusline" {
2769
screen.Redraw()
2870
} else if option == "filetype" {
29-
config.InitRuntimeFiles(true)
30-
err := config.ReadSettings()
31-
if err != nil {
32-
screen.TermMessage(err)
33-
}
34-
err = config.InitGlobalSettings()
35-
if err != nil {
36-
screen.TermMessage(err)
37-
}
38-
config.InitLocalSettings(b.Settings, b.Path)
39-
b.UpdateRules()
71+
b.ReloadSettings(false)
4072
} else if option == "fileformat" {
4173
switch b.Settings["fileformat"].(string) {
4274
case "unix":
@@ -85,6 +117,15 @@ func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
85117
if b.OptionCallback != nil {
86118
b.OptionCallback(option, nativeValue)
87119
}
120+
}
121+
122+
func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
123+
if err := config.OptionIsValid(option, nativeValue); err != nil {
124+
return err
125+
}
126+
127+
b.DoSetOptionNative(option, nativeValue)
128+
b.LocalSettings[option] = true
88129

89130
return nil
90131
}

internal/config/autosave.go

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,49 @@
11
package config
22

33
import (
4-
"sync"
54
"time"
65
)
76

87
var Autosave chan bool
9-
var autotime int
10-
11-
// lock for autosave
12-
var autolock sync.Mutex
8+
var autotime chan float64
139

1410
func init() {
1511
Autosave = make(chan bool)
12+
autotime = make(chan float64)
1613
}
1714

18-
func SetAutoTime(a int) {
19-
autolock.Lock()
20-
autotime = a
21-
autolock.Unlock()
22-
}
23-
24-
func GetAutoTime() int {
25-
autolock.Lock()
26-
a := autotime
27-
autolock.Unlock()
28-
return a
15+
func SetAutoTime(a float64) {
16+
autotime <- a
2917
}
3018

3119
func StartAutoSave() {
3220
go func() {
21+
var a float64
22+
var t *time.Timer
23+
var elapsed <-chan time.Time
3324
for {
34-
autolock.Lock()
35-
a := autotime
36-
autolock.Unlock()
37-
if a < 1 {
38-
break
25+
select {
26+
case a = <-autotime:
27+
if t != nil {
28+
t.Stop()
29+
for len(elapsed) > 0 {
30+
<-elapsed
31+
}
32+
}
33+
if a > 0 {
34+
if t != nil {
35+
t.Reset(time.Duration(a * float64(time.Second)))
36+
} else {
37+
t = time.NewTimer(time.Duration(a * float64(time.Second)))
38+
elapsed = t.C
39+
}
40+
}
41+
case <-elapsed:
42+
if a > 0 {
43+
t.Reset(time.Duration(a * float64(time.Second)))
44+
Autosave <- true
45+
}
3946
}
40-
time.Sleep(time.Duration(a) * time.Second)
41-
Autosave <- true
4247
}
4348
}()
4449
}

0 commit comments

Comments
 (0)