micro/src/buffer.go

94 lines
2.2 KiB
Go
Raw Normal View History

2016-03-18 00:27:57 +03:00
package main
import (
"io/ioutil"
"strings"
)
2016-03-19 03:40:00 +03:00
// Buffer stores the text for files that are loaded into the text editor
// It uses a rope to efficiently store the string and contains some
// simple functions for saving and wrapper functions for modifying the rope
2016-03-18 00:27:57 +03:00
type Buffer struct {
2016-03-19 03:40:00 +03:00
// Stores the text of the buffer
2016-03-18 00:27:57 +03:00
r *Rope
// Path to the file on disk
path string
// Name of the buffer on the status line
name string
2016-03-19 16:24:04 +03:00
// This is the text stored every time the buffer is saved to check if the buffer is modified
2016-03-18 00:27:57 +03:00
savedText string
2016-03-19 04:25:45 +03:00
// Provide efficient and easy access to text and lines so the rope String does not
2016-03-19 03:40:00 +03:00
// need to be constantly recalculated
// These variables are updated in the update() function
2016-03-18 00:27:57 +03:00
text string
lines []string
// Syntax highlighting rules
rules string
// File type of the buffer
filetype string
2016-03-18 00:27:57 +03:00
}
2016-03-19 03:40:00 +03:00
// NewBuffer creates a new buffer from `txt` with path and name `path`
func NewBuffer(txt, path string) *Buffer {
2016-03-18 00:27:57 +03:00
b := new(Buffer)
2016-03-19 04:25:45 +03:00
b.r = NewRope(txt)
2016-03-18 00:27:57 +03:00
b.path = path
b.name = path
b.savedText = txt
2016-03-19 03:40:00 +03:00
b.Update()
2016-03-18 00:27:57 +03:00
b.rules, b.filetype = GetRules(b)
2016-03-18 00:27:57 +03:00
return b
}
2016-03-19 03:40:00 +03:00
// Update fetches the string from the rope and updates the `text` and `lines` in the buffer
func (b *Buffer) Update() {
2016-03-19 04:25:45 +03:00
b.text = b.r.String()
2016-03-18 00:27:57 +03:00
b.lines = strings.Split(b.text, "\n")
}
2016-03-19 03:40:00 +03:00
// Save saves the buffer to its default path
func (b *Buffer) Save() error {
return b.SaveAs(b.path)
2016-03-18 00:27:57 +03:00
}
2016-03-19 03:40:00 +03:00
// SaveAs saves the buffer to a specified path (filename), creating the file if it does not exist
func (b *Buffer) SaveAs(filename string) error {
2016-03-18 00:27:57 +03:00
err := ioutil.WriteFile(filename, []byte(b.text), 0644)
2016-03-23 17:28:12 +03:00
if err == nil {
b.savedText = b.text
}
2016-03-18 00:27:57 +03:00
return err
}
2016-03-23 18:41:04 +03:00
// IsDirty returns whether or not the buffer has been modified compared to the one on disk
func (b *Buffer) IsDirty() bool {
return b.savedText != b.text
}
2016-03-19 03:40:00 +03:00
// Insert a string into the rope
func (b *Buffer) Insert(idx int, value string) {
2016-03-19 04:25:45 +03:00
b.r.Insert(idx, value)
2016-03-19 03:40:00 +03:00
b.Update()
2016-03-18 00:27:57 +03:00
}
2016-03-19 03:40:00 +03:00
// Remove a slice of the rope from start to end (exclusive)
2016-03-20 01:16:10 +03:00
// Returns the string that was removed
func (b *Buffer) Remove(start, end int) string {
removed := b.text[start:end]
2016-03-19 04:25:45 +03:00
b.r.Remove(start, end)
2016-03-19 03:40:00 +03:00
b.Update()
2016-03-20 01:16:10 +03:00
return removed
2016-03-18 00:27:57 +03:00
}
2016-03-19 03:40:00 +03:00
// Len gives the length of the buffer
func (b *Buffer) Len() int {
2016-03-18 00:27:57 +03:00
return b.r.len
}