5 "github.com/vinzmay/go-rope"
10 // Buffer stores the text for files that are loaded into the text editor
11 // It uses a rope to efficiently store the string and contains some
12 // simple functions for saving and wrapper functions for modifying the rope
14 // Stores the text of the buffer
17 // Path to the file on disk
19 // Name of the buffer on the status line
22 // This is the text stored every time the buffer is saved to check if the buffer is modified
25 dirtySinceLastCheck bool
27 // Provide efficient and easy access to text and lines so the rope String does not
28 // need to be constantly recalculated
29 // These variables are updated in the update() function
33 // Syntax highlighting rules
35 // The buffer's filetype
39 // NewBuffer creates a new buffer from `txt` with path and name `path`
40 func NewBuffer(txt, path string) *Buffer {
49 b.savedText = md5.Sum([]byte(txt))
57 // UpdateRules updates the syntax rules and filetype for this buffer
58 // This is called when the colorscheme changes
59 func (b *Buffer) UpdateRules() {
60 b.rules, b.Filetype = GetRules(b)
63 func (b *Buffer) String() string {
70 // Update fetches the string from the rope and updates the `text` and `lines` in the buffer
71 func (b *Buffer) Update() {
72 b.Lines = strings.Split(b.String(), "\n")
73 b.NumLines = len(b.Lines)
76 // Save saves the buffer to its default path
77 func (b *Buffer) Save() error {
78 return b.SaveAs(b.Path)
81 // SaveAs saves the buffer to a specified path (filename), creating the file if it does not exist
82 func (b *Buffer) SaveAs(filename string) error {
84 data := []byte(b.String())
85 err := ioutil.WriteFile(filename, data, 0644)
87 b.savedText = md5.Sum(data)
93 // IsDirty returns whether or not the buffer has been modified compared to the one on disk
94 func (b *Buffer) IsDirty() bool {
95 if !b.dirtySinceLastCheck {
98 if b.netInsertions == 0 {
99 isDirty := b.savedText != md5.Sum([]byte(b.String()))
100 b.dirtySinceLastCheck = isDirty
106 // Insert a string into the rope
107 func (b *Buffer) Insert(idx int, value string) {
108 b.dirtySinceLastCheck = true
109 b.netInsertions += len(value)
110 b.r = b.r.Insert(idx, value)
114 // Remove a slice of the rope from start to end (exclusive)
115 // Returns the string that was removed
116 func (b *Buffer) Remove(start, end int) string {
117 b.dirtySinceLastCheck = true
118 b.netInsertions -= end - start
125 removed := b.Substr(start, end)
126 // The rope implenentation I am using wants indicies starting at 1 instead of 0
129 b.r = b.r.Delete(start, end-start)
134 func (b *Buffer) Substr(start, end int) string {
135 return b.r.Substr(start+1, end-start).String()
138 // Len gives the length of the buffer
139 func (b *Buffer) Len() int {