<commit_before>// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package text contains a widget that displays textual data.
package text

import (
	"bytes"
	"errors"
	"fmt"
	"image"
	"sync"
	"unicode"

	"github.com/mum4k/termdash/canvas"
	"github.com/mum4k/termdash/terminalapi"
	"github.com/mum4k/termdash/widgetapi"
)

// Text displays a block of text.
//
// Each line of the text is either trimmed or wrapped according to the provided
// options. The entire text content is either trimmed or rolled up through the
// canvas according to the provided options.
//
// By default the widget supports scrolling of content with either the keyboard
// or mouse. See the options for the default keys and mouse buttons.
//
// Implements widgetapi.Widget. This object is thread-safe.
type Text struct {
	// buff contains the text to be displayed in the widget.
	buff bytes.Buffer
	// givenWOpts are write options given for the text.
	givenWOpts givenWOpts

	// scroll tracks scrolling the position.
	scroll *scrollTracker

	// lastWidth stores the width of the last canvas the widget drew on.
	// Used to determine if the previous line wrapping was invalidated.
	lastWidth int
	// contentChanged indicates if the text content of the widget changed since
	// the last drawing. Used to determine if the previous line wrapping was
	// invalidated.
	contentChanged bool
	// lines stores the starting locations in bytes of all the lines in the
	// buffer. I.e. positions of newline characters and of any calculated line wraps.
	lines []int

	// mu protects the Text widget.
	mu sync.Mutex

	// opts are the provided options.
	opts *options
}

// New returns a new text widget.
func New(opts ...Option) *Text {
	opt := newOptions(opts...)
	return &Text{
		givenWOpts: newGivenWOpts(),
		scroll:     newScrollTracker(opt),
		opts:       opt,
	}
}

// Reset resets the widget back to empty content.
func (t *Text) Reset() {
	t.mu.Lock()
	defer t.mu.Unlock()

	t.buff.Reset()
	t.givenWOpts = newGivenWOpts()
	t.scroll = newScrollTracker(t.opts)
	t.lastWidth = 0
	t.contentChanged = true
	t.lines = nil
}

// Write writes text for the widget to display. Multiple calls append
// additional text. The text cannot control characters (unicode.IsControl) or
// space character (unicode.IsSpace) other than:
//   ' ', '\n'
// Any newline ('\n') characters are interpreted as newlines when displaying
// the text.
func (t *Text) Write(text string, wOpts ...WriteOption) error {
	t.mu.Lock()
	defer t.mu.Unlock()
<commit_msg>Fixing a comment.<commit_after>// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package text contains a widget that displays textual data.
package text

import (
	"bytes"
	"errors"
	"fmt"
	"image"
	"sync"
	"unicode"

	"github.com/mum4k/termdash/canvas"
	"github.com/mum4k/termdash/terminalapi"
	"github.com/mum4k/termdash/widgetapi"
)

// Text displays a block of text.
//
// Each line of the text is either trimmed or wrapped according to the provided
// options. The entire text content is either trimmed or rolled up through the
// canvas according to the provided options.
//
// By default the widget supports scrolling of content with either the keyboard
// or mouse. See the options for the default keys and mouse buttons.
//
// Implements widgetapi.Widget. This object is thread-safe.
type Text struct {
	// buff contains the text to be displayed in the widget.
	buff bytes.Buffer
	// givenWOpts are write options given for the text.
	givenWOpts givenWOpts

	// scroll tracks scrolling the position.
	scroll *scrollTracker

	// lastWidth stores the width of the last canvas the widget drew on.
	// Used to determine if the previous line wrapping was invalidated.
	lastWidth int
	// contentChanged indicates if the text content of the widget changed since
	// the last drawing. Used to determine if the previous line wrapping was
	// invalidated.
	contentChanged bool
	// lines stores the starting locations in bytes of all the lines in the
	// buffer. I.e. positions of newline characters and of any calculated line wraps.
	lines []int

	// mu protects the Text widget.
	mu sync.Mutex

	// opts are the provided options.
	opts *options
}

// New returns a new text widget.
func New(opts ...Option) *Text {
	opt := newOptions(opts...)
	return &Text{
		givenWOpts: newGivenWOpts(),
		scroll:     newScrollTracker(opt),
		opts:       opt,
	}
}

// Reset resets the widget back to empty content.
func (t *Text) Reset() {
	t.mu.Lock()
	defer t.mu.Unlock()

	t.buff.Reset()
	t.givenWOpts = newGivenWOpts()
	t.scroll = newScrollTracker(t.opts)
	t.lastWidth = 0
	t.contentChanged = true
	t.lines = nil
}

// Write writes text for the widget to display. Multiple calls append
// additional text. The text contain cannot control characters
// (unicode.IsControl) or space character (unicode.IsSpace) other than:
//   ' ', '\n'
// Any newline ('\n') characters are interpreted as newlines when displaying
// the text.
func (t *Text) Write(text string, wOpts ...WriteOption) error {
	t.mu.Lock()
	defer t.mu.Unlock()

{'fraction_non_alphanumeric': 0.09262295081967213, 'fraction_numerical': 0.003934426229508197, 'mean_word_length': 3.336176261549396, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '2318216', 'n_tokens_mistral': 1781, 'n_tokens_neox': 1722, 'n_words': 787}