162 lines
3.1 KiB
Go
162 lines
3.1 KiB
Go
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
|
|
}
|