You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							112 lines
						
					
					
						
							1.6 KiB
						
					
					
				
			
		
		
	
	
							112 lines
						
					
					
						
							1.6 KiB
						
					
					
				package acedoc
 | 
						|
 | 
						|
import (
 | 
						|
	"strings"
 | 
						|
	"sync"
 | 
						|
)
 | 
						|
 | 
						|
type Document struct {
 | 
						|
	mtx     sync.RWMutex
 | 
						|
	lines   []string
 | 
						|
	deltas  []Delta
 | 
						|
	clients []*Client
 | 
						|
 | 
						|
	logger *Client
 | 
						|
}
 | 
						|
 | 
						|
type DeltaHandler interface {
 | 
						|
	Handle([]Delta) error
 | 
						|
}
 | 
						|
 | 
						|
type DeltaHandlerFunc func([]Delta) error
 | 
						|
 | 
						|
func (fn DeltaHandlerFunc) Handle(d []Delta) error {
 | 
						|
	return fn(d)
 | 
						|
}
 | 
						|
 | 
						|
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() int {
 | 
						|
	r := int(d.End.Row) - int(d.Start.Row)
 | 
						|
	return r
 | 
						|
}
 | 
						|
 | 
						|
func (d Delta) cols() int {
 | 
						|
	if d.Start.Row == d.End.Row {
 | 
						|
		return int(d.End.Column) - int(d.Start.Column)
 | 
						|
	} else {
 | 
						|
		return int(d.End.Column)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (d *Document) Contents() string {
 | 
						|
	d.mtx.RLock()
 | 
						|
	defer d.mtx.RUnlock()
 | 
						|
 | 
						|
	return d.contents()
 | 
						|
}
 | 
						|
 | 
						|
func (d *Document) contents() string {
 | 
						|
	return strings.Join(d.lines, "\n")
 | 
						|
}
 | 
						|
 | 
						|
type Position struct {
 | 
						|
	Row    uint `json:"row"`
 | 
						|
	Column uint `json:"column"`
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
}
 | 
						|
 |