mirror of
https://github.com/sorenisanerd/gotty.git
synced 2024-11-22 04:14:25 +00:00
Merge branch 'develop': control sequence
This commit is contained in:
commit
9813acaff3
@ -175,8 +175,9 @@ visit `http://127.0.0.1:8080/?arg=without-istio&arg=sleep-7b6d569576-57sjq&arg=s
|
|||||||
|
|
||||||
```
|
```
|
||||||
...
|
...
|
||||||
2022/11/13 10:48:12 [write-log] {"arg":["without-istio","sleep-7b6d569576-57sjq","sleep","21001713"]} lsCR
|
2022/12/13 13:36:46 [write-log] map[arg:[without-istio sleep-7b6d569576-8nz7t sleep 21001713]] ls[CR]
|
||||||
2022/11/13 10:48:14 [write-log] {"arg":["without-istio","sleep-7b6d569576-57sjq","sleep","21001713"]} pwdCR
|
2022/12/13 13:37:25 [write-log] map[arg:[without-istio sleep-7b6d569576-8nz7t sleep 21001713]] echo[SPACE]hello[SPACE]world;[CR]
|
||||||
|
2022/12/13 13:47:00 [write-log] map[arg:[without-istio sleep-7b6d569576-8nz7t sleep 21001713]] [CUU][CR]
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
109
utils/log.go
109
utils/log.go
@ -1,8 +1,11 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
var CtrlChar = map[byte]string{
|
var ControlCodes = map[byte]string{
|
||||||
0: "NUL",
|
0: "NUL",
|
||||||
1: "SOH",
|
1: "SOH",
|
||||||
2: "STX",
|
2: "STX",
|
||||||
@ -39,67 +42,73 @@ var CtrlChar = map[byte]string{
|
|||||||
127: "DEL",
|
127: "DEL",
|
||||||
}
|
}
|
||||||
|
|
||||||
var CtrlCharGroup = map[string]string{
|
// https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||||
"1B5B41": "UP",
|
// https://xtermjs.org/docs/api/vtfeatures/
|
||||||
"1B5B42": "DOWN",
|
var ControlSequences = map[string]string{
|
||||||
"1B5B43": "RIGHT",
|
// Cursor Up
|
||||||
"1B5B44": "LEFT",
|
"ESC[A": "CUU",
|
||||||
|
// Cursor Down
|
||||||
// shell control codes
|
"ESC[B": "CUD",
|
||||||
// codes[0]+codes[1]+codes[n-1]
|
// Cursor Forward
|
||||||
// for example:
|
"ESC[C": "CUF",
|
||||||
// [1B(ESC) 5B([) 32(2) 3B(;) 35(5) 52(R)]: row 2 col 5
|
// Cursor Back
|
||||||
// [1B(ESC) 5B([) 31(1) 30(0) 3B(;) 35(5) 52(R)]: row 10 col 5
|
"ESC[D": "CUB",
|
||||||
// [1B(ESC) 5B([) 32(2) 32(2) 3B(;) 35(5) 52(R)]: row 22 col 5
|
|
||||||
"1B5B52": "",
|
|
||||||
|
|
||||||
// maybe there will be more control char group
|
|
||||||
// ...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func FormatWriteLog(codes []byte, line *string) {
|
var ControlSequencePatterns = map[string]string{
|
||||||
n := len(codes)
|
// Device Status Report
|
||||||
// when user uses the keyboard arrow keys
|
// Reports the cursor position (CPR) by transmitting `ESC[n;mR`, where n is the row and m is the column.
|
||||||
// arrow keys are combination of 3 ASCII codes
|
"^ESC\\[\\d+;\\d+R$": "",
|
||||||
if n == 3 {
|
|
||||||
if str, exist := ASCIIGroupToStr(fmt.Sprintf("%X", codes)); exist {
|
|
||||||
*line += str
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for some shells
|
|
||||||
// they will automatically send some control characters
|
|
||||||
// after typing the command and pressing Enter
|
|
||||||
// which indicate the current row and column.
|
|
||||||
if n >= 6 {
|
|
||||||
if str, exist := ASCIIGroupToStr(fmt.Sprintf("%X", []byte{codes[0], codes[1], codes[n-1]})); exist {
|
|
||||||
*line += str
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str := ASCIIToStr(codes)
|
|
||||||
*line += str
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ASCIIToStr(codes []byte) (str string) {
|
func ControlCodesToStr(codes []byte) (str string) {
|
||||||
for _, code := range codes {
|
for _, code := range codes {
|
||||||
if value, ok := CtrlChar[code]; ok {
|
if value, ok := ControlCodes[code]; ok {
|
||||||
str += value
|
str += value
|
||||||
} else {
|
} else {
|
||||||
str += string(code)
|
str += string(code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ASCIIGroupToStr(group string) (string, bool) {
|
func ControlCodesToEscapedStr(codes []byte) (str string) {
|
||||||
if value, ok := CtrlCharGroup[group]; ok {
|
for _, code := range codes {
|
||||||
return value, true
|
if value, ok := ControlCodes[code]; ok {
|
||||||
|
str += fmt.Sprintf("[%s]", value)
|
||||||
|
} else if code == 91 || code == 92 || code == 93 {
|
||||||
|
// escaping [ ] \
|
||||||
|
str += fmt.Sprintf("\\%s", string(code))
|
||||||
|
} else {
|
||||||
|
str += string(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ControlSequenceToStr(codes []byte) (string, bool) {
|
||||||
|
sequence := ControlCodesToStr(codes)
|
||||||
|
for key, value := range ControlSequences {
|
||||||
|
if key == sequence {
|
||||||
|
return fmt.Sprintf("[%s]", value), true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", false
|
for key, value := range ControlSequencePatterns {
|
||||||
|
if regexp.MustCompile(key).Match([]byte(sequence)) {
|
||||||
|
return value, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sequence, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormatWriteLog(codes []byte, line *string) {
|
||||||
|
n := len(codes)
|
||||||
|
if n >= 3 {
|
||||||
|
if str, exists := ControlSequenceToStr(codes); exists {
|
||||||
|
*line += str
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*line += ControlCodesToEscapedStr(codes)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user