X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Fbuffer.go;h=fdcc37ad2d43cf3f8e71773c43d749b174f48165;hb=d49e366413dc8956f6b62734a6331df6632672fe;hp=b6fd672b28424bcef542a78d4086d38bf7a201dd;hpb=4c0b00bf2b19912eef1109b21a3f21b981f059e6;p=micro.git diff --git a/cmd/micro/buffer.go b/cmd/micro/buffer.go index b6fd672b..fdcc37ad 100644 --- a/cmd/micro/buffer.go +++ b/cmd/micro/buffer.go @@ -3,15 +3,19 @@ package main import ( "bytes" "encoding/gob" + "io" "io/ioutil" "os" "os/exec" "os/signal" "path/filepath" + "regexp" "strconv" "strings" "time" "unicode/utf8" + + "github.com/mitchellh/go-homedir" ) // Buffer stores the text for files that are loaded into the text editor @@ -27,8 +31,10 @@ type Buffer struct { // Path to the file on disk Path string + // Absolute path to the file on disk + AbsPath string // Name of the buffer on the status line - Name string + name string // Whether or not the buffer has been modified since it was opened IsModified bool @@ -53,8 +59,12 @@ type SerializedBuffer struct { ModTime time.Time } -// NewBuffer creates a new buffer from `txt` with path and name `path` -func NewBuffer(txt []byte, path string) *Buffer { +func NewBufferFromString(text, path string) *Buffer { + return NewBuffer(strings.NewReader(text), path) +} + +// NewBuffer creates a new buffer from a given reader with a given path +func NewBuffer(reader io.Reader, path string) *Buffer { if path != "" { for _, tab := range tabs { for _, view := range tab.views { @@ -66,7 +76,7 @@ func NewBuffer(txt []byte, path string) *Buffer { } b := new(Buffer) - b.LineArray = NewLineArray(txt) + b.LineArray = NewLineArray(reader) b.Settings = DefaultLocalSettings() for k, v := range globalSettings { @@ -75,13 +85,10 @@ func NewBuffer(txt []byte, path string) *Buffer { } } - b.Path = path - b.Name = path + absPath, _ := filepath.Abs(path) - // If the file doesn't have a path to disk then we give it no name - if path == "" { - b.Name = "No name" - } + b.Path = path + b.AbsPath = absPath // The last time this file was modified b.ModTime, _ = GetModTime(b.Path) @@ -136,8 +143,7 @@ func NewBuffer(txt []byte, path string) *Buffer { 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) - file, err := os.Open(configDir + "/buffers/" + EscapePath(absPath)) + file, err := os.Open(configDir + "/buffers/" + EscapePath(b.AbsPath)) if err == nil { var buffer SerializedBuffer decoder := gob.NewDecoder(file) @@ -166,6 +172,16 @@ func NewBuffer(txt []byte, path string) *Buffer { return b } +func (b *Buffer) GetName() string { + if b.name == "" { + if b.Path == "" { + return "No name" + } + return b.Path + } + return b.name +} + // UpdateRules updates the syntax rules and filetype for this buffer // This is called when the colorscheme changes func (b *Buffer) UpdateRules() { @@ -246,8 +262,7 @@ func (b *Buffer) SaveWithSudo() error { // Serialize serializes the buffer to configDir/buffers func (b *Buffer) Serialize() error { if b.Settings["savecursor"].(bool) || b.Settings["saveundo"].(bool) { - absPath, _ := filepath.Abs(b.Path) - file, err := os.Create(configDir + "/buffers/" + EscapePath(absPath)) + file, err := os.Create(configDir + "/buffers/" + EscapePath(b.AbsPath)) if err == nil { enc := gob.NewEncoder(file) gob.Register(TextEvent{}) @@ -267,15 +282,27 @@ func (b *Buffer) Serialize() error { func (b *Buffer) SaveAs(filename string) error { b.FindFileType() b.UpdateRules() - b.Name = filename - b.Path = filename - str := b.String() + dir, _ := homedir.Dir() + b.Path = strings.Replace(filename, "~", dir, 1) + if b.Settings["rmtrailingws"].(bool) { + r, _ := regexp.Compile(`[ \t]+$`) + for lineNum, line := range b.Lines(0, b.NumLines) { + indices := r.FindStringIndex(line) + if indices == nil { + continue + } + startLoc := Loc{indices[0], lineNum} + b.deleteToEnd(startLoc) + } + b.Cursor.Relocate() + } if b.Settings["eofnewline"].(bool) { end := b.End() if b.RuneAt(Loc{end.X - 1, end.Y}) != '\n' { b.Insert(end, "\n") } } + str := b.String() data := []byte(str) err := ioutil.WriteFile(filename, data, 0644) if err == nil { @@ -292,7 +319,6 @@ func (b *Buffer) SaveAs(filename string) error { func (b *Buffer) SaveAsWithSudo(filename string) error { b.FindFileType() b.UpdateRules() - b.Name = filename b.Path = filename // The user may have already used sudo in which case we won't need the password @@ -349,6 +375,11 @@ func (b *Buffer) remove(start, end Loc) string { b.Update() return sub } +func (b *Buffer) deleteToEnd(start Loc) { + b.IsModified = true + b.LineArray.DeleteToEnd(start) + b.Update() +} // Start returns the location of the first character in the buffer func (b *Buffer) Start() Loc {