mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
80 lines
1.5 KiB
Go
80 lines
1.5 KiB
Go
package peco
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/google/btree"
|
|
"github.com/peco/peco/line"
|
|
)
|
|
|
|
// Selection stores the line ids that were selected by the user.
|
|
// The contents of the Selection is always sorted from smallest to
|
|
// largest line ID
|
|
type Selection struct {
|
|
mutex sync.RWMutex
|
|
tree *btree.BTree
|
|
}
|
|
|
|
// RangeStart tracks the starting position of a range selection.
|
|
type RangeStart struct {
|
|
val int
|
|
valid bool
|
|
}
|
|
|
|
// NewSelection creates a new empty Selection
|
|
func NewSelection() *Selection {
|
|
s := &Selection{}
|
|
s.Reset()
|
|
return s
|
|
}
|
|
|
|
// Add adds a new line to the selection. If the line already
|
|
// exists in the selection, it is silently ignored
|
|
func (s *Selection) Add(l line.Line) {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
s.tree.ReplaceOrInsert(l)
|
|
}
|
|
|
|
func (s *Selection) Copy(dst *Selection) {
|
|
s.Ascend(func(it btree.Item) bool {
|
|
l, ok := it.(line.Line)
|
|
if !ok {
|
|
return true
|
|
}
|
|
dst.Add(l)
|
|
return true
|
|
})
|
|
}
|
|
|
|
// Remove removes the specified line from the selection
|
|
func (s *Selection) Remove(l line.Line) {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
s.tree.Delete(l)
|
|
}
|
|
|
|
func (s *Selection) Reset() {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
s.tree = btree.New(32)
|
|
}
|
|
|
|
func (s *Selection) Has(x line.Line) bool {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
return s.tree.Has(x)
|
|
}
|
|
|
|
func (s *Selection) Len() int {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
return s.tree.Len()
|
|
}
|
|
|
|
func (s *Selection) Ascend(i btree.ItemIterator) {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
s.tree.Ascend(i)
|
|
}
|