shell/main.go

162 lines
3.1 KiB
Go
Raw Normal View History

2023-03-19 13:08:11 +01:00
package main
import (
"fmt"
"os"
"strconv"
"strings"
"time"
"unicode"
"github.com/fatih/color"
"golang.org/x/crypto/ssh/terminal"
)
var (
inputBuffer = new(ColorString)
oldLineContent = new(ColorString)
oldWidth int
debugInfo string
)
func main() {
// enable raw mode
doItRaw()
defer cook()
inputChannel := handleInput()
running := true
refreshInputBuffer(true)
for running {
select {
case input := <-inputChannel:
if unicode.IsControl(rune(input)) {
if input == 127 && inputBuffer.Len() > 0 { // Backspace
str := inputBuffer.Raw()
inputBuffer = new(ColorString)
inputBuffer.Append(str[:len(str)-1])
} else if input == 12 { // C-L
clear()
refreshInputBuffer(true)
} else if input == 13 { // Enter
cmd := inputBuffer.Raw()
if strings.TrimSpace(cmd) == "exit" {
running = false
break
}
inputBuffer = new(ColorString)
fmt.Print("\r\n")
handle(cmd)
refreshInputBuffer(true)
} else if input == 3 { // C-C
inputBuffer = new(ColorString)
} else if input == 17 { // C-Q
running = false
break
}
//fmt.Print(input, "\r\n")
break
}
inputBuffer.Append(string(input))
case <-time.After(time.Second):
}
refreshInputBuffer(false)
}
}
func refreshInputBuffer(force bool) {
ps := prompt()
lineContent := new(ColorString).AppendColorString(ps, inputBuffer)
width, _, err := terminal.GetSize(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
if oldWidth == 0 {
oldWidth = width
}
lines := oldLineContent.Len() / width
debugInfo = strconv.Itoa(lines)
for i := 0; i <= lines; i++ {
fmt.Print("\r")
clearEOL()
if i < lines {
goUp()
}
}
fmt.Print(lineContent.String())
oldLineContent = lineContent
oldWidth = width
}
// func refreshInputBuffer(force bool) {
// width, _, err := terminal.GetSize(int(os.Stdin.Fd()))
// if err != nil {
// panic(err)
// }
// clearEOL()
// debugInfo = fmt.Sprint(oldLineContent.Len(), width, oldLineContent.Len()/width)
// for i := 0; i < oldLineContent.Len()/width; i++ {
// goUp()
// }
// ps := prompt()
// lineContent := new(ColorString).AppendColorString(ps, inputBuffer)
// if !force && lineContent.Equals(oldLineContent) {
// return
// }
// diff := lineContent.Len() - oldLineContent.Len()
// if diff < 0 {
// diff = -diff
// }
// for i := 0; i < diff; i++ {
// goLeft()
// }
// clearEOL()
// fmt.Print("\r")
// fmt.Print(lineContent.String())
// oldLineContent = lineContent
// }
// func getTerminalSize() (width, height int, err error) {
// width, height, err = terminal.GetSize(int(os.Stdout.Fd()))
// if err != nil {
// return 0, 0, adverr.Wrap("Could not retrieve terminal size", err)
// }
// return
// }
func print(str string, attrs ...color.Attribute) string {
return color.New(attrs...).Sprint(str)
}
func host() string {
hostname, _ := os.Hostname()
return hostname
}
func wd() string {
wd, _ := os.Getwd()
home := env("HOME")
return strings.Replace(wd, home, "~", 1)
}
func env(key string) string {
value, _ := os.LookupEnv(key)
return value
}