mirror of
https://github.com/rivo/tview.git
synced 2025-04-30 13:48:50 +08:00
Add batch writer for TextView's
This commit is contained in:
parent
5508f4b002
commit
4385df9931
21
example_textview_test.go
Normal file
21
example_textview_test.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package tview_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/rivo/tview"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleTextView_BatchWriter() {
|
||||||
|
tv := tview.NewTextView()
|
||||||
|
|
||||||
|
w := tv.BatchWriter()
|
||||||
|
defer w.Close()
|
||||||
|
w.Clear()
|
||||||
|
fmt.Fprintln(w, "To sit in solemn silence")
|
||||||
|
fmt.Fprintln(w, "on a dull, dark, dock")
|
||||||
|
fmt.Println(tv.GetText(false))
|
||||||
|
// Output:
|
||||||
|
// To sit in solemn silence
|
||||||
|
// on a dull, dark, dock
|
||||||
|
}
|
69
textview.go
69
textview.go
@ -419,10 +419,20 @@ func (t *TextView) GetScrollOffset() (row, column int) {
|
|||||||
|
|
||||||
// Clear removes all text from the buffer.
|
// Clear removes all text from the buffer.
|
||||||
func (t *TextView) Clear() *TextView {
|
func (t *TextView) Clear() *TextView {
|
||||||
|
t.Lock()
|
||||||
|
defer t.Unlock()
|
||||||
|
|
||||||
|
t.clear()
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear is the internal implementaton of clear.
|
||||||
|
// It is used by TextViewWriter and anywhere that we need to perform a write
|
||||||
|
// without locking the buffer.
|
||||||
|
func (t *TextView) clear() {
|
||||||
t.buffer = nil
|
t.buffer = nil
|
||||||
t.recentBytes = nil
|
t.recentBytes = nil
|
||||||
t.index = nil
|
t.index = nil
|
||||||
return t
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Highlight specifies which regions should be highlighted. If highlight
|
// Highlight specifies which regions should be highlighted. If highlight
|
||||||
@ -622,10 +632,18 @@ func (t *TextView) HasFocus() bool {
|
|||||||
// replaced with TabSize space characters. A "\n" or "\r\n" will be interpreted
|
// replaced with TabSize space characters. A "\n" or "\r\n" will be interpreted
|
||||||
// as a new line.
|
// as a new line.
|
||||||
func (t *TextView) Write(p []byte) (n int, err error) {
|
func (t *TextView) Write(p []byte) (n int, err error) {
|
||||||
// Notify at the end.
|
|
||||||
t.Lock()
|
t.Lock()
|
||||||
|
defer t.Unlock()
|
||||||
|
|
||||||
|
return t.write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write is the internal implementation of Write.
|
||||||
|
// It is used by TextViewWriter and anywhere that we need to perform a write
|
||||||
|
// without locking the buffer.
|
||||||
|
func (t *TextView) write(p []byte) (n int, err error) {
|
||||||
|
// Notify at the end.
|
||||||
changed := t.changed
|
changed := t.changed
|
||||||
t.Unlock()
|
|
||||||
if changed != nil {
|
if changed != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
// We always call the "changed" function in a separate goroutine to avoid
|
// We always call the "changed" function in a separate goroutine to avoid
|
||||||
@ -634,9 +652,6 @@ func (t *TextView) Write(p []byte) (n int, err error) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Lock()
|
|
||||||
defer t.Unlock()
|
|
||||||
|
|
||||||
// Copy data over.
|
// Copy data over.
|
||||||
newBytes := append(t.recentBytes, p...)
|
newBytes := append(t.recentBytes, p...)
|
||||||
t.recentBytes = nil
|
t.recentBytes = nil
|
||||||
@ -1259,3 +1274,45 @@ func (t *TextView) MouseHandler() func(action MouseAction, event *tcell.EventMou
|
|||||||
return
|
return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TextViewWriter is a writer that can be used to write and clear a TextView in
|
||||||
|
// batches (ie. multiple writes with the lock only being aquired once).
|
||||||
|
// It should not be instantiated directly and should instead only be created by
|
||||||
|
// TextView's BatchWriter method.
|
||||||
|
type TextViewWriter struct {
|
||||||
|
t *TextView
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements io.Closer for the writer by unlocking the original TextView.
|
||||||
|
func (w TextViewWriter) Close() error {
|
||||||
|
w.t.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear removes all text from the buffer.
|
||||||
|
func (w TextViewWriter) Clear() {
|
||||||
|
w.t.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements the io.Writer interface.
|
||||||
|
// It behaves like the TextView's Write method except that it does not aquire
|
||||||
|
// the lock.
|
||||||
|
func (w TextViewWriter) Write(p []byte) (n int, err error) {
|
||||||
|
return w.t.write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasFocus returns whether the underlying TextView has focus.
|
||||||
|
func (w TextViewWriter) HasFocus() bool {
|
||||||
|
return w.t.hasFocus
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchWriter returns a new writer that can be used to write into the buffer
|
||||||
|
// but without Locking/Unlocking the buffer on every write.
|
||||||
|
// The lock will only be aquired once when BatchWriter is called, and will be
|
||||||
|
// released when the returned writer is Closed.
|
||||||
|
func (t *TextView) BatchWriter() TextViewWriter {
|
||||||
|
t.Lock()
|
||||||
|
return TextViewWriter{
|
||||||
|
t: t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user