10 "github.com/vinzmay/go-rope"
13 // Buffer stores the text for files that are loaded into the text editor
14 // It uses a rope to efficiently store the string and contains some
15 // simple functions for saving and wrapper functions for modifying the rope
17 // The eventhandler for undo/redo
20 // Stores the text of the buffer
25 // Path to the file on disk
27 // Name of the buffer on the status line
32 // Provide efficient and easy access to text and lines so the rope String does not
33 // need to be constantly recalculated
34 // These variables are updated in the update() function
38 // Syntax highlighting rules
40 // The buffer's filetype
44 // NewBuffer creates a new buffer from `txt` with path and name `path`
45 func NewBuffer(txt, path string) *Buffer {
55 b.EventHandler = NewEventHandler(b)
60 if _, err := os.Stat(configDir + "/buffers/"); os.IsNotExist(err) {
61 os.Mkdir(configDir+"/buffers/", os.ModePerm)
64 if settings["savecursor"].(bool) {
65 absPath, _ := filepath.Abs(b.Path)
66 file, err := os.Open(configDir + "/buffers/" + EscapePath(absPath))
69 decoder := gob.NewDecoder(file)
70 err = decoder.Decode(&cursor)
72 TermMessage(err.Error())
78 // Put the cursor at the first spot
87 // Put the cursor at the first spot
98 // UpdateRules updates the syntax rules and filetype for this buffer
99 // This is called when the colorscheme changes
100 func (b *Buffer) UpdateRules() {
101 b.rules, b.FileType = GetRules(b)
104 func (b *Buffer) String() string {
111 // Update fetches the string from the rope and updates the `text` and `lines` in the buffer
112 func (b *Buffer) Update() {
113 b.Lines = strings.Split(b.String(), "\n")
114 b.NumLines = len(b.Lines)
117 // Save saves the buffer to its default path
118 func (b *Buffer) Save() error {
119 return b.SaveAs(b.Path)
122 // Serialize serializes the buffer to configDir/buffers
123 func (b *Buffer) Serialize() error {
124 if settings["savecursor"].(bool) {
125 absPath, _ := filepath.Abs(b.Path)
126 file, err := os.Create(configDir + "/buffers/" + EscapePath(absPath))
128 enc := gob.NewEncoder(file)
129 err = enc.Encode(b.Cursor)
137 // SaveAs saves the buffer to a specified path (filename), creating the file if it does not exist
138 func (b *Buffer) SaveAs(filename string) error {
140 data := []byte(b.String())
141 err := ioutil.WriteFile(filename, data, 0644)
149 // This directly inserts value at idx, bypassing all undo/redo
150 func (b *Buffer) insert(idx int, value string) {
152 b.r = b.r.Insert(idx, value)
156 // Remove a slice of the rope from start to end (exclusive)
157 // Returns the string that was removed
158 // This directly removes from start to end from the buffer, bypassing all undo/redo
159 func (b *Buffer) remove(start, end int) string {
170 removed := b.Substr(start, end)
171 // The rope implenentation I am using wants indicies starting at 1 instead of 0
174 b.r = b.r.Delete(start, end-start)
179 // Substr returns the substring of the rope from start to end
180 func (b *Buffer) Substr(start, end int) string {
181 return b.r.Substr(start+1, end-start).String()
184 // Len gives the length of the buffer
185 func (b *Buffer) Len() int {