ref: 7235fc1225901e80e0058acdc3db9b67e9a36338
dir: /readline_plan9.go/
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
"image"
"codeberg.org/penny64/go/draw"
"codeberg.org/penny64/go/draw/frame"
)
// not relevant
const (
CharCtrlJ = 0
CharInterrupt = 0
CharEnter = 0
)
type readline struct {
config Config
multi bool
ctl *os.File
label *os.File
}
type Config struct {
Prompt string
//These are unused on Plan 9
FuncFilterInputRune func(rune) (rune, bool)
Listener func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool)
}
func (rl *readline) GetConfig() *Config {
return &Config{Prompt: rl.config.Prompt}
}
func NewReadline(config *Config) (*readline, error) {
window, err := draw.Init(nil, "", "hell", "")
if err != nil {
return nil, err
}
var maincols [frame.NCOL]*draw.Image
/* Main text is yellowish */
screen := window.ScreenImage
maincols[frame.BACK] = window.AllocImageMix(draw.PaleYellow, draw.White)
maincols[frame.HIGH], _ = window.AllocImage(image.Rect(0, 0, 1, 1), screen.Pix, true, draw.DarkYellow)
maincols[frame.BORD], _ = window.AllocImage(image.Rect(0, 0, 2, 2), screen.Pix, true, draw.YellowGreen)
maincols[frame.TEXT] = window.Black
maincols[frame.HTEXT] = window.Black
const (
ScrollbarWidth = 12
BorderWidth = 2
)
fullRect := window.ScreenImage.R
window.ScreenImage.Draw(fullRect, maincols[frame.BACK], nil, draw.ZP)
scrollRect := fullRect
scrollRect.Max.X = scrollRect.Min.X + ScrollbarWidth
textRect := fullRect
textRect.Min.X = scrollRect.Max.X
window.ScreenImage.Border(textRect, BorderWidth, maincols[frame.BORD], draw.ZP)
frameRect := textRect.Inset(BorderWidth)
f := &frame.Frame{}
f.Init(frameRect, window.Font, window.ScreenImage, maincols[:])
f.Insert([]rune("Hello, Frame!"), 0)
f.Display = window
f.InitTick()
f.Tick(f.PointOf(f.NumChars), true)
window.ScreenImage.Draw(scrollRect, maincols[frame.TEXT], nil, draw.ZP)
window.Flush()
label, err := os.OpenFile("/dev/label", os.O_WRONLY, 0)
return &readline{config: *config, ctl: nil, label: label}, nil
}
func (rl *readline) ReadLineWithConfig(cfg *Config) (string, error) {
if rl.multi {
fmt.Print("MULTILINE ")
}
fmt.Print(cfg.Prompt)
var sb strings.Builder
var err error
var input string
for {
buffer := bufio.NewReader(os.Stdin)
input, err = buffer.ReadString('\n')
sb.WriteString(input)
if err != nil {
rl.multi = !rl.multi
if rl.multi {
fmt.Printf("MULTILINE %s", cfg.Prompt)
rl.ctl.WriteString("holdon")
continue
}
}
if !rl.multi {
break
}
}
return strings.TrimSpace(sb.String()), err
}
func (rl *readline) Stdout() io.Writer {
return os.Stdout
}
func (rl *readline) Close() {
return
}
func (rl *readline) SetPrompt(prompt string) {
rl.config.Prompt = prompt
}
func (rl *readline) SetDefault(editline string) {
rl.multi = true
rl.ctl.WriteString("holdon")
fmt.Printf("%s\n\n", editline)
}
func (rl *readline) Readline() (string, error) {
return rl.ReadLineWithConfig(&rl.config)
}
func enablePipeHack(rl *readline) {
}
func (rl *readline) setWindowTitle(title string) {
rl.label.WriteString(title)
}