package document import ( "bufio" "log" "os" "timshome.page/gilo/internal/gilo" ) type Document struct { dirty bool Filename string rows []*Row } func NewDocument() *Document { var rows []*Row return &Document{ false, "", rows, } } func (d *Document) Open(filename string) { file, err := os.Open(filename) if err != nil { log.Fatalf("failed to open file") } defer file.Close() d.Filename = filename scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) for scanner.Scan() { d.AppendRow(scanner.Text()) } d.dirty = false } func (d *Document) Save() int { if d.Filename == "" { return 0 } file, err := os.OpenFile(d.Filename, os.O_RDWR|os.O_CREATE, 0644) if err != nil { panic("failed to open/create file for saving") } defer file.Close() fileStr := d.ToString() fileLen := len(fileStr) err = file.Truncate(int64(fileLen)) if err != nil { panic("failed to truncate file") } size, err := file.WriteString(fileStr) if err != nil { panic("failed to save Document to file") } if fileLen == size { return size } d.dirty = false return 0 } func (d *Document) Row(at int) *Row { return d.rows[at] } func (d *Document) AppendRow(s string) { newRow := newRow(s) newRow.update() d.rows = append(d.rows, newRow) d.dirty = true } func (d *Document) ToString() string { buf := gilo.NewBuffer() for _, row := range d.rows { buf.Append(row.toString()) buf.AppendRune('\n') } return buf.ToString() } func (d *Document) RowCount() int { return len(d.rows) } func (d *Document) InsertChar(at *gilo.Point, ch rune) { d.rows[at.Y].insertRune(ch, at.X) d.dirty = true } func (d *Document) DelChar(at *gilo.Point) { d.rows[at.Y].deleteRune(at.X) d.dirty = true } func (d *Document) IsDirty() bool { return d.dirty }