mirror of https://github.com/liamg/aminal.git
tidy up main package
This commit is contained in:
parent
d049fddfd6
commit
bd4dcb1fe4
|
@ -200,6 +200,9 @@ func (buffer *Buffer) ViewHeight() uint16 {
|
|||
}
|
||||
|
||||
func (buffer *Buffer) insertLine() {
|
||||
|
||||
defer buffer.emitDisplayChange()
|
||||
|
||||
if !buffer.InScrollableRegion() {
|
||||
pos := buffer.RawLine()
|
||||
out := make([]Line, len(buffer.lines)+1)
|
||||
|
@ -251,6 +254,8 @@ func (buffer *Buffer) Index() {
|
|||
// This sequence causes the active position to move downward one line without changing the column position.
|
||||
// If the active position is at the bottom margin, a scroll up is performed."
|
||||
|
||||
defer buffer.emitDisplayChange()
|
||||
|
||||
if buffer.InScrollableRegion() {
|
||||
|
||||
if uint(buffer.cursorY) < buffer.bottomMargin {
|
||||
|
@ -277,6 +282,9 @@ func (buffer *Buffer) Index() {
|
|||
}
|
||||
|
||||
func (buffer *Buffer) ReverseIndex() {
|
||||
|
||||
defer buffer.emitDisplayChange()
|
||||
|
||||
if buffer.InScrollableRegion() {
|
||||
|
||||
if uint(buffer.cursorY) > buffer.topMargin {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/liamg/aminal/config"
|
||||
)
|
||||
|
||||
func getConfig() *config.Config {
|
||||
ignore := false
|
||||
flag.BoolVar(&ignore, "ignore-config", ignore, "Ignore user config files and use defauls")
|
||||
if ignore {
|
||||
return &config.DefaultConfig
|
||||
}
|
||||
|
||||
conf := loadConfigFile()
|
||||
|
||||
flag.BoolVar(&conf.DebugMode, "debug", conf.DebugMode, "Enable debug logging")
|
||||
flag.BoolVar(&conf.Slomo, "slomo", conf.Slomo, "Render in slow motion (useful for debugging)")
|
||||
flag.BoolVar(&conf.Rendering.AlwaysRepaint, "always-repaint", conf.Rendering.AlwaysRepaint, "Always repaint the window, even when no changes have occurred")
|
||||
|
||||
flag.Parse()
|
||||
return conf
|
||||
}
|
||||
|
||||
func loadConfigFile() *config.Config {
|
||||
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" {
|
||||
return &config.DefaultConfig
|
||||
}
|
||||
|
||||
places := []string{
|
||||
fmt.Sprintf("%s/.aminal.toml", home),
|
||||
}
|
||||
|
||||
for _, place := range places {
|
||||
if b, err := ioutil.ReadFile(place); err == nil {
|
||||
if c, err := config.Parse(b); err == nil {
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Printf("Invalid config at %s: %s\n", place, err)
|
||||
}
|
||||
}
|
||||
|
||||
if b, err := config.DefaultConfig.Encode(); err != nil {
|
||||
fmt.Printf("Failed to encode config file: %s\n", err)
|
||||
} else {
|
||||
if err := ioutil.WriteFile(fmt.Sprintf("%s/.aminal.toml", home), b, 0644); err != nil {
|
||||
fmt.Printf("Failed to encode config file: %s\n", err)
|
||||
}
|
||||
}
|
||||
return &config.DefaultConfig
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/liamg/aminal/config"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func getLogger(conf *config.Config) (*zap.SugaredLogger, error) {
|
||||
|
||||
var logger *zap.Logger
|
||||
var err error
|
||||
if conf.DebugMode {
|
||||
logger, err = zap.NewDevelopment()
|
||||
} else {
|
||||
loggerConfig := zap.NewProductionConfig()
|
||||
loggerConfig.Encoding = "console"
|
||||
logger, err = loggerConfig.Build()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create logger: %s", err)
|
||||
}
|
||||
return logger.Sugar(), nil
|
||||
}
|
76
main.go
76
main.go
|
@ -1,93 +1,20 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/kr/pty"
|
||||
"github.com/liamg/aminal/config"
|
||||
"github.com/liamg/aminal/gui"
|
||||
"github.com/liamg/aminal/terminal"
|
||||
"github.com/riywo/loginshell"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func getConfig() *config.Config {
|
||||
ignore := false
|
||||
flag.BoolVar(&ignore, "ignore-config", ignore, "Ignore user config files and use defauls")
|
||||
if ignore {
|
||||
return &config.DefaultConfig
|
||||
}
|
||||
|
||||
conf := loadConfigFile()
|
||||
|
||||
flag.BoolVar(&conf.DebugMode, "debug", conf.DebugMode, "Enable debug logging")
|
||||
flag.BoolVar(&conf.Slomo, "slomo", conf.Slomo, "Render in slow motion (useful for debugging)")
|
||||
flag.BoolVar(&conf.Rendering.AlwaysRepaint, "always-repaint", conf.Rendering.AlwaysRepaint, "Always repaint the window, even when no changes have occurred")
|
||||
|
||||
flag.Parse()
|
||||
return conf
|
||||
}
|
||||
|
||||
func loadConfigFile() *config.Config {
|
||||
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" {
|
||||
return &config.DefaultConfig
|
||||
}
|
||||
|
||||
places := []string{
|
||||
fmt.Sprintf("%s/.aminal.toml", home),
|
||||
}
|
||||
|
||||
for _, place := range places {
|
||||
if b, err := ioutil.ReadFile(place); err == nil {
|
||||
if c, err := config.Parse(b); err == nil {
|
||||
return c
|
||||
} else {
|
||||
fmt.Printf("Invalid config at %s: %s\n", place, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if b, err := config.DefaultConfig.Encode(); err != nil {
|
||||
fmt.Printf("Failed to encode config file: %s\n", err)
|
||||
} else {
|
||||
if err := ioutil.WriteFile(fmt.Sprintf("%s/.aminal.toml", home), b, 0644); err != nil {
|
||||
fmt.Printf("Failed to encode config file: %s\n", err)
|
||||
}
|
||||
}
|
||||
return &config.DefaultConfig
|
||||
}
|
||||
|
||||
func getLogger(conf *config.Config) (*zap.SugaredLogger, error) {
|
||||
|
||||
var logger *zap.Logger
|
||||
var err error
|
||||
if conf.DebugMode {
|
||||
logger, err = zap.NewDevelopment()
|
||||
} else {
|
||||
loggerConfig := zap.NewProductionConfig()
|
||||
loggerConfig.Encoding = "console"
|
||||
logger, err = loggerConfig.Build()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create logger: %s", err)
|
||||
}
|
||||
return logger.Sugar(), nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
// parse this
|
||||
conf := getConfig()
|
||||
|
||||
os.Setenv("TERM", "xterm-256color") // contraversial! easier than installing terminfo everywhere, but obviously going to be slightly different to xterm functionality, so we'll see...
|
||||
|
||||
logger, err := getLogger(conf)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create logger: %s\n", err)
|
||||
|
@ -106,6 +33,9 @@ func main() {
|
|||
logger.Fatalf("Failed to ascertain your shell: %s", err)
|
||||
}
|
||||
|
||||
os.Setenv("TERM", "xterm-256color") // contraversial! easier than installing terminfo everywhere, but obviously going to be slightly different to xterm functionality, so we'll see...
|
||||
os.Setenv("COLORTERM", "truecolor")
|
||||
|
||||
shell := exec.Command(shellStr)
|
||||
shell.Stdout = tty
|
||||
shell.Stdin = tty
|
||||
|
|
34
pty/pty.go
34
pty/pty.go
|
@ -1,34 +0,0 @@
|
|||
package pty
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/riywo/loginshell"
|
||||
)
|
||||
|
||||
func NewPtyWithShell() (*os.File, error) {
|
||||
|
||||
shellStr, err := loginshell.Shell()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to ascertain your shell: %s", err)
|
||||
}
|
||||
|
||||
pty, tty, err := open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tty.Close()
|
||||
shell := exec.Command(shellStr)
|
||||
shell.Stdout = tty
|
||||
shell.Stdin = tty
|
||||
shell.Stderr = tty
|
||||
shell.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true}
|
||||
if err := shell.Start(); err != nil {
|
||||
pty.Close()
|
||||
return nil, err
|
||||
}
|
||||
return pty, nil
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package pty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// todo: port these for darwin/windows:
|
||||
func open() (*os.File, *os.File, error) {
|
||||
|
||||
pty, err := getpt()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ptsName, err := ptsname(pty)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = grantpt(pty)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = unlockpt(pty)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tty, err := os.OpenFile(ptsName, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pty, tty, nil
|
||||
|
||||
}
|
||||
|
||||
func getpt() (file *os.File, err error) {
|
||||
f, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return os.NewFile(uintptr(f), "/dev/ptmx"), nil
|
||||
}
|
||||
|
||||
func ptsname(file *os.File) (name string, err error) {
|
||||
|
||||
n := make([]byte, (syscall.TIOCPTYGNAME>>16)&((1<<13)-1))
|
||||
_, err = ioctl(file, syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
|
||||
for i, c := range n {
|
||||
if c == 0 {
|
||||
return string(n[:i]), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
||||
}
|
||||
|
||||
func ioctl(file *os.File, command uint, arg uintptr) (uintptr, error) {
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(file.Fd()),
|
||||
uintptr(command), uintptr(unsafe.Pointer(&arg)))
|
||||
if err != 0 {
|
||||
return 0, fmt.Errorf("Error no %d", err)
|
||||
}
|
||||
return arg, nil
|
||||
}
|
||||
|
||||
func grantpt(f *os.File) error {
|
||||
_, err := ioctl(f, syscall.TIOCPTYGRANT, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
_, err := ioctl(f, syscall.TIOCPTYUNLK, 0)
|
||||
return err
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
package pty
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// todo: port these for darwin/windows:
|
||||
func open() (*os.File, *os.File, error) {
|
||||
|
||||
pty, err := getpt()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ptsName, err := ptsname(pty)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// err = grantpt(pty)
|
||||
// if err != nil {
|
||||
// return nil, nil, err
|
||||
// }
|
||||
|
||||
err = unlockpt(pty)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tty, err := os.OpenFile(ptsName, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pty, tty, nil
|
||||
|
||||
}
|
||||
|
||||
func getpt() (file *os.File, err error) {
|
||||
return os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
|
||||
}
|
||||
|
||||
func ptsname(file *os.File) (name string, err error) {
|
||||
n, err := ioctl(file, syscall.TIOCGPTN, 0)
|
||||
return fmt.Sprintf("/dev/pts/%d", n), err
|
||||
}
|
||||
|
||||
func ioctl(file *os.File, command uint, arg int) (int, error) {
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(file.Fd()),
|
||||
uintptr(command), uintptr(unsafe.Pointer(&arg)))
|
||||
if err != 0 {
|
||||
return 0, fmt.Errorf("Error no %d", err)
|
||||
}
|
||||
return arg, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func grantpt(f *os.File) error {
|
||||
_, err := ioctl(f, syscall.TIOCPTYGRANT, 0)
|
||||
syscall.SYS
|
||||
return err
|
||||
}
|
||||
*/
|
||||
|
||||
func unlockpt(f *os.File) error {
|
||||
_, err := ioctl(f, syscall.TIOCSPTLCK, 0)
|
||||
return err
|
||||
}
|
Loading…
Reference in New Issue