-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfile.go
75 lines (66 loc) · 1.86 KB
/
file.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main
import (
"os"
"strings"
)
type cursor struct {
first int
second int
dot int // current address
addrc int // address count
}
type file struct {
dirty bool // modified state
lines []string // file content
mark ['z' - 'a']int // a to z
path string // full file path to the file
}
func (f *file) append(dest int, lines []string) {
f.lines = append(f.lines[:dest], append(lines, f.lines[dest:]...)...)
}
func (f *file) yank(start, end, dest int) int {
buf := make([]string, end-start+1)
copy(buf, f.lines[start-1:end])
f.lines = append(f.lines[:dest], append(buf, f.lines[dest:]...)...)
return len(buf)
}
func (f *file) delete(start, end int) {
f.lines = append(f.lines[:start-1], f.lines[end:]...)
}
func (f *file) join(start, end int) {
buf := strings.Join(f.lines[start-1:end], "")
f.lines = append(append(append([]string{}, f.lines[:start-1]...), buf), f.lines[end:]...)
}
func (f *file) move(start, end, dest int) int {
buf := make([]string, end-start+1)
copy(buf, f.lines[start-1:end])
f.lines = append(f.lines[:start-1], f.lines[end:]...) // remove the lines
if dest > start {
dest -= (end - start + 1)
}
f.lines = append(f.lines[:dest], append(buf, f.lines[dest:]...)...)
return dest + (end - start + 1)
}
func (f *file) write(path string, r rune, start, end int) (int, error) {
perms := os.O_CREATE | os.O_RDWR | os.O_TRUNC
if r == 'W' {
perms = perms&^os.O_TRUNC | os.O_APPEND
}
file, err := os.OpenFile(path, perms, 0666)
if err != nil {
return -1, ErrCannotOpenFile
}
start = max(start-1, 0)
lastline := ""
if len(f.lines) > 0 && f.lines[end-1] != "" {
lastline = "\n"
}
size, err := file.WriteString(strings.Join(f.lines[start:end], "\n") + lastline)
if err != nil {
return -1, ErrCannotWriteFile
}
if err := file.Close(); err != nil {
return -1, ErrCannotCloseFile
}
return size, nil
}