<commit_before>package peco

import (
	"io"
	"sync"
	"time"
)

func (c *Ctx) CaretPos() int {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	return c.caretPosition
}

func (c *Ctx) SetCaretPos(where int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = where
}

func (c *Ctx) MoveCaretPos(offset int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = c.caretPosition + offset
}

func (q FilterQuery) Query() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.query[:]
}

func (q FilterQuery) SavedQuery() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.savedQuery[:]
}

func (q FilterQuery) QueryString() string {
	qbytes := q.Query()
	return string(qbytes)
}

func (q FilterQuery) QueryLen() int {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return len(q.query)
}

func (q *FilterQuery) AppendQuery(r rune) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.query = append(q.query, r)
}

func (q *FilterQuery) InsertQueryAt(ch rune, where int) {
	q.mutex.Lock()
	defer q.mutex.Unlock()

	sq := q.query
	buf := make([]rune, len(sq)+1)
	copy(buf, sq[:where])
	buf[where] = ch
	copy(buf[where+1:], sq[where:])
	q.query = buf
}

func NewCtx(o CtxOptions) *Ctx {
	return newCtx(o, 5)
}

func newCtx(o CtxOptions, hubBufferSize int) *Ctx {
	c := &Ctx{
		Hub:                 NewHub(hubBufferSize),
		FilterQuery:         &FilterQuery{[]rune{}, []rune{}, newMutex()},
		filters:             FilterSet{},
		caretPosition:       0,
		resultCh:            nil,
		mutex:               newMutex(),
		currentCol:          0,
		currentPage:         &PageInfo{},
		selection:           NewSelection(),
		activeLineBuffer:    nil,
		rawLineBuffer:       NewRawLineBuffer(),
		lines:               []Line{},
		linesMutex:          newMutex(),
		current:             nil,
		currentMutex:        newMutex(),
		config:              NewConfig(),
		selectionRangeStart: invalidSelectionRange,
		wait:                &sync.WaitGroup{},
		layoutType:          "top-down",
		singleKeyJumpMode:   false,
	}

	if o != nil {
		// XXX Pray this is really nil :)
		c.enableSep = o.EnableNullSep()
		c.currentLine = o.InitialIndex()

		c.rawLineBuffer.SetCapacity(o.BufferSize())

		if v := o.LayoutType(); v != "" {
			c.layoutType = v
		}
	}

	c.filters.Add(NewIgnoreCaseFilter())
	c.filters.Add(NewCaseSensitiveFilter())
	c.filters.Add(NewSmartCaseFilter())
	c.filters.Add(NewRegexpFilter())

	return c
}

const invalidSelectionRange = -1

func (c *Ctx) ReadConfig(file string) error {
	if err := c.config.ReadFilename(file); err != nil {
		return err
	}

	if err := c.LoadCustomFilter(); err != nil {
		return err
	}

	c.SetCurrentFilterByName(c.config.InitialFilter)

	if c.layoutType == "" { // Not set yet
		if c.config.Layout != "" {
			c.layoutType = c.config.Layout
		}
	}

	c.config.SingleKeyJumpMap = make(map[rune]uint)
	chrs := "asdfghjklzxcvbnmqwertyuiop"
	for i := 0; i < len(chrs); i++ {
		c.config.SingleKeyJumpMap[rune(chrs[i])] = uint(i)
	}
	c.config.SingleKeyJumpList = make([]rune, len(c.config.SingleKeyJumpMap))
	for k, v := range c.config.SingleKeyJumpMap {
		c.config.SingleKeyJumpList[v] = k
	}

	return nil
}

func (c *Ctx) IsRangeMode() bool {
	return c.selectionRangeStart != invalidSelectionRange
}

func (c *Ctx) SelectionLen() int {
	return c.selection.Len()
}

