Refactor
This commit is contained in:
@@ -2,123 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/creack/pty"
|
||||
|
||||
"tea.kareha.org/lab/kakiko/internal/console"
|
||||
"tea.kareha.org/lab/kakiko/internal/fep"
|
||||
"tea.kareha.org/lab/kakiko/internal/skk"
|
||||
)
|
||||
|
||||
var defaultCommand []string = []string{
|
||||
"/bin/sh",
|
||||
}
|
||||
|
||||
func main() {
|
||||
var cmd []string
|
||||
if len(os.Args) > 1 {
|
||||
cmd = os.Args[1:]
|
||||
} else {
|
||||
cmd = defaultCommand
|
||||
}
|
||||
var c *exec.Cmd
|
||||
if len(cmd) < 2 {
|
||||
c = exec.Command(cmd[0])
|
||||
} else {
|
||||
c = exec.Command(cmd[0], cmd[1:]...)
|
||||
}
|
||||
|
||||
ptmx, err := pty.Start(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGWINCH)
|
||||
|
||||
go func() {
|
||||
for range ch {
|
||||
rows, cols, err := pty.Getsize(os.Stdin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pty.Setsize(ptmx, &pty.Winsize{
|
||||
Rows: uint16(rows - 1),
|
||||
Cols: uint16(cols),
|
||||
})
|
||||
}
|
||||
}()
|
||||
rows, cols, err := pty.Getsize(os.Stdin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pty.Setsize(ptmx, &pty.Winsize{
|
||||
Rows: uint16(rows - 1),
|
||||
Cols: uint16(cols),
|
||||
})
|
||||
|
||||
console.ScrollRange(0, rows-1)
|
||||
defer console.ScrollRange(0, rows)
|
||||
|
||||
console.Clear()
|
||||
console.HomeCursor()
|
||||
console.Raw()
|
||||
defer func() {
|
||||
console.Clear()
|
||||
console.HomeCursor()
|
||||
console.Cooked()
|
||||
console.ShowCursor()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
b := make([]byte, 1)
|
||||
n, err := os.Stdin.Read(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
processed := skkProcess(b)
|
||||
|
||||
_, err = ptmx.Write(processed)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
c.Wait()
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
n, err := ptmx.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Stdout.Write(buf[:n])
|
||||
|
||||
drawStatus()
|
||||
}
|
||||
}
|
||||
|
||||
func drawStatus() {
|
||||
_, h := console.Size()
|
||||
console.SaveCursor()
|
||||
console.HideCursor()
|
||||
console.MoveCursor(0, h-1)
|
||||
console.Print("Hello, World!")
|
||||
console.ShowCursor()
|
||||
console.LoadCursor()
|
||||
}
|
||||
|
||||
func skkProcess(b []byte) []byte {
|
||||
return b
|
||||
f := fep.Init(os.Args, skk.Process, skk.Status)
|
||||
defer f.Finish()
|
||||
f.Main()
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ func Cooked() {
|
||||
panic("invalid state")
|
||||
}
|
||||
term.Restore(int(os.Stdin.Fd()), state)
|
||||
state = nil
|
||||
}
|
||||
|
||||
func Clear() {
|
||||
@@ -75,3 +76,7 @@ func LoadCursor() {
|
||||
func ScrollRange(top, bottom int) {
|
||||
fmt.Printf("\x1b[%d;%dr", top+1, bottom)
|
||||
}
|
||||
|
||||
func ClearLine() {
|
||||
fmt.Print("\x1b[K")
|
||||
}
|
||||
|
||||
138
internal/fep/fep.go
Normal file
138
internal/fep/fep.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package fep
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/creack/pty"
|
||||
|
||||
"tea.kareha.org/lab/kakiko/internal/console"
|
||||
)
|
||||
|
||||
type Process func(b []byte) []byte
|
||||
type Status func() string
|
||||
|
||||
const defaultCommand = "/bin/sh"
|
||||
const bufferSize = 1024
|
||||
|
||||
type FEP struct {
|
||||
fd *os.File
|
||||
process Process
|
||||
status Status
|
||||
}
|
||||
|
||||
func (f *FEP) updateSize() {
|
||||
rows, cols, err := pty.Getsize(os.Stdin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pty.Setsize(f.fd, &pty.Winsize{
|
||||
Rows: uint16(rows - 1),
|
||||
Cols: uint16(cols),
|
||||
})
|
||||
}
|
||||
|
||||
func Init(args []string, process Process, status Status) *FEP {
|
||||
var command string = defaultCommand
|
||||
var arguments []string
|
||||
if len(args) > 1 {
|
||||
command = args[1]
|
||||
}
|
||||
if len(args) > 2 {
|
||||
arguments = args[2:]
|
||||
}
|
||||
var c = exec.Command(command, arguments...)
|
||||
fd, err := pty.Start(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f := &FEP{
|
||||
fd: fd,
|
||||
process: process,
|
||||
status: status,
|
||||
}
|
||||
|
||||
f.updateSize()
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGWINCH)
|
||||
go func() {
|
||||
for range ch {
|
||||
f.updateSize()
|
||||
}
|
||||
}()
|
||||
|
||||
_, h := console.Size()
|
||||
console.ScrollRange(0, h-1)
|
||||
|
||||
console.Clear()
|
||||
console.HomeCursor()
|
||||
console.Raw()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
b := make([]byte, 1)
|
||||
n, err := os.Stdin.Read(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
processed := f.process(b)
|
||||
|
||||
_, err = fd.Write(processed)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
c.Wait()
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *FEP) Finish() {
|
||||
_, h := console.Size()
|
||||
console.ScrollRange(0, h)
|
||||
|
||||
console.Clear()
|
||||
console.HomeCursor()
|
||||
console.Cooked()
|
||||
console.ShowCursor()
|
||||
}
|
||||
|
||||
func (f *FEP) drawStatus() {
|
||||
_, h := console.Size()
|
||||
console.SaveCursor()
|
||||
console.HideCursor()
|
||||
console.MoveCursor(0, h-1)
|
||||
|
||||
status := f.status()
|
||||
console.Print(status)
|
||||
console.ClearLine()
|
||||
|
||||
console.ShowCursor()
|
||||
console.LoadCursor()
|
||||
}
|
||||
|
||||
func (f *FEP) Main() {
|
||||
buf := make([]byte, bufferSize)
|
||||
for {
|
||||
n, err := f.fd.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Stdout.Write(buf[:n])
|
||||
|
||||
f.drawStatus()
|
||||
}
|
||||
}
|
||||
18
internal/skk/skk.go
Normal file
18
internal/skk/skk.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package skk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// XXX dummy
|
||||
var count int = 0
|
||||
|
||||
func Process(b []byte) []byte {
|
||||
count++ // XXX dummy
|
||||
return b
|
||||
}
|
||||
|
||||
func Status() string {
|
||||
// XXX dummy
|
||||
return fmt.Sprintf("Hello, World! (%d)", count)
|
||||
}
|
||||
Reference in New Issue
Block a user