1
0
textedit/lib.go

123 lines
2.3 KiB
Go
Raw Normal View History

2025-11-01 03:49:02 +01:00
package textedit
import "io"
type Editor interface {
Edit(r rune, state any) ([]rune, any)
ReleaseState(state any) []rune
}
type editorFunc[S any] struct {
edit func(rune, S) ([]rune, S)
releaseState func(S) []rune
}
type Writer struct {
out io.Writer
editor Editor
state any
err error
}
func (e editorFunc[S]) Edit(r rune, state any) ([]rune, any) {
s, _ := state.(S)
return e.edit(r, s)
}
func (e editorFunc[S]) ReleaseState(state any) []rune {
s, _ := state.(S)
r := e.releaseState(s)
return r
}
func Func[S any](edit func(r rune, state S) ([]rune, S), releaseState func(S) []rune) Editor {
if edit == nil {
edit = func(r rune, s S) ([]rune, S) { return []rune{r}, s }
}
if releaseState == nil {
releaseState = func(S) []rune { return nil }
}
return editorFunc[S]{edit: edit, releaseState: releaseState}
}
func Replace(a ...string) Editor {
return replace(a...)
}
func Escape(esc rune, chars ...rune) Editor {
return escape(esc, chars...)
}
func Indent(first, rest string) Editor {
return wrapIndent([]rune(first), []rune(rest), 0, 0)
}
func Wrap(firstWidth, restWidth int) Editor {
return wrapIndent(nil, nil, firstWidth, restWidth)
}
func WrapIndent(firstIndent, restIndent string, firstWidth, restWidth int) Editor {
return wrapIndent([]rune(firstIndent), []rune(restIndent), firstWidth, restWidth)
}
func SingleLine() Editor {
return sequence(
replace("\n", " "),
wrapIndent(nil, nil, 0, 0),
)
}
func New(out io.Writer, e ...Editor) *Writer {
return &Writer{
out: out,
editor: sequence(e...),
}
}
func (w *Writer) write(r []rune) error {
if w.err != nil {
return w.err
}
for _, ri := range r {
rr, s := w.editor.Edit(ri, w.state)
if _, err := w.out.Write([]byte(string(rr))); err != nil {
w.err = err
return w.err
}
w.state = s
}
return nil
}
func (w *Writer) flush() error {
if w.err != nil {
return w.err
}
r := w.editor.ReleaseState(w.state)
w.state = nil
if _, err := w.out.Write([]byte(string(r))); err != nil {
w.err = err
return w.err
}
return nil
}
func (w *Writer) Write(p []byte) (int, error) {
return len(p), w.write([]rune(string(p)))
}
func (w *Writer) WriteRune(r rune) (int, error) {
return len([]byte(string(r))), w.write([]rune{r})
}
func (w *Writer) Flush() error {
return w.flush()
}