From 261748bd56bc7e358fe57cb4644fee1f9594f7a5 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Wed, 24 Aug 2016 16:55:44 -0700 Subject: [PATCH] Add local settings for each buffer --- cmd/micro/actions.go | 24 +++++------ cmd/micro/autocomplete.go | 2 +- cmd/micro/buffer.go | 16 +++++-- cmd/micro/colorscheme.go | 2 +- cmd/micro/command.go | 55 ++++++++++++++--------- cmd/micro/cursor.go | 9 ++-- cmd/micro/micro.go | 12 +++++- cmd/micro/search.go | 2 +- cmd/micro/settings.go | 91 +++++++++++++++++++++++++++------------ cmd/micro/split_tree.go | 2 +- cmd/micro/util.go | 8 ++-- cmd/micro/view.go | 30 ++++++------- 12 files changed, 159 insertions(+), 94 deletions(-) diff --git a/cmd/micro/actions.go b/cmd/micro/actions.go index c238aafa..82b3b94b 100644 --- a/cmd/micro/actions.go +++ b/cmd/micro/actions.go @@ -447,7 +447,7 @@ func (v *View) InsertNewline(usePlugin bool) bool { ws := GetLeadingWhitespace(v.Buf.Line(v.Cursor.Y)) v.Cursor.Right() - if settings["autoindent"].(bool) { + if v.Buf.Settings["autoindent"].(bool) { v.Buf.Insert(v.Cursor.Loc, ws) for i := 0; i < len(ws); i++ { v.Cursor.Right() @@ -487,8 +487,8 @@ func (v *View) Backspace(usePlugin bool) bool { // whitespace at the start of the line, we should delete as if its a // tab (tabSize number of spaces) lineStart := v.Buf.Line(v.Cursor.Y)[:v.Cursor.X] - tabSize := int(settings["tabsize"].(float64)) - if settings["tabstospaces"].(bool) && IsSpaces(lineStart) && len(lineStart) != 0 && len(lineStart)%tabSize == 0 { + tabSize := int(v.Buf.Settings["tabsize"].(float64)) + if v.Buf.Settings["tabstospaces"].(bool) && IsSpaces(lineStart) && len(lineStart) != 0 && len(lineStart)%tabSize == 0 { loc := v.Cursor.Loc v.Cursor.Loc = loc.Move(-tabSize, v.Buf) cx, cy := v.Cursor.X, v.Cursor.Y @@ -581,8 +581,8 @@ func (v *View) IndentSelection(usePlugin bool) bool { end := v.Cursor.CurSelection[1].Move(-1, v.Buf).Y endX := v.Cursor.CurSelection[1].Move(-1, v.Buf).X for i := start; i <= end; i++ { - if settings["tabstospaces"].(bool) { - tabsize := int(settings["tabsize"].(float64)) + if v.Buf.Settings["tabstospaces"].(bool) { + tabsize := int(v.Buf.Settings["tabsize"].(float64)) v.Buf.Insert(Loc{0, i}, Spaces(tabsize)) if i == start { if v.Cursor.CurSelection[0].X > 0 { @@ -626,8 +626,8 @@ func (v *View) OutdentSelection(usePlugin bool) bool { endX := v.Cursor.CurSelection[1].Move(-1, v.Buf).X for i := start; i <= end; i++ { if len(GetLeadingWhitespace(v.Buf.Line(i))) > 0 { - if settings["tabstospaces"].(bool) { - tabsize := int(settings["tabsize"].(float64)) + if v.Buf.Settings["tabstospaces"].(bool) { + tabsize := int(v.Buf.Settings["tabsize"].(float64)) for j := 0; j < tabsize; j++ { if len(GetLeadingWhitespace(v.Buf.Line(i))) == 0 { break @@ -675,8 +675,8 @@ func (v *View) InsertTab(usePlugin bool) bool { return false } // Insert a tab - if settings["tabstospaces"].(bool) { - tabSize := int(settings["tabsize"].(float64)) + if v.Buf.Settings["tabstospaces"].(bool) { + tabSize := int(v.Buf.Settings["tabsize"].(float64)) v.Buf.Insert(v.Cursor.Loc, Spaces(tabSize)) for i := 0; i < tabSize; i++ { v.Cursor.Right() @@ -1162,11 +1162,11 @@ func (v *View) ToggleRuler(usePlugin bool) bool { return false } - if settings["ruler"] == false { - settings["ruler"] = true + if v.Buf.Settings["ruler"] == false { + v.Buf.Settings["ruler"] = true messenger.Message("Enabled ruler") } else { - settings["ruler"] = false + v.Buf.Settings["ruler"] = false messenger.Message("Disabled ruler") } diff --git a/cmd/micro/autocomplete.go b/cmd/micro/autocomplete.go index fcfd726a..64ec89d1 100644 --- a/cmd/micro/autocomplete.go +++ b/cmd/micro/autocomplete.go @@ -91,7 +91,7 @@ func HelpComplete(input string) (string, []string) { // OptionComplete autocompletes options func OptionComplete(input string) (string, []string) { var suggestions []string - for option := range settings { + for option := range globalSettings { if strings.HasPrefix(option, input) { suggestions = append(suggestions, option) } diff --git a/cmd/micro/buffer.go b/cmd/micro/buffer.go index 6a855417..a4ba7922 100644 --- a/cmd/micro/buffer.go +++ b/cmd/micro/buffer.go @@ -41,6 +41,9 @@ type Buffer struct { rules []SyntaxRule // The buffer's filetype FileType string + + // Buffer local settings + Settings map[string]interface{} } // The SerializedBuffer holds the types that get serialized when a buffer is saved @@ -56,6 +59,11 @@ func NewBuffer(txt []byte, path string) *Buffer { b := new(Buffer) b.LineArray = NewLineArray(txt) + b.Settings = make(map[string]interface{}) + for k, v := range globalSettings { + b.Settings[k] = v + } + b.Path = path b.Name = path @@ -85,7 +93,7 @@ func NewBuffer(txt []byte, path string) *Buffer { buf: b, } - if settings["savecursor"].(bool) || settings["saveundo"].(bool) { + if b.Settings["savecursor"].(bool) || b.Settings["saveundo"].(bool) { // If either savecursor or saveundo is turned on, we need to load the serialized information // from ~/.config/micro/buffers absPath, _ := filepath.Abs(b.Path) @@ -98,13 +106,13 @@ func NewBuffer(txt []byte, path string) *Buffer { if err != nil { TermMessage(err.Error(), "\n", "You may want to remove the files in ~/.config/micro/buffers (these files store the information for the 'saveundo' and 'savecursor' options) if this problem persists.") } - if settings["savecursor"].(bool) { + if b.Settings["savecursor"].(bool) { b.Cursor = buffer.Cursor b.Cursor.buf = b b.Cursor.Relocate() } - if settings["saveundo"].(bool) { + if b.Settings["saveundo"].(bool) { // We should only use last time's eventhandler if the file wasn't by someone else in the meantime if b.ModTime == buffer.ModTime { b.EventHandler = buffer.EventHandler @@ -184,7 +192,7 @@ func (b *Buffer) SaveWithSudo() error { // Serialize serializes the buffer to configDir/buffers func (b *Buffer) Serialize() error { - if settings["savecursor"].(bool) || settings["saveundo"].(bool) { + if b.Settings["savecursor"].(bool) || b.Settings["saveundo"].(bool) { absPath, _ := filepath.Abs(b.Path) file, err := os.Create(configDir + "/buffers/" + EscapePath(absPath)) if err == nil { diff --git a/cmd/micro/colorscheme.go b/cmd/micro/colorscheme.go index 7c9ad1e4..eac9062a 100644 --- a/cmd/micro/colorscheme.go +++ b/cmd/micro/colorscheme.go @@ -24,7 +24,7 @@ func InitColorscheme() { // LoadDefaultColorscheme loads the default colorscheme from $(configDir)/colorschemes func LoadDefaultColorscheme() { - LoadColorscheme(settings["colorscheme"].(string), configDir+"/colorschemes") + LoadColorscheme(globalSettings["colorscheme"].(string), configDir+"/colorschemes") } // LoadColorscheme loads the given colorscheme from a directory diff --git a/cmd/micro/command.go b/cmd/micro/command.go index b41a3db4..61ba4330 100644 --- a/cmd/micro/command.go +++ b/cmd/micro/command.go @@ -25,16 +25,17 @@ type StrCommand struct { var commands map[string]Command var commandActions = map[string]func([]string){ - "Set": Set, - "Run": Run, - "Bind": Bind, - "Quit": Quit, - "Save": Save, - "Replace": Replace, - "VSplit": VSplit, - "HSplit": HSplit, - "Tab": NewTab, - "Help": Help, + "Set": Set, + "SetLocal": SetLocal, + "Run": Run, + "Bind": Bind, + "Quit": Quit, + "Save": Save, + "Replace": Replace, + "VSplit": VSplit, + "HSplit": HSplit, + "Tab": NewTab, + "Help": Help, } // InitCommands initializes the default commands @@ -67,16 +68,17 @@ func MakeCommand(name, function string, completions ...Completion) { // DefaultCommands returns a map containing micro's default commands func DefaultCommands() map[string]StrCommand { return map[string]StrCommand{ - "set": StrCommand{"Set", []Completion{OptionCompletion, NoCompletion}}, - "bind": StrCommand{"Bind", []Completion{NoCompletion}}, - "run": StrCommand{"Run", []Completion{NoCompletion}}, - "quit": StrCommand{"Quit", []Completion{NoCompletion}}, - "save": StrCommand{"Save", []Completion{NoCompletion}}, - "replace": StrCommand{"Replace", []Completion{NoCompletion}}, - "vsplit": StrCommand{"VSplit", []Completion{FileCompletion, NoCompletion}}, - "hsplit": StrCommand{"HSplit", []Completion{FileCompletion, NoCompletion}}, - "tab": StrCommand{"Tab", []Completion{FileCompletion, NoCompletion}}, - "help": StrCommand{"Help", []Completion{HelpCompletion, NoCompletion}}, + "set": StrCommand{"Set", []Completion{OptionCompletion, NoCompletion}}, + "setlocal": StrCommand{"SetLocal", []Completion{OptionCompletion, NoCompletion}}, + "bind": StrCommand{"Bind", []Completion{NoCompletion}}, + "run": StrCommand{"Run", []Completion{NoCompletion}}, + "quit": StrCommand{"Quit", []Completion{NoCompletion}}, + "save": StrCommand{"Save", []Completion{NoCompletion}}, + "replace": StrCommand{"Replace", []Completion{NoCompletion}}, + "vsplit": StrCommand{"VSplit", []Completion{FileCompletion, NoCompletion}}, + "hsplit": StrCommand{"HSplit", []Completion{FileCompletion, NoCompletion}}, + "tab": StrCommand{"Tab", []Completion{FileCompletion, NoCompletion}}, + "help": StrCommand{"Help", []Completion{HelpCompletion, NoCompletion}}, } } @@ -175,6 +177,17 @@ func Set(args []string) { SetOptionAndSettings(option, value) } +func SetLocal(args []string) { + if len(args) < 2 { + return + } + + option := strings.TrimSpace(args[0]) + value := strings.TrimSpace(args[1]) + + SetLocalOption(option, value, CurView()) +} + // Bind creates a new keybinding func Bind(args []string) { if len(args) != 2 { @@ -259,7 +272,7 @@ func Replace(args []string) { // The 'check' flag was used Search(search, view, true) view.Relocate() - if settings["syntax"].(bool) { + if view.Buf.Settings["syntax"].(bool) { view.matches = Match(view) } RedrawAll() diff --git a/cmd/micro/cursor.go b/cmd/micro/cursor.go index 69027410..cd1a1657 100644 --- a/cmd/micro/cursor.go +++ b/cmd/micro/cursor.go @@ -294,12 +294,12 @@ func (c *Cursor) Start() { // GetCharPosInLine gets the char position of a visual x y coordinate (this is necessary because tabs are 1 char but 4 visual spaces) func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int { // Get the tab size - tabSize := int(settings["tabsize"].(float64)) - visualLineLen := StringWidth(c.buf.Line(lineNum)) + tabSize := int(c.buf.Settings["tabsize"].(float64)) + visualLineLen := StringWidth(c.buf.Line(lineNum), tabSize) if visualPos > visualLineLen { visualPos = visualLineLen } - width := WidthOfLargeRunes(c.buf.Line(lineNum)) + width := WidthOfLargeRunes(c.buf.Line(lineNum), tabSize) if visualPos >= width { return visualPos - width } @@ -309,7 +309,8 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int { // GetVisualX returns the x value of the cursor in visual spaces func (c *Cursor) GetVisualX() int { runes := []rune(c.buf.Line(c.Y)) - return StringWidth(string(runes[:c.X])) + tabSize := int(c.buf.Settings["tabsize"].(float64)) + return StringWidth(string(runes[:c.X]), tabSize) } // Relocate makes sure that the cursor is inside the bounds of the buffer diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index b7eae904..e46bf41e 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -248,6 +248,14 @@ func main() { tab := NewTabFromView(NewView(buf)) tab.SetNum(len(tabs)) tabs = append(tabs, tab) + for _, t := range tabs { + for _, v := range t.views { + v.Center(false) + if globalSettings["syntax"].(bool) { + v.matches = Match(v) + } + } + } } // Load all the plugin stuff @@ -258,7 +266,7 @@ func main() { L.SetGlobal("messenger", luar.New(L, messenger)) L.SetGlobal("GetOption", luar.New(L, GetOption)) L.SetGlobal("AddOption", luar.New(L, AddOption)) - L.SetGlobal("SetOption", luar.New(L, SetOption)) + L.SetGlobal("SetOption", luar.New(L, SetGlobalOption)) L.SetGlobal("BindKey", luar.New(L, BindKey)) L.SetGlobal("MakeCommand", luar.New(L, MakeCommand)) L.SetGlobal("CurView", luar.New(L, CurView)) @@ -283,7 +291,7 @@ func main() { if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") { TermMessage(err) } - if settings["syntax"].(bool) { + if v.Buf.Settings["syntax"].(bool) { v.matches = Match(v) } } diff --git a/cmd/micro/search.go b/cmd/micro/search.go index a0233c4a..f7fa8e82 100644 --- a/cmd/micro/search.go +++ b/cmd/micro/search.go @@ -90,7 +90,7 @@ func Search(searchStr string, v *View, down bool) { str = string([]rune(text)[:searchStart]) } r, err := regexp.Compile(searchStr) - if settings["ignorecase"].(bool) { + if v.Buf.Settings["ignorecase"].(bool) { r, err = regexp.Compile("(?i)" + searchStr) } if err != nil { diff --git a/cmd/micro/settings.go b/cmd/micro/settings.go index 5c278ae1..e08c49b9 100644 --- a/cmd/micro/settings.go +++ b/cmd/micro/settings.go @@ -10,7 +10,7 @@ import ( ) // The options that the user can set -var settings map[string]interface{} +var globalSettings map[string]interface{} // InitSettings initializes the options map and sets all options to their default values func InitSettings() { @@ -31,12 +31,12 @@ func InitSettings() { } } - settings = make(map[string]interface{}) + globalSettings = make(map[string]interface{}) for k, v := range defaults { - settings[k] = v + globalSettings[k] = v } for k, v := range parsed { - settings[k] = v + globalSettings[k] = v } err := WriteSettings(filename) @@ -49,7 +49,7 @@ func InitSettings() { func WriteSettings(filename string) error { var err error if _, e := os.Stat(configDir); e == nil { - txt, _ := json.MarshalIndent(settings, "", " ") + txt, _ := json.MarshalIndent(globalSettings, "", " ") err = ioutil.WriteFile(filename, txt, 0644) } return err @@ -57,7 +57,7 @@ func WriteSettings(filename string) error { // AddOption creates a new option. This is meant to be called by plugins to add options. func AddOption(name string, value interface{}) { - settings[name] = value + globalSettings[name] = value err := WriteSettings(configDir + "/settings.json") if err != nil { TermMessage("Error writing settings.json file: " + err.Error()) @@ -65,8 +65,19 @@ func AddOption(name string, value interface{}) { } // GetOption returns the specified option. This is meant to be called by plugins to add options. +func GetGlobalOption(name string) interface{} { + return globalSettings[name] +} + +func GetLocalOption(name string, buf *Buffer) interface{} { + return buf.Settings[name] +} + func GetOption(name string) interface{} { - return settings[name] + if GetLocalOption(name, CurView().Buf) != nil { + return GetLocalOption(name, CurView().Buf) + } + return GetGlobalOption(name) } // DefaultSettings returns the default settings for micro @@ -90,48 +101,72 @@ func DefaultSettings() map[string]interface{} { } // SetOption attempts to set the given option to the value -func SetOption(option, value string) error { - if _, ok := settings[option]; !ok { +func SetGlobalOption(option, value string) error { + if _, ok := globalSettings[option]; !ok { return errors.New("Invalid option") } - kind := reflect.TypeOf(settings[option]).Kind() + kind := reflect.TypeOf(globalSettings[option]).Kind() if kind == reflect.Bool { b, err := ParseBool(value) if err != nil { return errors.New("Invalid value") } - settings[option] = b + globalSettings[option] = b } else if kind == reflect.String { - settings[option] = value + globalSettings[option] = value } else if kind == reflect.Float64 { i, err := strconv.Atoi(value) if err != nil { return errors.New("Invalid value") } - settings[option] = float64(i) + globalSettings[option] = float64(i) + } + + for _, tab := range tabs { + for _, view := range tab.views { + SetLocalOption(option, value, view) + } + } + + return nil +} + +func SetLocalOption(option, value string, view *View) error { + buf := view.Buf + if _, ok := buf.Settings[option]; !ok { + return errors.New("Invalid option") + } + + kind := reflect.TypeOf(buf.Settings[option]).Kind() + if kind == reflect.Bool { + b, err := ParseBool(value) + if err != nil { + return errors.New("Invalid value") + } + buf.Settings[option] = b + } else if kind == reflect.String { + buf.Settings[option] = value + } else if kind == reflect.Float64 { + i, err := strconv.Atoi(value) + if err != nil { + return errors.New("Invalid value") + } + buf.Settings[option] = float64(i) } if option == "colorscheme" { LoadSyntaxFiles() - for _, tab := range tabs { - for _, view := range tab.views { - view.Buf.UpdateRules() - if settings["syntax"].(bool) { - view.matches = Match(view) - } - } + buf.UpdateRules() + if buf.Settings["syntax"].(bool) { + view.matches = Match(view) } } if option == "statusline" { - for _, tab := range tabs { - for _, view := range tab.views { - view.ToggleStatusLine() - if settings["syntax"].(bool) { - view.matches = Match(view) - } - } + view.ToggleStatusLine() + if buf.Settings["syntax"].(bool) { + view.matches = Match(view) } } @@ -142,7 +177,7 @@ func SetOption(option, value string) error { func SetOptionAndSettings(option, value string) { filename := configDir + "/settings.json" - err := SetOption(option, value) + err := SetGlobalOption(option, value) if err != nil { messenger.Message(err.Error()) diff --git a/cmd/micro/split_tree.go b/cmd/micro/split_tree.go index b1656372..223e1c96 100644 --- a/cmd/micro/split_tree.go +++ b/cmd/micro/split_tree.go @@ -148,7 +148,7 @@ func (s *SplitTree) ResizeSplits() { } // n.view.ToggleStatusLine() _, screenH := screen.Size() - if settings["statusline"].(bool) || (n.view.y+n.view.height) != screenH-1 { + if n.view.Buf.Settings["statusline"].(bool) || (n.view.y+n.view.height) != screenH-1 { n.view.height-- } diff --git a/cmd/micro/util.go b/cmd/micro/util.go index c477c41e..3a1cb4bb 100644 --- a/cmd/micro/util.go +++ b/cmd/micro/util.go @@ -152,20 +152,20 @@ func GetModTime(path string) (time.Time, bool) { } // StringWidth returns the width of a string where tabs count as `tabsize` width -func StringWidth(str string) int { +func StringWidth(str string, tabsize int) int { sw := runewidth.StringWidth(str) - sw += NumOccurences(str, '\t') * (int(settings["tabsize"].(float64)) - 1) + sw += NumOccurences(str, '\t') * (tabsize - 1) return sw } // WidthOfLargeRunes searches all the runes in a string and counts up all the widths of runes // that have a width larger than 1 (this also counts tabs as `tabsize` width) -func WidthOfLargeRunes(str string) int { +func WidthOfLargeRunes(str string, tabsize int) int { count := 0 for _, ch := range str { var w int if ch == '\t' { - w = int(settings["tabsize"].(float64)) + w = tabsize } else { w = runewidth.RuneWidth(ch) } diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 7dc57413..755912dc 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -107,7 +107,7 @@ func NewViewWidthHeight(buf *Buffer, w, h int) *View { view: v, } - if settings["statusline"].(bool) { + if v.Buf.Settings["statusline"].(bool) { v.height-- } @@ -115,7 +115,7 @@ func NewViewWidthHeight(buf *Buffer, w, h int) *View { } func (v *View) ToggleStatusLine() { - if settings["statusline"].(bool) { + if v.Buf.Settings["statusline"].(bool) { v.height-- } else { v.height++ @@ -236,7 +236,7 @@ func (v *View) VSplit(buf *Buffer) bool { func (v *View) Relocate() bool { ret := false cy := v.Cursor.Y - scrollmargin := int(settings["scrollmargin"].(float64)) + scrollmargin := int(v.Buf.Settings["scrollmargin"].(float64)) if cy < v.Topline+scrollmargin && cy > scrollmargin-1 { v.Topline = cy - scrollmargin ret = true @@ -408,11 +408,11 @@ func (v *View) HandleEvent(event tcell.Event) { } case tcell.WheelUp: // Scroll up - scrollspeed := int(settings["scrollspeed"].(float64)) + scrollspeed := int(v.Buf.Settings["scrollspeed"].(float64)) v.ScrollUp(scrollspeed) case tcell.WheelDown: // Scroll down - scrollspeed := int(settings["scrollspeed"].(float64)) + scrollspeed := int(v.Buf.Settings["scrollspeed"].(float64)) v.ScrollDown(scrollspeed) } } @@ -420,7 +420,7 @@ func (v *View) HandleEvent(event tcell.Event) { if relocate { v.Relocate() } - if settings["syntax"].(bool) { + if v.Buf.Settings["syntax"].(bool) { v.matches = Match(v) } } @@ -486,7 +486,7 @@ func (v *View) DisplayView() { // We are going to have to offset by that amount maxLineLength := len(strconv.Itoa(v.Buf.NumLines)) - if settings["ruler"] == true { + if v.Buf.Settings["ruler"] == true { // + 1 for the little space after the line number v.lineNumOffset = maxLineLength + 1 } else { @@ -585,7 +585,7 @@ func (v *View) DisplayView() { } } - if settings["ruler"] == true { + if v.Buf.Settings["ruler"] == true { // Write the line number lineNumStyle := defStyle if style, ok := colorscheme["line-number"]; ok { @@ -620,7 +620,7 @@ func (v *View) DisplayView() { for _, ch := range line { lineStyle := defStyle - if settings["syntax"].(bool) { + if v.Buf.Settings["syntax"].(bool) { // Syntax highlighting is enabled highlightStyle = v.matches[viewLine][colN] } @@ -640,7 +640,7 @@ func (v *View) DisplayView() { // We need to display the background of the linestyle with the correct color if cursorline is enabled // and this is the current view and there is no selection on this line and the cursor is on this line - if settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN { + if v.Buf.Settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN { if style, ok := colorscheme["cursor-line"]; ok { fg, _, _ := style.Decompose() lineStyle = lineStyle.Background(fg) @@ -666,19 +666,19 @@ func (v *View) DisplayView() { lineIndentStyle = style } } - if settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN { + if v.Buf.Settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN { if style, ok := colorscheme["cursor-line"]; ok { fg, _, _ := style.Decompose() lineIndentStyle = lineIndentStyle.Background(fg) } } // Here we get the indent char - indentChar := []rune(settings["indentchar"].(string)) + indentChar := []rune(v.Buf.Settings["indentchar"].(string)) if screenX-v.x-v.leftCol >= v.lineNumOffset { v.drawCell(screenX-v.leftCol, screenY, indentChar[0], nil, lineIndentStyle) } // Now the tab has to be displayed as a bunch of spaces - tabSize := int(settings["tabsize"].(float64)) + tabSize := int(v.Buf.Settings["tabsize"].(float64)) for i := 0; i < tabSize-1; i++ { screenX++ if screenX-v.x-v.leftCol >= v.lineNumOffset { @@ -725,7 +725,7 @@ func (v *View) DisplayView() { for i := 0; i < v.width; i++ { lineStyle := defStyle - if settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN { + if v.Buf.Settings["cursorline"].(bool) && tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN { if style, ok := colorscheme["cursor-line"]; ok { fg, _, _ := style.Decompose() lineStyle = lineStyle.Background(fg) @@ -755,7 +755,7 @@ func (v *View) Display() { v.DisplayCursor() } _, screenH := screen.Size() - if settings["statusline"].(bool) { + if v.Buf.Settings["statusline"].(bool) { v.sline.Display() } else if (v.y + v.height) != screenH-1 { for x := 0; x < v.width; x++ {