package acedoc import ( "strings" "sync" ) type Document struct { mtx sync.RWMutex Lines []string } func NewString(str string) *Document { d := &Document{ Lines: strings.Split(str, "\n"), } return d } func (d *Document) NLines() uint { n := uint(len(d.Lines)) if n == 0 { n = 1 } return n } func (d Delta) NLines() uint { n := uint(len(d.Lines)) if n == 0 { n = 1 } return n } func (d Document) Line(i uint) string { if i >= uint(len(d.Lines)) { return "" } return d.Lines[i] } func (d Delta) Line(i uint) string { if i >= uint(len(d.Lines)) { return "" } return d.Lines[i] } func (d Delta) NRows() uint { r := d.End.Row - d.Start.Row r += 1 if r == 0 { return 1 } return r } func (d Delta) Rows() uint { r := d.End.Row - d.Start.Row return r } func (d Delta) Cols() uint { r := d.End.Column return r } func (d *Document) Contents() string { d.mtx.RLock() defer d.mtx.RUnlock() return strings.Join(d.Lines, "\n") } type Position struct { Row, Column uint } func (d *Document) InDocument(pos Position) bool { if pos.Row > d.NLines() { return false } line := d.Line(pos.Row) if pos.Column > uint(len(line)) { return false } return true }