func (c *Ctx) SelectionAdd(x int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(x); err == nil {<commit_msg>Populate things at the right locations<commit_after>package peco

import (
	"io"
	"sync"
	"time"
)

func (c *Ctx) CaretPos() int {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	return c.caretPosition
}

func (c *Ctx) SetCaretPos(where int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = where
}

func (c *Ctx) MoveCaretPos(offset int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.caretPosition = c.caretPosition + offset
}

func (q FilterQuery) Query() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.query[:]
}

func (q FilterQuery) SavedQuery() []rune {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return q.savedQuery[:]
}

func (q FilterQuery) QueryString() string {
	qbytes := q.Query()
	return string(qbytes)
}

func (q FilterQuery) QueryLen() int {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	return len(q.query)
}

func (q *FilterQuery) AppendQuery(r rune) {
	q.mutex.Lock()
	defer q.mutex.Unlock()
	q.query = append(q.query, r)
}

func (q *FilterQuery) InsertQueryAt(ch rune, where int) {
	q.mutex.Lock()
	defer q.mutex.Unlock()

	sq := q.query
	buf := make([]rune, len(sq)+1)
	copy(buf, sq[:where])
	buf[where] = ch
	copy(buf[where+1:], sq[where:])
	q.query = buf
}

func NewCtx(o CtxOptions) *Ctx {
	return newCtx(o, 5)
}

func newCtx(o CtxOptions, hubBufferSize int) *Ctx {
	c := &Ctx{
		Hub:                 NewHub(hubBufferSize),
		FilterQuery:         &FilterQuery{[]rune{}, []rune{}, newMutex()},
		filters:             FilterSet{},
		caretPosition:       0,
		resultCh:            nil,
		mutex:               newMutex(),
		currentCol:          0,
		currentPage:         &PageInfo{},
		selection:           NewSelection(),
		activeLineBuffer:    nil,
		rawLineBuffer:       NewRawLineBuffer(),
		lines:               []Line{},
		linesMutex:          newMutex(),
		current:             nil,
		currentMutex:        newMutex(),
		config:              NewConfig(),
		selectionRangeStart: invalidSelectionRange,
		wait:                &sync.WaitGroup{},
		layoutType:          "top-down",
		singleKeyJumpMode:   false,
	}

	if o != nil {
		// XXX Pray this is really nil :)
		c.enableSep = o.EnableNullSep()
		c.currentLine = o.InitialIndex()

		c.rawLineBuffer.SetCapacity(o.BufferSize())

		if v := o.LayoutType(); v != "" {
			c.layoutType = v
		}
	}

	c.filters.Add(NewIgnoreCaseFilter())
	c.filters.Add(NewCaseSensitiveFilter())
	c.filters.Add(NewSmartCaseFilter())
	c.filters.Add(NewRegexpFilter())

	jumpMap := make(map[rune]uint)
	chrs := "<KEY>"
	for i := 0; i < len(chrs); i++ {
		jumpMap[rune(chrs[i])] = uint(i)
	}
	c.config.SingleKeyJumpMap = jumpMap
	c.populateSingleKeyJumpList()

	return c
}

func (c *Ctx) populateSingleKeyJumpList() {
	c.config.SingleKeyJumpList = make([]rune, len(c.config.SingleKeyJumpMap))
	for k, v := range c.config.SingleKeyJumpMap {
		c.config.SingleKeyJumpList[v] = k
	}
}

const invalidSelectionRange = -1

func (c *Ctx) ReadConfig(file string) error {
	if err := c.config.ReadFilename(file); err != nil {
		return err
	}

	if err := c.LoadCustomFilter(); err != nil {
		return err
	}

	c.SetCurrentFilterByName(c.config.InitialFilter)

	if c.layoutType == "" { // Not set yet
		if c.config.Layout != "" {
			c.layoutType = c.config.Layout
		}
	}

	c.populateSingleKeyJumpList()

	return nil
}

func (c *Ctx) IsRangeMode() bool {
	return c.selectionRangeStart != invalidSelectionRange
}

func (c *Ctx) SelectionLen() int {
	return c.selection.Len()
}

func (c *Ctx) SelectionAdd(x int) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if l, err := c.GetCurrentLineBuffer().LineAt(x); err == nil {
{'fraction_non_alphanumeric': 0.15414285714285714, 'fraction_numerical': 0.002, 'mean_word_length': 3.2378934624697338, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '426749', 'n_tokens_mistral': 2694, 'n_tokens_neox': 2630, 'n_words': 571}