Browse Source

Initial Commit

Tim Schuster 1 year ago
commit
30e6a1f59c
Signed by: Tim Schuster <mail@timschuster.info> GPG Key ID: F9E27097EFB77F61
100 changed files with 13817 additions and 0 deletions
  1. 7
    0
      app/main.go
  2. 101
    0
      chc.go
  3. 29
    0
      con.go
  4. 10
    0
      direct.go
  5. 83
    0
      exec.go
  6. 68
    0
      parser.go
  7. 14
    0
      parser_test.go
  8. 22
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/HardwareControl.json
  9. 12
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/Regal0.json
  10. 12
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/Regal1.json
  11. 12
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/Regal2.json
  12. 45
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/StructContainer.go
  13. 246
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/HardwareControl/HardwareControl.go
  14. 3
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/README.md
  15. BIN
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/RP2_Pinout.png
  16. BIN
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/servertest
  17. 51
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/servertest.go
  18. 14
    0
      vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/test.go
  19. 8
    0
      vendor/git.timschuster.info/stephan.graf/SanguControl/README.md
  20. 385
    0
      vendor/git.timschuster.info/stephan.graf/SanguControl/sanguinololu_control.go
  21. 58
    0
      vendor/github.com/chzyer/readline/CHANGELOG.md
  22. 22
    0
      vendor/github.com/chzyer/readline/LICENSE
  23. 114
    0
      vendor/github.com/chzyer/readline/README.md
  24. 246
    0
      vendor/github.com/chzyer/readline/ansi_windows.go
  25. 283
    0
      vendor/github.com/chzyer/readline/complete.go
  26. 165
    0
      vendor/github.com/chzyer/readline/complete_helper.go
  27. 82
    0
      vendor/github.com/chzyer/readline/complete_segment.go
  28. 312
    0
      vendor/github.com/chzyer/readline/history.go
  29. 504
    0
      vendor/github.com/chzyer/readline/operation.go
  30. 32
    0
      vendor/github.com/chzyer/readline/password.go
  31. 125
    0
      vendor/github.com/chzyer/readline/rawreader_windows.go
  32. 288
    0
      vendor/github.com/chzyer/readline/readline.go
  33. 474
    0
      vendor/github.com/chzyer/readline/remote.go
  34. 572
    0
      vendor/github.com/chzyer/readline/runebuf.go
  35. 223
    0
      vendor/github.com/chzyer/readline/runes.go
  36. 164
    0
      vendor/github.com/chzyer/readline/search.go
  37. 133
    0
      vendor/github.com/chzyer/readline/std.go
  38. 9
    0
      vendor/github.com/chzyer/readline/std_windows.go
  39. 123
    0
      vendor/github.com/chzyer/readline/term.go
  40. 29
    0
      vendor/github.com/chzyer/readline/term_bsd.go
  41. 33
    0
      vendor/github.com/chzyer/readline/term_linux.go
  42. 32
    0
      vendor/github.com/chzyer/readline/term_solaris.go
  43. 24
    0
      vendor/github.com/chzyer/readline/term_unix.go
  44. 171
    0
      vendor/github.com/chzyer/readline/term_windows.go
  45. 232
    0
      vendor/github.com/chzyer/readline/terminal.go
  46. 276
    0
      vendor/github.com/chzyer/readline/utils.go
  47. 83
    0
      vendor/github.com/chzyer/readline/utils_unix.go
  48. 41
    0
      vendor/github.com/chzyer/readline/utils_windows.go
  49. 174
    0
      vendor/github.com/chzyer/readline/vim.go
  50. 152
    0
      vendor/github.com/chzyer/readline/windows_api.go
  51. 15
    0
      vendor/github.com/davecgh/go-spew/LICENSE
  52. 152
    0
      vendor/github.com/davecgh/go-spew/spew/bypass.go
  53. 38
    0
      vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
  54. 341
    0
      vendor/github.com/davecgh/go-spew/spew/common.go
  55. 306
    0
      vendor/github.com/davecgh/go-spew/spew/config.go
  56. 211
    0
      vendor/github.com/davecgh/go-spew/spew/doc.go
  57. 509
    0
      vendor/github.com/davecgh/go-spew/spew/dump.go
  58. 419
    0
      vendor/github.com/davecgh/go-spew/spew/format.go
  59. 148
    0
      vendor/github.com/davecgh/go-spew/spew/spew.go
  60. 19
    0
      vendor/github.com/foize/go.fifo/LICENSE
  61. 113
    0
      vendor/github.com/foize/go.fifo/fifo.go
  62. 107
    0
      vendor/github.com/foize/go.fifo/readme.md
  63. 202
    0
      vendor/github.com/jacobsa/go-serial/LICENSE
  64. 8
    0
      vendor/github.com/jacobsa/go-serial/serial/Makefile
  65. 242
    0
      vendor/github.com/jacobsa/go-serial/serial/open_darwin.go
  66. 21
    0
      vendor/github.com/jacobsa/go-serial/serial/open_freebsd.go
  67. 203
    0
      vendor/github.com/jacobsa/go-serial/serial/open_linux.go
  68. 317
    0
      vendor/github.com/jacobsa/go-serial/serial/open_windows.go
  69. 134
    0
      vendor/github.com/jacobsa/go-serial/serial/serial.go
  70. 27
    0
      vendor/github.com/pmezard/go-difflib/LICENSE
  71. 772
    0
      vendor/github.com/pmezard/go-difflib/difflib/difflib.go
  72. 22
    0
      vendor/github.com/stretchr/testify/LICENSE
  73. 352
    0
      vendor/github.com/stretchr/testify/assert/assertion_forward.go
  74. 4
    0
      vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
  75. 1069
    0
      vendor/github.com/stretchr/testify/assert/assertions.go
  76. 45
    0
      vendor/github.com/stretchr/testify/assert/doc.go
  77. 10
    0
      vendor/github.com/stretchr/testify/assert/errors.go
  78. 16
    0
      vendor/github.com/stretchr/testify/assert/forward_assertions.go
  79. 106
    0
      vendor/github.com/stretchr/testify/assert/http_assertions.go
  80. 28
    0
      vendor/github.com/stretchr/testify/require/doc.go
  81. 16
    0
      vendor/github.com/stretchr/testify/require/forward_requirements.go
  82. 429
    0
      vendor/github.com/stretchr/testify/require/require.go
  83. 6
    0
      vendor/github.com/stretchr/testify/require/require.go.tmpl
  84. 353
    0
      vendor/github.com/stretchr/testify/require/require_forward.go
  85. 4
    0
      vendor/github.com/stretchr/testify/require/require_forward.go.tmpl
  86. 9
    0
      vendor/github.com/stretchr/testify/require/requirements.go
  87. 27
    0
      vendor/go.rls.moe/misc/adafruitPCA9685/consts.go
  88. 28
    0
      vendor/go.rls.moe/misc/adafruitPCA9685/helper.go
  89. 145
    0
      vendor/go.rls.moe/misc/adafruitPCA9685/pca9685.go
  90. 78
    0
      vendor/go.rls.moe/misc/adafruitPCA9685/servo.go
  91. 27
    0
      vendor/golang.org/x/exp/LICENSE
  92. 22
    0
      vendor/golang.org/x/exp/PATENTS
  93. 79
    0
      vendor/golang.org/x/exp/io/i2c/devfs.go
  94. 24
    0
      vendor/golang.org/x/exp/io/i2c/devfs_nonlinux.go
  95. 24
    0
      vendor/golang.org/x/exp/io/i2c/driver/driver.go
  96. 70
    0
      vendor/golang.org/x/exp/io/i2c/i2c.go
  97. 27
    0
      vendor/golang.org/x/sys/LICENSE
  98. 22
    0
      vendor/golang.org/x/sys/PATENTS
  99. 173
    0
      vendor/golang.org/x/sys/unix/README.md
  100. 0
    0
      vendor/golang.org/x/sys/unix/asm_darwin_386.s

+ 7
- 0
app/main.go View File

@@ -0,0 +1,7 @@
1
+package main
2
+
3
+import "git.timschuster.info/tscs37/chocococon"
4
+
5
+func main() {
6
+	chocococon.Run()
7
+}

+ 101
- 0
chc.go View File

@@ -0,0 +1,101 @@
1
+package chocococon
2
+
3
+import (
4
+	"fmt"
5
+)
6
+
7
+func init() {
8
+	cmds["move_to"] = moveTo
9
+	helpm["move_to"] = "Moves the head to a position with given speed. [x,y,z,hspd,vspd]"
10
+	cmds["m"] = moveTo
11
+	helpm["m"] = "Alias for move_to"
12
+
13
+	cmds["roll"] = roll
14
+	helpm["roll"] = "Rolls the head. [angle]"
15
+	cmds["rotate"] = rotate
16
+	helpm["rotate"] = "Rotates the head. [angle]"
17
+}
18
+
19
+func moveTo(params []string) error {
20
+	/*if curCHC == nil {
21
+		fmt.Println("CHC not connected, aborting.")
22
+		return nil
23
+	}*/
24
+	var (
25
+		x, y, z         float64
26
+		xyspeed, zspeed int16
27
+	)
28
+	x, y, z = -1, -1, -1
29
+	xyspeed, zspeed = -1, -1
30
+
31
+	for k := range params {
32
+		if err := parseParamToFloat64("x", &x, params[k]); err != nil {
33
+			fmt.Println("Err parsing: ", err)
34
+			return nil
35
+		}
36
+		if err := parseParamToFloat64("y", &y, params[k]); err != nil {
37
+			fmt.Println("Err parsing: ", err)
38
+			return nil
39
+		}
40
+		if err := parseParamToFloat64("z", &z, params[k]); err != nil {
41
+			fmt.Println("Err parsing: ", err)
42
+			return nil
43
+		}
44
+		if err := parseParamToInt16("hspd", &xyspeed, params[k]); err != nil {
45
+			fmt.Println("Err parsing: ", err)
46
+			return nil
47
+		}
48
+		if err := parseParamToInt16("vspd", &zspeed, params[k]); err != nil {
49
+			fmt.Println("Err parsing: ", err)
50
+			return nil
51
+		}
52
+	}
53
+
54
+	fmt.Printf("Moving to %5.1f %5.1f %5.1f with speed horizontal=%d and vertical=%d\n", x, y, z, xyspeed, zspeed)
55
+	//curCHC.MoveTo(x, y, z, xyspeed, zspeed)
56
+	return nil
57
+}
58
+
59
+func roll(params []string) error {
60
+	/*if curCHC == nil {
61
+		fmt.Println("CHC not connected, aborting.")
62
+		return nil
63
+	}*/
64
+	var (
65
+		angle int16
66
+	)
67
+	angle = -1
68
+
69
+	for k := range params {
70
+		if err := parseParamToInt16("angle", &angle, params[k]); err != nil {
71
+			fmt.Println("Err parsing: ", err)
72
+			return nil
73
+		}
74
+	}
75
+
76
+	fmt.Printf("Rolling to angle %d\n", angle)
77
+	//curCHC.MoveTo(x, y, z, xyspeed, zspeed)
78
+	return nil
79
+}
80
+
81
+func rotate(params []string) error {
82
+	/*if curCHC == nil {
83
+		fmt.Println("CHC not connected, aborting.")
84
+		return nil
85
+	}*/
86
+	var (
87
+		angle int16
88
+	)
89
+	angle = -1
90
+
91
+	for k := range params {
92
+		if err := parseParamToInt16("angle", &angle, params[k]); err != nil {
93
+			fmt.Println("Err parsing: ", err)
94
+			return nil
95
+		}
96
+	}
97
+
98
+	fmt.Printf("Rotating to angle %d\n", angle)
99
+	//curCHC.MoveTo(x, y, z, xyspeed, zspeed)
100
+	return nil
101
+}

+ 29
- 0
con.go View File

@@ -0,0 +1,29 @@
1
+package chocococon
2
+
3
+import (
4
+	"bufio"
5
+	"fmt"
6
+	"os"
7
+)
8
+
9
+//var curCHC *HardwareControl.HardwareControl
10
+
11
+func Run() {
12
+	bufin := bufio.NewReader(os.Stdin)
13
+	for {
14
+		line, err := readCmdLine(bufin)
15
+		if err != nil {
16
+			fmt.Println("Error: ", err)
17
+			return
18
+		}
19
+		err = exec(makeTokens(line))
20
+		if err == errExit {
21
+			fmt.Println(err.Error())
22
+			return
23
+		} else if err != nil {
24
+			fmt.Println(err.Error())
25
+			continue
26
+		}
27
+		fmt.Println("OK")
28
+	}
29
+}

+ 10
- 0
direct.go View File

@@ -0,0 +1,10 @@
1
+package chocococon
2
+
3
+func init() {
4
+	cmds["home"] = notyetimplemented
5
+	helpm["home"] = "Calibrates the position of the head"
6
+	cmds["xyz"] = notyetimplemented
7
+	helpm["xyz"] = "Manually moves the head, bypassing the CHC"
8
+	cmds["stop"] = notyetimplemented
9
+	helpm["stop"] = "Issues an emergency stop to all devices and exits"
10
+}

+ 83
- 0
exec.go View File

@@ -0,0 +1,83 @@
1
+package chocococon
2
+
3
+import (
4
+	"errors"
5
+	"fmt"
6
+)
7
+
8
+type errNoCmd struct {
9
+	cmd string
10
+}
11
+
12
+func (e errNoCmd) Error() string {
13
+	return "unknown command: " + e.cmd
14
+}
15
+
16
+var (
17
+	errExit    = errors.New("exit")
18
+	errNoToken = errors.New("no command")
19
+)
20
+
21
+var cmds = map[string]func(params []string) error{
22
+	"help": help,
23
+	"exit": exit,
24
+}
25
+
26
+var helpm = map[string]string{
27
+	"help": "Shows help on how to use the console",
28
+	"exit": "Shuts down the controller and exits the console",
29
+	"lsc":  "Lists all commands, will execute if nothing is typed in",
30
+}
31
+
32
+func init() {
33
+	cmds[""] = listcommands
34
+	cmds["lsc"] = listcommands
35
+}
36
+
37
+func notyetimplemented(_ []string) error {
38
+	fmt.Println("not implemented")
39
+	return nil
40
+}
41
+
42
+func exec(tokens []string) error {
43
+	if len(tokens) == 0 {
44
+		return errNoToken
45
+	}
46
+	if val, ok := cmds[tokens[0]]; ok {
47
+		if len(tokens) == 1 {
48
+			return val([]string{})
49
+		} else {
50
+			return val(tokens[1:])
51
+		}
52
+	} else {
53
+		return errNoCmd{tokens[0]}
54
+	}
55
+}
56
+
57
+func help(params []string) error {
58
+	fmt.Println("Line Ending: `;`")
59
+	fmt.Println("Seperate Parameters with `,`")
60
+	fmt.Println("Example: `println,\"Hello World\";")
61
+	return nil
62
+}
63
+
64
+func exit(params []string) error {
65
+	return errExit
66
+}
67
+
68
+func listcommands(params []string) error {
69
+	fmt.Println("Parameters noted within [] brackets, seperated by a comma")
70
+	fmt.Println("Defaults notated as [value=default]")
71
+	fmt.Println("Available commands: ")
72
+	for v, _ := range cmds {
73
+		if v == "" {
74
+			continue
75
+		}
76
+		if vh, ok := helpm[v]; ok {
77
+			fmt.Printf(" * %10s    %s\n", v, vh)
78
+			continue
79
+		}
80
+		fmt.Printf(" * %10s\n", v)
81
+	}
82
+	return nil
83
+}

+ 68
- 0
parser.go View File

@@ -0,0 +1,68 @@
1
+package chocococon
2
+
3
+import (
4
+	"bufio"
5
+	"github.com/chzyer/readline"
6
+	"strconv"
7
+	"strings"
8
+)
9
+
10
+func makeTokens(inp string) []string {
11
+	var (
12
+		stringList = []string{}
13
+		crString   = ""
14
+		isInEscape = false
15
+	)
16
+	for k := range []rune(inp) {
17
+		if !isInEscape {
18
+			if inp[k] == '\\' {
19
+				isInEscape = true
20
+				continue
21
+			} else {
22
+				if inp[k] == ',' {
23
+					stringList = append(stringList, crString)
24
+					crString = ""
25
+					continue
26
+				}
27
+				crString += string(inp[k])
28
+			}
29
+		} else {
30
+			crString += string(inp[k])
31
+			isInEscape = false
32
+		}
33
+	}
34
+	return append(stringList, crString)
35
+}
36
+
37
+func readCmdLine(inp *bufio.Reader) (string, error) {
38
+	str, err := readline.Line("RLagCON> ")
39
+	readline.AddHistory(str)
40
+	return str, err
41
+}
42
+
43
+func parseParamToFloat64(paramName string, paramTar *float64, value string) error {
44
+	value = strings.TrimSpace(value)
45
+	if strings.HasPrefix(value, paramName+"=") {
46
+		value = strings.TrimPrefix(value, paramName+"=")
47
+		fl, err := strconv.ParseFloat(value, 64)
48
+		if err != nil {
49
+			return err
50
+		}
51
+		*paramTar = fl
52
+	}
53
+	return nil
54
+}
55
+
56
+func parseParamToInt16(paramName string, paramTar *int16, value string) error {
57
+	value = strings.TrimSpace(value)
58
+	if strings.HasPrefix(value, paramName+"=") {
59
+		value = strings.TrimPrefix(value, paramName+"=")
60
+		fl, err := strconv.ParseInt(value, 10, 16)
61
+		if err != nil {
62
+			return err
63
+		}
64
+		flt := int16(fl)
65
+		*paramTar = flt
66
+	}
67
+	return nil
68
+}

+ 14
- 0
parser_test.go View File

@@ -0,0 +1,14 @@
1
+package chocococon
2
+
3
+import (
4
+	"github.com/stretchr/testify/require"
5
+	"testing"
6
+)
7
+
8
+func TestTokenSeperation(t *testing.T) {
9
+	assert := require.New(t)
10
+	assert.EqualValues([]string{"go"}, makeTokens("go"))
11
+	assert.EqualValues([]string{"go", "8"}, makeTokens("go,8"))
12
+	assert.EqualValues([]string{"go,", "8"}, makeTokens("go\\,,8"))
13
+	assert.EqualValues([]string{"opendev", "/dev/tty0", "bus0", "newline=,\n"}, makeTokens("opendev,/dev/tty0,bus0,newline=\\,\n"))
14
+}

+ 22
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/HardwareControl.json View File

@@ -0,0 +1,22 @@
1
+{
2
+	"ServoControlBus":1,
3
+	"ServoRollChannel":5,
4
+	"ServoRollMax":500,
5
+	"ServoRollMin":140,
6
+	"ServoRollMid":310,
7
+	"ServoRotateChannel":14,
8
+	"ServoRotateMax":500,
9
+	"ServoRotateMin":140,
10
+	"ServoRotateMid":307,
11
+	"ThreeDControlPort":"/dev/ttyUSB0",
12
+	"ThreeDControlCustomLogger":false,
13
+	"Speed":600,
14
+	"SpeedXYOffset":0,
15
+	"SpeedZOffset":900,
16
+	"RegalAnzahl":3,
17
+	"SettingApplyTime":1,
18
+	"MaxMoveTimeOut":20,
19
+	"AuslieferungX":0,
20
+	"AuslieferungY":0,
21
+	"AuslieferungZ":0
22
+}

+ 12
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/Regal0.json View File

@@ -0,0 +1,12 @@
1
+{
2
+    "RegalID":0,
3
+    "ServoRotateOffset":0,
4
+    "RegalstartX":0,       
5
+    "RegalstartY":0,       
6
+    "RegalstartZ":0,       
7
+    "Fachary":{"0":{"Position":1,"Offset":0},"1":{"Position":2,"Offset":0}},      
8
+    "Fachoffset":0,   
9
+    "Pickupoffset":0,
10
+    "PickupMove":{"XOffset":0,"YOffset":0},
11
+    "PickupSpeed":{"XYspeedOffset":0,"ZspeedOffset":0}
12
+}

+ 12
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/Regal1.json View File

@@ -0,0 +1,12 @@
1
+{
2
+    "RegalID":1,
3
+    "ServoRotateOffset":0,
4
+    "RegalstartX":0,       
5
+    "RegalstartY":0,       
6
+    "RegalstartZ":0,       
7
+    "Fachary":{"0":{"Position":1,"Offset":0},"1":{"Position":2,"Offset":0}},   
8
+    "Fachoffset":0,   
9
+    "Pickupoffset":0,
10
+    "PickupMove":{"XOffset":0,"YOffset":0},
11
+    "PickupSpeed":{"XYspeedOffset":0,"ZspeedOffset":0}
12
+}

+ 12
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/Regal2.json View File

@@ -0,0 +1,12 @@
1
+{
2
+    "RegalID":2,
3
+    "ServoRotateOffset":0,
4
+    "RegalstartX":0,       
5
+    "RegalstartY":0,       
6
+    "RegalstartZ":0,       
7
+    "Fachary":{"0":{"Position":1,"Offset":0},"1":{"Position":2,"Offset":0}},    
8
+    "Fachoffset":0,   
9
+    "Pickupoffset":0,
10
+    "PickupMove":{"XOffset":0,"YOffset":0},
11
+    "PickupSpeed":{"XYspeedOffset":0,"ZspeedOffset":0}
12
+}

+ 45
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/StructContainer.go View File

@@ -0,0 +1,45 @@
1
+package Config
2
+
3
+type HardwareControlMainConfig struct {
4
+	ServoControlBus    byte
5
+	ServoRollChannel   byte
6
+	ServoRollMax       int16
7
+	ServoRollMin       int16
8
+	ServoRollMid       int16
9
+	ServoRotateChannel byte
10
+	ServoRotateMax     int16
11
+	ServoRotateMin     int16
12
+	ServoRotateMid     int16
13
+	SettingApplyTime   int32
14
+	MaxMoveTimeOut     int64
15
+	//########################
16
+	//Sangu-3D-Controller
17
+	//########################
18
+	ThreeDControlPort         string
19
+	ThreeDControlCustomLogger bool
20
+	//########################
21
+	//Movment Config
22
+	//########################
23
+	Speed         int16
24
+	SpeedXYOffset int16
25
+	SpeedZOffset  int16
26
+	//########################
27
+	//Storage Config
28
+	//########################
29
+	RegalAnzahl   int32
30
+	AuslieferungX float64
31
+	AuslieferungY float64
32
+	AuslieferungZ float64
33
+}
34
+type Regal struct {
35
+	RegalID           int32
36
+	ServoRotateOffset int16
37
+	RegalstartX       float64
38
+	RegalstartY       float64
39
+	RegalstartZ       float64
40
+	Fachary           map[int32]map[string]float64
41
+	Fachoffset        float64
42
+	Pickupoffset      float64
43
+	PickupMove        map[string]float64
44
+	PickupSpeed       map[string]int16
45
+}

+ 246
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/HardwareControl/HardwareControl.go View File

@@ -0,0 +1,246 @@
1
+package HardwareControl
2
+
3
+import (
4
+	"encoding/json"
5
+	"errors"
6
+	"log"
7
+	"os"
8
+
9
+	"fmt"
10
+
11
+	"time"
12
+
13
+	"sync"
14
+
15
+	"git.timschuster.info/stephan.graf/Complete_hardware_Control/Config"
16
+	"git.timschuster.info/stephan.graf/SanguControl"
17
+	"go.rls.moe/misc/adafruitPCA9685"
18
+)
19
+
20
+type HardwareControl struct {
21
+	servoroll     *adafruitPCA9685.Servo
22
+	servorotate   *adafruitPCA9685.Servo
23
+	ThreeDControl *SanguControl.Schrittmotorcontroller
24
+	Logger        *log.Logger
25
+	config        *Config.HardwareControlMainConfig
26
+	regalConfigs  map[int32]*Config.Regal
27
+	locker        *sync.Mutex
28
+	storagelock   *sync.Mutex
29
+}
30
+
31
+//###############################
32
+//Override Basic Hardware Control
33
+//###############################
34
+
35
+func (h *HardwareControl) waitforarrival() error {
36
+	starttime := time.Now().Unix()
37
+	for {
38
+		tx, ty, tz, err := h.ThreeDControl.Getposition(true)
39
+		if err != nil {
40
+			h.Logger.Panicf("Error while waiting for Position %s", err.Error())
41
+			h.Shutdown()
42
+		}
43
+		x, y, z, err := h.ThreeDControl.Getposition(false)
44
+		if err != nil {
45
+			h.Logger.Panicf("Error while waiting for Position %s", err.Error())
46
+			h.Shutdown()
47
+		}
48
+		if x-tx == 0 && y-ty == 0 && z-tz == 0 {
49
+			break
50
+		}
51
+		if (time.Now().Unix() - starttime) >= h.config.MaxMoveTimeOut {
52
+			h.Logger.Fatal("Actuel move is impossible to complete TIMEOUT!!")
53
+			return errors.New("TIMEOUT at waiting for coord response at getcurrentposition")
54
+		}
55
+		//deshalb weil ich net will dass er den 3D-Controller zu tode penetriert
56
+		time.Sleep(time.Second * 2)
57
+	}
58
+	return nil
59
+}
60
+func (h *HardwareControl) waitforchangestoapply() {
61
+	time.Sleep(time.Second * time.Duration(h.config.SettingApplyTime))
62
+}
63
+
64
+//MoveTo bewege zur angegebenen Poistion erst x,y dann z
65
+func (h *HardwareControl) MoveTo(X float64, Y float64, Z float64, xyspeedoffset int16, zspeedoffset int16) {
66
+	h.locker.Lock()
67
+	h.ThreeDControl.Setspeed(h.config.Speed + h.config.SpeedXYOffset + xyspeedoffset)
68
+	h.waitforchangestoapply()
69
+	h.ThreeDControl.Moveto(X, Y, -1)
70
+	err := h.waitforarrival()
71
+	if err != nil {
72
+		h.Logger.Panic("Something is wrong shutting down!")
73
+		h.locker.Unlock()
74
+		h.Shutdown()
75
+	}
76
+	h.ThreeDControl.Setspeed(h.config.Speed + h.config.SpeedZOffset + zspeedoffset)
77
+	h.waitforchangestoapply()
78
+	h.ThreeDControl.Moveto(-1, -1, Z)
79
+	h.waitforarrival()
80
+	if err != nil {
81
+		h.Logger.Panic("Something is wrong shutting down!")
82
+		h.locker.Unlock()
83
+		h.Shutdown()
84
+	}
85
+	h.ThreeDControl.Setspeed(h.config.Speed)
86
+	h.locker.Unlock()
87
+}
88
+
89
+//Roll Rolle zum angegebenen Winkel
90
+func (h *HardwareControl) Roll(angle int16) {
91
+	h.servoroll.TurnTo(angle)
92
+}
93
+
94
+//Rotate Rotate zum angegebenen Winkel
95
+func (h *HardwareControl) Rotate(angle int16) {
96
+	h.servorotate.TurnTo(angle)
97
+}
98
+
99
+//###############################
100
+//Storage functions
101
+//###############################
102
+
103
+//Deliver hole aus der genanntenBox die Schachtel und transpotiere diese zum Auswurf
104
+func (h *HardwareControl) Deliver(regalnumber int32, boxnumber int32) {
105
+	h.storagelock.Lock()
106
+	if reg, ok := h.regalConfigs[regalnumber]; ok {
107
+		if fach, ok := reg.Fachary[boxnumber]; ok {
108
+			zpos := reg.RegalstartZ + fach["Position"]*reg.Fachoffset + fach["Offset"]
109
+			h.MoveTo(reg.RegalstartX, reg.RegalstartY, zpos, 0, 0)
110
+			h.Rotate(h.servoroll.MiddleAngle() + reg.ServoRotateOffset)
111
+			h.waitforchangestoapply()
112
+			h.MoveTo(reg.RegalstartX+reg.PickupMove["XOffset"],
113
+				reg.RegalstartY+reg.PickupMove["YOffset"],
114
+				-1, reg.PickupSpeed["XYspeedOffset"], 0)
115
+			h.MoveTo(-1, -1, reg.RegalstartZ+reg.Pickupoffset, 0, reg.PickupSpeed["ZspeedOffset"])
116
+			h.MoveTo(reg.RegalstartX, reg.RegalstartY, -1, reg.PickupSpeed["XYspeedOffset"], 0)
117
+			h.Rotate(h.servoroll.MiddleAngle())
118
+			h.MoveTo(h.config.AuslieferungX, h.config.AuslieferungY, h.config.AuslieferungZ, 0, 0)
119
+		}
120
+	}
121
+	h.storagelock.Unlock()
122
+}
123
+
124
+//PutIn Lagere aktuelle Ladung auf gabel in boxnumber ein
125
+func (h *HardwareControl) PutIn(regalnumber int32, boxnumber int32) {
126
+	h.storagelock.Lock()
127
+
128
+	h.storagelock.Unlock()
129
+}
130
+
131
+//PickUp fahre zum Schachtelaufnamepunkt
132
+func (h *HardwareControl) PickUp() {
133
+	h.storagelock.Lock()
134
+
135
+	h.storagelock.Unlock()
136
+}
137
+
138
+//###############################
139
+//Manage Function
140
+//###############################
141
+
142
+func (h *HardwareControl) readconfig(path string) int32 {
143
+	if h.getstructoutfjsonfile(path+"HardwareControl.json", &h.config) < 0 {
144
+		h.Logger.Panic("No Main Config stopping HardwareControl")
145
+		return -1
146
+	}
147
+	h.regalConfigs = make(map[int32]*Config.Regal)
148
+	if h.config.RegalAnzahl > 0 {
149
+		for i := int32(0); i < h.config.RegalAnzahl; i++ {
150
+			tmp := Config.Regal{}
151
+			if h.getstructoutfjsonfile(path+"Regal"+fmt.Sprintf("%d", i)+".json", &tmp) < 0 {
152
+				h.Logger.Fatal("Could not add Regalconfig for file" + path + "Regal" + fmt.Sprintf("%d", i) + ".json")
153
+			} else {
154
+				h.regalConfigs[tmp.RegalID] = &tmp
155
+			}
156
+		}
157
+	}
158
+	return 0
159
+}
160
+
161
+func (h *HardwareControl) getstructoutfjsonfile(path string, typ interface{}) int32 {
162
+	file, err := os.Open(path)
163
+	if err != nil {
164
+		h.Logger.Fatalf("Error while open Config file: %s", err.Error())
165
+		return -1
166
+	}
167
+	decoder := json.NewDecoder(file)
168
+	err = decoder.Decode(&typ)
169
+	if err != nil {
170
+		h.Logger.Fatalf("Error while reading Config file: %s", err.Error())
171
+		return -1
172
+	}
173
+	return 0
174
+}
175
+
176
+//NewHardwareControl erstelle ein neues voll init. HardwareControl
177
+func NewHardwareControl(logger *log.Logger, path string) *HardwareControl {
178
+	object := HardwareControl{}
179
+	object.locker = &sync.Mutex{}
180
+	object.storagelock = &sync.Mutex{}
181
+	object.Logger = logger
182
+	if object.readconfig(path) < 0 {
183
+		object.Logger.Panic("Config Faild cannot work without main Config Shutting Down!")
184
+		return nil
185
+	}
186
+	//Setup Servos
187
+	tmpadafruit, err := adafruitPCA9685.NewPCA9685(nil, object.config.ServoControlBus, object.Logger)
188
+	if err != nil {
189
+		object.Logger.Panic("Cannot Init Servos Shutting Down")
190
+		return nil
191
+	}
192
+	object.servoroll, err = adafruitPCA9685.NewServo(tmpadafruit,
193
+		object.config.ServoRollChannel,
194
+		object.config.ServoRollMid,
195
+		object.config.ServoRollMin,
196
+		object.config.ServoRollMax,
197
+		object.config.ServoRollMid)
198
+	if err != nil {
199
+		object.Logger.Panic("Cannot setup Roll Servo Shutting Down")
200
+		return nil
201
+	}
202
+	object.servorotate, err = adafruitPCA9685.NewServo(tmpadafruit,
203
+		object.config.ServoRotateChannel,
204
+		object.config.ServoRotateMid,
205
+		object.config.ServoRotateMin,
206
+		object.config.ServoRotateMax,
207
+		object.config.ServoRotateMid)
208
+	if err != nil {
209
+		object.Logger.Panic("Cannot setup Rotate Servo Shutting Down")
210
+		object.servoroll.DisableSignal()
211
+		return nil
212
+	}
213
+	//Setup 3D-Controller
214
+	object.ThreeDControl = SanguControl.NewSchrittmotorController(object.config.ThreeDControlPort,
215
+		object.Logger,
216
+		object.config.ThreeDControlCustomLogger)
217
+	if object.ThreeDControl == nil {
218
+		object.Logger.Panic("Cannot setup 3D-Controller see log for more info")
219
+		object.servoroll.DisableSignal()
220
+		object.servorotate.DisableSignal()
221
+		return nil
222
+	}
223
+	object.ThreeDControl.Movehome()
224
+	object.waitforarrival()
225
+	object.Logger.Print("Setup successfull all Hardware is functional")
226
+	return &object
227
+}
228
+
229
+//Restart kompletter Neustart schalter gibt an ob auch die config neu gelesen werden soll
230
+func (h *HardwareControl) Restart(readconfig bool) {
231
+	//nothing todo atm useless
232
+}
233
+
234
+//Shutdown ShutdownHardware for safty
235
+func (h *HardwareControl) Shutdown() {
236
+	h.locker.Lock()
237
+	h.ThreeDControl.Movehome()
238
+	h.servoroll.DisableSignal()
239
+	h.servorotate.DisableSignal()
240
+	h.locker.Unlock()
241
+}
242
+
243
+//GetThreeDControl Gibt dir den Kompletten 3DController !!DirektZugriff auf den 3DController ist risky aufpassen!!
244
+func (h *HardwareControl) GetThreeDControl() *SanguControl.Schrittmotorcontroller {
245
+	return h.ThreeDControl
246
+}

+ 3
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/README.md View File

@@ -0,0 +1,3 @@
1
+Complete_Hardware_Control_for everything
2
+----------------------------------------
3
+

BIN
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/RP2_Pinout.png View File


BIN
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/servertest View File


+ 51
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/servertest.go View File

@@ -0,0 +1,51 @@
1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"log"
6
+	"net/http"
7
+	"strings"
8
+)
9
+
10
+type httphandlerrework struct {
11
+}
12
+
13
+// formatRequest generates ascii representation of a request
14
+func formatRequest(r *http.Request) string {
15
+	// Create return string
16
+	var request []string
17
+	// Add the request string
18
+	url := fmt.Sprintf("%v %v %v", r.Method, r.URL, r.Proto)
19
+	request = append(request, fmt.Sprintf("%v", r.URL.Query()))
20
+	request = append(request, url)
21
+	// Add the host
22
+	request = append(request, fmt.Sprintf("Host: %v", r.Host))
23
+	// Loop through headers
24
+	for name, headers := range r.Header {
25
+		name = strings.ToLower(name)
26
+		for _, h := range headers {
27
+			request = append(request, fmt.Sprintf("%v: %v", name, h))
28
+		}
29
+	}
30
+
31
+	// If this is a POST, add post data
32
+	if r.Method == "POST" {
33
+		r.ParseForm()
34
+		request = append(request, "\n")
35
+		request = append(request, r.Form.Encode())
36
+	}
37
+	// Return the request as a string
38
+	return strings.Join(request, "\n")
39
+}
40
+
41
+func (h *httphandlerrework) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
42
+	//	fmt.Println("s%", formatRequest(req))
43
+	fmt.Fprint(writer, formatRequest(req))
44
+}
45
+
46
+func main() {
47
+	err := http.ListenAndServe("localhost:33949", &httphandlerrework{}) // set listen port
48
+	if err != nil {
49
+		log.Fatal("ListenAndServe: ", err)
50
+	}
51
+}

+ 14
- 0
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/test.go View File

@@ -0,0 +1,14 @@
1
+package main
2
+
3
+import (
4
+	"log"
5
+	"os"
6
+
7
+	"./HardwareControl"
8
+)
9
+
10
+func main() {
11
+	logger := log.New(os.Stderr, "hardwareControl", log.LUTC|log.Llongfile)
12
+	object := HardwareControl.NewHardwareControl(logger, "Config/")
13
+	object.Restart(false)
14
+}

+ 8
- 0
vendor/git.timschuster.info/stephan.graf/SanguControl/README.md View File

@@ -0,0 +1,8 @@
1
+Code for den Sangolulu... teil
2
+==============================
3
+
4
+Der Code is Gottgleich und bedarf keinerlei Changes
5
+---------------------------------------------------
6
+
7
+wollte nur ascii verwenden deshalb extremes DENGLISH!!
8
+------------------------------------------------------

+ 385
- 0
vendor/git.timschuster.info/stephan.graf/SanguControl/sanguinololu_control.go View File

@@ -0,0 +1,385 @@
1
+package SanguControl
2
+
3
+import (
4
+	"errors"
5
+	"fmt"
6
+	"io"
7
+	"os"
8
+	"strconv"
9
+	"strings"
10
+
11
+	"bufio"
12
+
13
+	"log"
14
+
15
+	"time"
16
+
17
+	"sync"
18
+
19
+	"github.com/foize/go.fifo"
20
+	"github.com/jacobsa/go-serial/serial"
21
+)
22
+
23
+type Schrittmotorcontroller struct {
24
+	serialstream io.ReadWriteCloser
25
+	feedrate     int16
26
+	logger       *log.Logger
27
+	customlogger *log.Logger
28
+	coordbuff    *fifo.Queue
29
+	locker       *sync.Mutex
30
+}
31
+
32
+func (s *Schrittmotorcontroller) Moveto(X float64, Y float64, Z float64) {
33
+	//G1 Xnnn Ynnn Znnn Linear
34
+	s.locker.Lock()
35
+	var command = "G1 "
36
+	if X != -1 {
37
+		command = command + "X" + fmt.Sprintf("%f", X) + " "
38
+	}
39
+	if Y != -1 {
40
+		command = command + "Y" + fmt.Sprintf("%f", Y) + " "
41
+	}
42
+	if Z != -1 {
43
+		command = command + "Z" + fmt.Sprintf("%f", Z)
44
+	}
45
+	command = command + " F" + fmt.Sprintf("%d", s.feedrate) + "\n"
46
+	s.writecommand(command)
47
+	s.locker.Unlock()
48
+}
49
+
50
+func (s *Schrittmotorcontroller) Movehome() {
51
+	//G28
52
+	s.locker.Lock()
53
+	var command = "G28\n"
54
+	s.writecommand(command)
55
+	s.locker.Unlock()
56
+}
57
+func (s *Schrittmotorcontroller) parsefloat64(number string) (float64, error) {
58
+	val, err := strconv.ParseFloat(strings.TrimSpace(number), 64)
59
+	if err != nil {
60
+		s.logger.Fatalf("Error parsing input number: %s\n", err)
61
+		return 0, err
62
+	}
63
+	return val, nil
64
+}
65
+
66
+func (s *Schrittmotorcontroller) parsecoords(data string, targetcoords bool) (float64, float64, float64, error) {
67
+	//X:0.00 Y:0.00 Z:0.00 E:0.00 Count X: 0.00 Y:0.00 Z:0.00
68
+	responseparts := strings.Fields(data)
69
+	countpassed := targetcoords
70
+	xcoord := 0.0
71
+	ycoord := 0.0
72
+	zcoord := 0.0
73
+	var err error
74
+	for index, element := range responseparts {
75
+		if strings.HasPrefix(element, "Count") {
76
+			if countpassed {
77
+				break
78
+			}
79
+			countpassed = true
80
+		}
81
+		if countpassed {
82
+			if strings.HasPrefix(element, "X:") {
83
+				if targetcoords {
84
+					element = strings.TrimPrefix(element, "X:")
85
+					xcoord, err = s.parsefloat64(element)
86
+					if err != nil {
87
+						s.logger.Fatalf("Error parsing input number: %s\n", err)
88
+						return 0, 0, 0, err
89
+					}
90
+				} else {
91
+					xcoord, err = s.parsefloat64(responseparts[index+1])
92
+					if err != nil {
93
+						s.logger.Fatalf("Error parsing input number: %s\n", err)
94
+						return 0, 0, 0, err
95
+					}
96
+				}
97
+			} else if strings.HasPrefix(element, "Y:") {
98
+				element = strings.TrimPrefix(element, "Y:")
99
+				ycoord, err = s.parsefloat64(element)
100
+				if err != nil {
101
+					s.logger.Fatalf("Error parsing input number: %s\n", err)
102
+					return 0, 0, 0, err
103
+				}
104
+			} else if strings.HasPrefix(element, "Z:") {
105
+				element = strings.TrimPrefix(element, "Z:")
106
+				zcoord, err = s.parsefloat64(element)
107
+				if err != nil {
108
+					s.logger.Fatalf("Error parsing input number: %s\n", err)
109
+					return 0, 0, 0, err
110
+				}
111
+			}
112
+		}
113
+	}
114
+	return xcoord, ycoord, zcoord, nil
115
+}
116
+func (s *Schrittmotorcontroller) Reset() {
117
+	s.locker.Lock()
118
+	var command = "M999\n"
119
+	s.writecommand(command)
120
+	s.locker.Unlock()
121
+}
122
+func (s *Schrittmotorcontroller) Gettemp() {
123
+	s.locker.Lock()
124
+	var command = "M105\n"
125
+	s.writecommand(command)
126
+	s.locker.Unlock()
127
+}
128
+func (s *Schrittmotorcontroller) Killit() {
129
+	s.locker.Lock()
130
+	var command = "M112\n"
131
+	s.writecommand(command)
132
+	s.locker.Unlock()
133
+}
134
+func (s *Schrittmotorcontroller) Getposition(targetcoords bool) (float64, float64, float64, error) {
135
+	//M114
136
+	s.locker.Lock()
137
+	var command = "M114\n"
138
+	s.writecommand(command)
139
+	starttime := time.Now().Unix()
140
+	for {
141
+		answer := s.coordbuff.Next()
142
+		if answer != nil {
143
+			x, y, z, err := s.parsecoords(strings.TrimSpace(answer.(string)), targetcoords)
144
+			if err != nil {
145
+				s.logger.Fatalf("Got error by parsing Numbers %s\n", err.Error())
146
+				s.locker.Unlock()
147
+				return 0, 0, 0, err
148
+
149
+			}
150
+			s.locker.Unlock()
151
+			return x, y, z, nil
152
+		}
153
+		if (time.Now().Unix() - starttime) >= 2 {
154
+			s.logger.Fatal("after sending M114 getting no response from reader !!Timeout after 2sec!!")
155
+			s.customlogger.Fatal("after sending M114 getting no response from reader !!Timeout after 2sec!!")
156
+			s.locker.Unlock()
157
+			return 0, 0, 0, errors.New("TIMEOUT at waiting for coord response at getcurrentposition")
158
+		}
159
+	}
160
+}
161
+
162
+func (s *Schrittmotorcontroller) Setspeed(speed int16) {
163
+	if speed > 0 {
164
+		s.feedrate = speed
165
+	}
166
+}
167
+
168
+//float32 X=0,float32 Y=0,float32 Z=0,int
169
+// singlestep exsistiert nur zum manuellen bewegen!!
170
+func (s *Schrittmotorcontroller) Singlestep(X bool, Y bool, Z bool, steplength float64, reverse bool) {
171
+	//G91\nG1....\nG90\n
172
+	s.locker.Unlock()
173
+	var step = steplength
174
+	if reverse {
175
+		step = -1 * steplength
176
+	}
177
+	if X {
178
+		s.writecommand(fmt.Sprintf("G91\nG1 X%f\nG90\n", step))
179
+	} else if Y {
180
+		s.writecommand(fmt.Sprintf("G91\nG1 Y%f\nG90\n", step))
181
+	} else if Z {
182
+		s.writecommand(fmt.Sprintf("G91\nG1 Z%f\nG90\n", step))
183
+	}
184
+	s.locker.Unlock()
185
+}
186
+
187
+func (s *Schrittmotorcontroller) writecommand(command string) {
188
+	//DO NOT TOUCH IT
189
+	s.customlogger.Println("sending command " + command)
190
+	i, err := s.serialstream.Write([]byte(command))
191
+	if err != nil {
192
+		s.logger.Fatalf("Fatal error while writing: %d letters: %s\n", i, err.Error())
193
+	}
194
+}
195
+func (s *Schrittmotorcontroller) reader() {
196
+	//DO NOT TOUCH IT
197
+	s.customlogger.Println("Start reading from serial")
198
+	var reader = bufio.NewReader(s.serialstream)
199
+	for {
200
+		response, err := reader.ReadString('\n')
201
+		if err != nil {
202
+			s.logger.Fatal("Error while reding at serial port: " + err.Error())
203
+			return
204
+		}
205
+		s.customlogger.Print(response)
206
+		//check if command needsto be pushed in responsebuffer
207
+		if strings.HasPrefix(response, "X:") {
208
+			s.logger.Println("Found coord respone pushing it to fifo")
209
+			s.coordbuff.Add(response)
210
+		}
211
+	}
212
+}
213
+
214
+// NewSchrittmotorController braucht den pfad zum device in port und das flag logfile legt fest ob er fuer sein Command Logging
215
+//den ubergebenen Logger nimmt oder selber einen Anlegt der in das file sanguinololu.log schreibt !!Achtung!! übergebener logger
216
+//könnte zu viel overhead im logfile führen
217
+func NewSchrittmotorController(port string, logger *log.Logger, logfile bool) *Schrittmotorcontroller {
218
+	var schritt = Schrittmotorcontroller{}
219
+	var err error
220
+	schritt.locker = &sync.Mutex{}
221
+	options := serial.OpenOptions{
222
+		PortName:        port,
223
+		BaudRate:        250000,
224
+		DataBits:        8,
225
+		StopBits:        1,
226
+		MinimumReadSize: 1,
227
+	}
228
+	if logger == nil {
229
+		return nil
230
+	}
231
+	schritt.logger = logger
232
+	schritt.serialstream, err = serial.Open(options)
233
+	schritt.feedrate = 1500
234
+	if err != nil {
235
+		schritt.logger.Printf("%s", err)
236
+		return nil
237
+	}
238
+	//baue speziellen command logger auf
239
+	if logfile {
240
+		file, err := os.OpenFile("sanguinololu.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0660)
241
+		if err != nil {
242
+			schritt.logger.Fatal("3D-PrinterControl reader failed: " + err.Error())
243
+			return nil
244
+		}
245
+		schritt.customlogger = log.New(file, "sanguinololu: ", log.LUTC)
246
+	} else {
247
+		schritt.customlogger = logger
248
+	}
249
+	//lege fifo an fuer coordbuffer an
250
+	schritt.coordbuff = fifo.NewQueue()
251
+	//starte den reader am seriellenport
252
+	go schritt.reader()
253
+	return &schritt
254
+}
255
+
256
+// Keyboardcontrol mit vorsicht zu genießen startet eine komplett neue Controller
257
+//instanz mit consolen eingabe und logging auf die console
258
+func Keyboardcontrol() {
259
+	logger := log.New(os.Stderr, "sanguinololu", log.LUTC|log.Llongfile)
260
+	schritt := NewSchrittmotorController("/dev/ttyUSB0", logger, false)
261
+	bufin := bufio.NewReader(os.Stdin)
262
+	for {
263
+		fmt.Print("CMD> ")
264
+		command, err := bufin.ReadString('\n')
265
+		if err != nil {
266
+			return
267
+		}
268
+		command = strings.TrimSpace(command)
269
+		switch command {
270
+		case "G28":
271
+			schritt.Movehome()
272
+		case "M114":
273
+			fmt.Println(schritt.Getposition(false))
274
+		case "M114 target":
275
+			fmt.Println(schritt.Getposition(true))
276
+		case "x":
277
+			schritt.Singlestep(true, false, false, 1.0, false)
278
+		case "y":
279
+			schritt.Singlestep(false, true, false, 1.0, false)
280
+		case "z":
281
+			schritt.Singlestep(false, false, true, 1.0, false)
282
+		case "-x":
283
+			schritt.Singlestep(true, false, false, 1.0, true)
284
+		case "-y":
285
+			schritt.Singlestep(false, true, false, 1.0, true)
286
+		case "-z":
287
+			schritt.Singlestep(false, false, true, 1.0, true)
288
+		case "x2":
289
+			schritt.Singlestep(true, false, false, 0.5, false)
290
+		case "y2":
291
+			schritt.Singlestep(false, true, false, 0.5, false)
292
+		case "z2":
293
+			schritt.Singlestep(false, false, true, 0.5, false)
294
+		case "-x2":
295
+			schritt.Singlestep(true, false, false, 0.5, true)
296
+		case "-y2":
297
+			schritt.Singlestep(false, true, false, 0.5, true)
298
+		case "-z2":
299
+			schritt.Singlestep(false, false, true, 0.5, true)
300
+		case "x25":
301
+			schritt.Singlestep(true, false, false, 0.25, false)
302
+		case "y25":
303
+			schritt.Singlestep(false, true, false, 0.25, false)
304
+		case "z25":
305
+			schritt.Singlestep(false, false, true, 0.25, false)
306
+		case "-x25":
307
+			schritt.Singlestep(true, false, false, 0.25, true)
308
+		case "-y25":
309
+			schritt.Singlestep(false, true, false, 0.25, true)
310
+		case "-z25":
311
+			schritt.Singlestep(false, false, true, 0.25, true)
312
+		case "x8":
313
+			schritt.Singlestep(true, false, false, 0.125, false)
314
+		case "y8":
315
+			schritt.Singlestep(false, true, false, 0.125, false)
316
+		case "z8":
317
+			schritt.Singlestep(false, false, true, 0.125, false)
318
+		case "-x8":
319
+			schritt.Singlestep(true, false, false, 0.125, true)
320
+		case "-y8":
321
+			schritt.Singlestep(false, true, false, 0.125, true)
322
+		case "-z8":
323
+			schritt.Singlestep(false, false, true, 0.125, true)
324
+		case "M999":
325
+			schritt.Reset()
326
+		case "M105":
327
+			schritt.Gettemp()
328
+		case "M112":
329
+			schritt.Killit()
330
+		default:
331
+			if strings.HasPrefix(command, "G1 ") {
332
+				command = strings.TrimPrefix(command, "G1 ")
333
+				command = strings.TrimSpace(command)
334
+				commadparts := strings.Fields(command)
335
+				xcoord := -1.0
336
+				ycoord := -1.0
337
+				zcoord := -1.0
338
+				if commadparts[0][0] == 'X' {
339
+					command = strings.TrimPrefix(commadparts[0], "X")
340
+					val, err := strconv.ParseFloat(strings.TrimSpace(command), 64)
341
+					if err != nil {
342
+						fmt.Printf("Error reading command: %s\n", err)
343
+						return
344
+					}
345
+					xcoord = val
346
+
347
+				}
348
+				if commadparts[1][0] == 'Y' {
349
+					command = strings.TrimPrefix(commadparts[1], "Y")
350
+					val, err := strconv.ParseFloat(strings.TrimSpace(command), 64)
351
+					if err != nil {
352
+						fmt.Printf("Error reading command: %s\n", err)
353
+						return
354
+					}
355
+					ycoord = val
356
+
357
+				}
358
+				if commadparts[2][0] == 'Z' {
359
+					command = strings.TrimPrefix(commadparts[2], "Z")
360
+					val, err := strconv.ParseFloat(strings.TrimSpace(command), 64)
361
+					if err != nil {
362
+						fmt.Printf("Error reading command: %s\n", err)
363
+						return
364
+					}
365
+					zcoord = val
366
+
367
+				}
368
+				schritt.Moveto(xcoord, ycoord, zcoord)
369
+			} else if strings.HasPrefix(command, "speed ") {
370
+				command = strings.TrimPrefix(command, "speed ")
371
+				val, err := strconv.Atoi(strings.TrimSpace(command))
372
+				if err != nil {
373
+					fmt.Printf("Error reading command: %s\n", err)
374
+					return
375
+				}
376
+				speed := int16(val)
377
+				schritt.Setspeed(speed)
378
+			}
379
+		}
380
+	}
381
+}
382
+
383
+/*func main() {
384
+	Keyboardcontrol()
385
+}*/

+ 58
- 0
vendor/github.com/chzyer/readline/CHANGELOG.md View File

@@ -0,0 +1,58 @@
1
+# ChangeLog
2
+
3
+### 1.4 - 2016-07-25
4
+
5
+* [#60][60] Support dynamic autocompletion
6
+* Fix ANSI parser on Windows
7
+* Fix wrong column width in complete mode on Windows
8
+* Remove dependent package "golang.org/x/crypto/ssh/terminal"
9
+
10
+### 1.3 - 2016-05-09
11
+
12
+* [#38][38] add SetChildren for prefix completer interface
13
+* [#42][42] improve multiple lines compatibility
14
+* [#43][43] remove sub-package(runes) for gopkg compatiblity
15
+* [#46][46] Auto complete with space prefixed line
16
+* [#48][48]	support suspend process (ctrl+Z)
17
+* [#49][49] fix bug that check equals with previous command
18
+* [#53][53] Fix bug which causes integer divide by zero panicking when input buffer is empty
19
+
20
+### 1.2 - 2016-03-05
21
+
22
+* Add a demo for checking password strength [example/readline-pass-strength](https://github.com/chzyer/readline/blob/master/example/readline-pass-strength/readline-pass-strength.go), , written by [@sahib](https://github.com/sahib)
23
+* [#23][23], support stdin remapping
24
+* [#27][27], add a `UniqueEditLine` to `Config`, which will erase the editing line after user submited it, usually use in IM.
25
+* Add a demo for multiline [example/readline-multiline](https://github.com/chzyer/readline/blob/master/example/readline-multiline/readline-multiline.go) which can submit one SQL by multiple lines.
26
+* Supports performs even stdin/stdout is not a tty.
27
+* Add a new simple apis for single instance, check by [here](https://github.com/chzyer/readline/blob/master/std.go). It need to save history manually if using this api.
28
+* [#28][28], fixes the history is not working as expected.
29
+* [#33][33], vim mode now support `c`, `d`, `x (delete character)`, `r (replace character)`
30
+
31
+### 1.1 - 2015-11-20
32
+
33
+* [#12][12] Add support for key `<Delete>`/`<Home>`/`<End>`
34
+* Only enter raw mode as needed (calling `Readline()`), program will receive signal(e.g. Ctrl+C) if not interact with `readline`.
35
+* Bugs fixed for `PrefixCompleter`
36
+* Press `Ctrl+D` in empty line will cause `io.EOF` in error, Press `Ctrl+C` in anytime will cause `ErrInterrupt` instead of `io.EOF`, this will privodes a shell-like user experience.
37
+* Customable Interrupt/EOF prompt in `Config`
38
+* [#17][17] Change atomic package to use 32bit function to let it runnable on arm 32bit devices
39
+* Provides a new password user experience(`readline.ReadPasswordEx()`).
40
+
41
+### 1.0 - 2015-10-14
42
+
43
+* Initial public release.
44
+
45
+[12]: https://github.com/chzyer/readline/pull/12
46
+[17]: https://github.com/chzyer/readline/pull/17
47
+[23]: https://github.com/chzyer/readline/pull/23
48
+[27]: https://github.com/chzyer/readline/pull/27
49
+[28]: https://github.com/chzyer/readline/pull/28
50
+[33]: https://github.com/chzyer/readline/pull/33
51
+[38]: https://github.com/chzyer/readline/pull/38
52
+[42]: https://github.com/chzyer/readline/pull/42
53
+[43]: https://github.com/chzyer/readline/pull/43
54
+[46]: https://github.com/chzyer/readline/pull/46
55
+[48]: https://github.com/chzyer/readline/pull/48
56
+[49]: https://github.com/chzyer/readline/pull/49
57
+[53]: https://github.com/chzyer/readline/pull/53
58
+[60]: https://github.com/chzyer/readline/pull/60

+ 22
- 0
vendor/github.com/chzyer/readline/LICENSE View File

@@ -0,0 +1,22 @@
1
+The MIT License (MIT)
2
+
3
+Copyright (c) 2015 Chzyer
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.
22
+

+ 114
- 0
vendor/github.com/chzyer/readline/README.md View File

@@ -0,0 +1,114 @@
1
+[![Build Status](https://travis-ci.org/chzyer/readline.svg?branch=master)](https://travis-ci.org/chzyer/readline)
2
+[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE.md)
3
+[![Version](https://img.shields.io/github/tag/chzyer/readline.svg)](https://github.com/chzyer/readline/releases)
4
+[![GoDoc](https://godoc.org/github.com/chzyer/readline?status.svg)](https://godoc.org/github.com/chzyer/readline)
5
+[![OpenCollective](https://opencollective.com/readline/badge/backers.svg)](#backers)
6
+[![OpenCollective](https://opencollective.com/readline/badge/sponsors.svg)](#sponsors)
7
+
8
+<p align="center">
9
+<img src="https://raw.githubusercontent.com/chzyer/readline/assets/logo.png" />
10
+<a href="https://asciinema.org/a/32oseof9mkilg7t7d4780qt4m" target="_blank"><img src="https://asciinema.org/a/32oseof9mkilg7t7d4780qt4m.png" width="654"/></a>
11
+<img src="https://raw.githubusercontent.com/chzyer/readline/assets/logo_f.png" />
12
+</p>
13
+
14
+A powerful readline library in `Linux` `macOS` `Windows` `Solaris`
15
+
16
+## Guide
17
+
18
+* [Demo](example/readline-demo/readline-demo.go)
19
+* [Shortcut](doc/shortcut.md)
20
+
21
+## Repos using readline
22
+
23
+[![cockroachdb](https://img.shields.io/github/stars/cockroachdb/cockroach.svg?label=cockroachdb/cockroach)](https://github.com/cockroachdb/cockroach)
24
+[![robertkrimen/otto](https://img.shields.io/github/stars/robertkrimen/otto.svg?label=robertkrimen/otto)](https://github.com/robertkrimen/otto)
25
+[![empire](https://img.shields.io/github/stars/remind101/empire.svg?label=remind101/empire)](https://github.com/remind101/empire)
26
+[![mehrdadrad/mylg](https://img.shields.io/github/stars/mehrdadrad/mylg.svg?label=mehrdadrad/mylg)](https://github.com/mehrdadrad/mylg)
27
+[![knq/usql](https://img.shields.io/github/stars/knq/usql.svg?label=knq/usql)](https://github.com/knq/usql)
28
+[![youtube/doorman](https://img.shields.io/github/stars/youtube/doorman.svg?label=youtube/doorman)](https://github.com/youtube/doorman)
29
+[![bom-d-van/harp](https://img.shields.io/github/stars/bom-d-van/harp.svg?label=bom-d-van/harp)](https://github.com/bom-d-van/harp)
30
+[![abiosoft/ishell](https://img.shields.io/github/stars/abiosoft/ishell.svg?label=abiosoft/ishell)](https://github.com/abiosoft/ishell)
31
+[![Netflix/hal-9001](https://img.shields.io/github/stars/Netflix/hal-9001.svg?label=Netflix/hal-9001)](https://github.com/Netflix/hal-9001)
32
+[![docker/go-p9p](https://img.shields.io/github/stars/docker/go-p9p.svg?label=docker/go-p9p)](https://github.com/docker/go-p9p)
33
+
34
+
35
+## Feedback
36
+
37
+If you have any questions, please submit a github issue and any pull requests is welcomed :)
38
+
39
+* [https://twitter.com/chzyer](https://twitter.com/chzyer)
40
+* [http://weibo.com/2145262190](http://weibo.com/2145262190)
41
+
42
+
43
+## Backers
44
+
45
+Love Readline? Help me keep it alive by donating funds to cover project expenses!<br />
46
+[[Become a backer](https://opencollective.com/readline#backer)]
47
+
48
+<a href="https://opencollective.com/readline/backer/0/website" target="_blank"><img src="https://opencollective.com/readline/backer/0/avatar.svg"></a>
49
+<a href="https://opencollective.com/readline/backer/1/website" target="_blank"><img src="https://opencollective.com/readline/backer/1/avatar.svg"></a>
50
+<a href="https://opencollective.com/readline/backer/2/website" target="_blank"><img src="https://opencollective.com/readline/backer/2/avatar.svg"></a>
51
+<a href="https://opencollective.com/readline/backer/3/website" target="_blank"><img src="https://opencollective.com/readline/backer/3/avatar.svg"></a>
52
+<a href="https://opencollective.com/readline/backer/4/website" target="_blank"><img src="https://opencollective.com/readline/backer/4/avatar.svg"></a>
53
+<a href="https://opencollective.com/readline/backer/5/website" target="_blank"><img src="https://opencollective.com/readline/backer/5/avatar.svg"></a>
54
+<a href="https://opencollective.com/readline/backer/6/website" target="_blank"><img src="https://opencollective.com/readline/backer/6/avatar.svg"></a>
55
+<a href="https://opencollective.com/readline/backer/7/website" target="_blank"><img src="https://opencollective.com/readline/backer/7/avatar.svg"></a>
56
+<a href="https://opencollective.com/readline/backer/8/website" target="_blank"><img src="https://opencollective.com/readline/backer/8/avatar.svg"></a>
57
+<a href="https://opencollective.com/readline/backer/9/website" target="_blank"><img src="https://opencollective.com/readline/backer/9/avatar.svg"></a>
58
+<a href="https://opencollective.com/readline/backer/10/website" target="_blank"><img src="https://opencollective.com/readline/backer/10/avatar.svg"></a>
59
+<a href="https://opencollective.com/readline/backer/11/website" target="_blank"><img src="https://opencollective.com/readline/backer/11/avatar.svg"></a>
60
+<a href="https://opencollective.com/readline/backer/12/website" target="_blank"><img src="https://opencollective.com/readline/backer/12/avatar.svg"></a>
61
+<a href="https://opencollective.com/readline/backer/13/website" target="_blank"><img src="https://opencollective.com/readline/backer/13/avatar.svg"></a>
62
+<a href="https://opencollective.com/readline/backer/14/website" target="_blank"><img src="https://opencollective.com/readline/backer/14/avatar.svg"></a>
63
+<a href="https://opencollective.com/readline/backer/15/website" target="_blank"><img src="https://opencollective.com/readline/backer/15/avatar.svg"></a>
64
+<a href="https://opencollective.com/readline/backer/16/website" target="_blank"><img src="https://opencollective.com/readline/backer/16/avatar.svg"></a>
65
+<a href="https://opencollective.com/readline/backer/17/website" target="_blank"><img src="https://opencollective.com/readline/backer/17/avatar.svg"></a>
66
+<a href="https://opencollective.com/readline/backer/18/website" target="_blank"><img src="https://opencollective.com/readline/backer/18/avatar.svg"></a>
67
+<a href="https://opencollective.com/readline/backer/19/website" target="_blank"><img src="https://opencollective.com/readline/backer/19/avatar.svg"></a>
68
+<a href="https://opencollective.com/readline/backer/20/website" target="_blank"><img src="https://opencollective.com/readline/backer/20/avatar.svg"></a>
69
+<a href="https://opencollective.com/readline/backer/21/website" target="_blank"><img src="https://opencollective.com/readline/backer/21/avatar.svg"></a>
70
+<a href="https://opencollective.com/readline/backer/22/website" target="_blank"><img src="https://opencollective.com/readline/backer/22/avatar.svg"></a>
71
+<a href="https://opencollective.com/readline/backer/23/website" target="_blank"><img src="https://opencollective.com/readline/backer/23/avatar.svg"></a>
72
+<a href="https://opencollective.com/readline/backer/24/website" target="_blank"><img src="https://opencollective.com/readline/backer/24/avatar.svg"></a>
73
+<a href="https://opencollective.com/readline/backer/25/website" target="_blank"><img src="https://opencollective.com/readline/backer/25/avatar.svg"></a>
74
+<a href="https://opencollective.com/readline/backer/26/website" target="_blank"><img src="https://opencollective.com/readline/backer/26/avatar.svg"></a>
75
+<a href="https://opencollective.com/readline/backer/27/website" target="_blank"><img src="https://opencollective.com/readline/backer/27/avatar.svg"></a>
76
+<a href="https://opencollective.com/readline/backer/28/website" target="_blank"><img src="https://opencollective.com/readline/backer/28/avatar.svg"></a>
77
+<a href="https://opencollective.com/readline/backer/29/website" target="_blank"><img src="https://opencollective.com/readline/backer/29/avatar.svg"></a>
78
+
79
+
80
+## Sponsors
81
+
82
+Become a sponsor and get your logo here on our Github page. [[Become a sponsor](https://opencollective.com/readline#sponsor)]
83
+
84
+<a href="https://opencollective.com/readline/sponsor/0/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/0/avatar.svg"></a>
85
+<a href="https://opencollective.com/readline/sponsor/1/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/1/avatar.svg"></a>
86
+<a href="https://opencollective.com/readline/sponsor/2/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/2/avatar.svg"></a>
87
+<a href="https://opencollective.com/readline/sponsor/3/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/3/avatar.svg"></a>
88
+<a href="https://opencollective.com/readline/sponsor/4/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/4/avatar.svg"></a>
89
+<a href="https://opencollective.com/readline/sponsor/5/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/5/avatar.svg"></a>
90
+<a href="https://opencollective.com/readline/sponsor/6/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/6/avatar.svg"></a>
91
+<a href="https://opencollective.com/readline/sponsor/7/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/7/avatar.svg"></a>
92
+<a href="https://opencollective.com/readline/sponsor/8/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/8/avatar.svg"></a>
93
+<a href="https://opencollective.com/readline/sponsor/9/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/9/avatar.svg"></a>
94
+<a href="https://opencollective.com/readline/sponsor/10/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/10/avatar.svg"></a>
95
+<a href="https://opencollective.com/readline/sponsor/11/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/11/avatar.svg"></a>
96
+<a href="https://opencollective.com/readline/sponsor/12/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/12/avatar.svg"></a>
97
+<a href="https://opencollective.com/readline/sponsor/13/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/13/avatar.svg"></a>
98
+<a href="https://opencollective.com/readline/sponsor/14/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/14/avatar.svg"></a>
99
+<a href="https://opencollective.com/readline/sponsor/15/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/15/avatar.svg"></a>
100
+<a href="https://opencollective.com/readline/sponsor/16/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/16/avatar.svg"></a>
101
+<a href="https://opencollective.com/readline/sponsor/17/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/17/avatar.svg"></a>
102
+<a href="https://opencollective.com/readline/sponsor/18/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/18/avatar.svg"></a>
103
+<a href="https://opencollective.com/readline/sponsor/19/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/19/avatar.svg"></a>
104
+<a href="https://opencollective.com/readline/sponsor/20/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/20/avatar.svg"></a>
105
+<a href="https://opencollective.com/readline/sponsor/21/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/21/avatar.svg"></a>
106
+<a href="https://opencollective.com/readline/sponsor/22/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/22/avatar.svg"></a>
107
+<a href="https://opencollective.com/readline/sponsor/23/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/23/avatar.svg"></a>
108
+<a href="https://opencollective.com/readline/sponsor/24/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/24/avatar.svg"></a>
109
+<a href="https://opencollective.com/readline/sponsor/25/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/25/avatar.svg"></a>
110
+<a href="https://opencollective.com/readline/sponsor/26/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/26/avatar.svg"></a>
111
+<a href="https://opencollective.com/readline/sponsor/27/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/27/avatar.svg"></a>
112
+<a href="https://opencollective.com/readline/sponsor/28/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/28/avatar.svg"></a>
113
+<a href="https://opencollective.com/readline/sponsor/29/website" target="_blank"><img src="https://opencollective.com/readline/sponsor/29/avatar.svg"></a>
114
+

+ 246
- 0
vendor/github.com/chzyer/readline/ansi_windows.go View File

@@ -0,0 +1,246 @@
1
+// +build windows
2
+
3
+package readline
4
+
5
+import (
6
+	"bufio"
7
+	"io"
8
+	"strconv"
9
+	"strings"
10
+	"sync"
11
+	"unicode/utf8"
12
+	"unsafe"
13
+)
14
+
15
+const (
16
+	_                = uint16(0)
17
+	COLOR_FBLUE      = 0x0001
18
+	COLOR_FGREEN     = 0x0002
19
+	COLOR_FRED       = 0x0004
20
+	COLOR_FINTENSITY = 0x0008
21
+
22
+	COLOR_BBLUE      = 0x0010
23
+	COLOR_BGREEN     = 0x0020
24
+	COLOR_BRED       = 0x0040
25
+	COLOR_BINTENSITY = 0x0080
26
+
27
+	COMMON_LVB_UNDERSCORE = 0x8000
28
+)
29
+
30
+var ColorTableFg = []word{
31
+	0,                                       // 30: Black
32
+	COLOR_FRED,                              // 31: Red
33
+	COLOR_FGREEN,                            // 32: Green
34
+	COLOR_FRED | COLOR_FGREEN,               // 33: Yellow
35
+	COLOR_FBLUE,                             // 34: Blue
36
+	COLOR_FRED | COLOR_FBLUE,                // 35: Magenta
37
+	COLOR_FGREEN | COLOR_FBLUE,              // 36: Cyan
38
+	COLOR_FRED | COLOR_FBLUE | COLOR_FGREEN, // 37: White
39
+}
40
+
41
+var ColorTableBg = []word{
42
+	0,                                       // 40: Black
43
+	COLOR_BRED,                              // 41: Red
44
+	COLOR_BGREEN,                            // 42: Green
45
+	COLOR_BRED | COLOR_BGREEN,               // 43: Yellow
46
+	COLOR_BBLUE,                             // 44: Blue
47
+	COLOR_BRED | COLOR_BBLUE,                // 45: Magenta
48
+	COLOR_BGREEN | COLOR_BBLUE,              // 46: Cyan
49
+	COLOR_BRED | COLOR_BBLUE | COLOR_BGREEN, // 47: White
50
+}
51
+
52
+type ANSIWriter struct {
53
+	target io.Writer
54
+	wg     sync.WaitGroup
55
+	ctx    *ANSIWriterCtx
56
+	sync.Mutex
57
+}
58
+
59
+func NewANSIWriter(w io.Writer) *ANSIWriter {
60
+	a := &ANSIWriter{
61
+		target: w,
62
+		ctx:    NewANSIWriterCtx(w),
63
+	}
64
+	return a
65
+}
66
+
67
+func (a *ANSIWriter) Close() error {
68
+	a.wg.Wait()
69
+	return nil
70
+}
71
+
72
+type ANSIWriterCtx struct {
73
+	isEsc     bool
74
+	isEscSeq  bool
75
+	arg       []string
76
+	target    *bufio.Writer
77
+	wantFlush bool
78
+}
79
+
80
+func NewANSIWriterCtx(target io.Writer) *ANSIWriterCtx {
81
+	return &ANSIWriterCtx{
82
+		target: bufio.NewWriter(target),
83
+	}
84
+}
85
+
86
+func (a *ANSIWriterCtx) Flush() {
87
+	a.target.Flush()
88
+}
89
+
90
+func (a *ANSIWriterCtx) process(r rune) bool {
91
+	if a.wantFlush {
92
+		if r == 0 || r == CharEsc {
93
+			a.wantFlush = false
94
+			a.target.Flush()
95
+		}
96
+	}
97
+	if a.isEscSeq {
98
+		a.isEscSeq = a.ioloopEscSeq(a.target, r, &a.arg)
99
+		return true
100
+	}
101
+
102
+	switch r {
103
+	case CharEsc:
104
+		a.isEsc = true
105
+	case '[':
106
+		if a.isEsc {
107
+			a.arg = nil
108
+			a.isEscSeq = true
109
+			a.isEsc = false
110
+			break
111
+		}
112
+		fallthrough
113
+	default:
114
+		a.target.WriteRune(r)
115
+		a.wantFlush = true
116
+	}
117
+	return true
118
+}
119
+
120
+func (a *ANSIWriterCtx) ioloopEscSeq(w *bufio.Writer, r rune, argptr *[]string) bool {
121
+	arg := *argptr
122
+	var err error
123
+
124
+	if r >= 'A' && r <= 'D' {
125
+		count := short(GetInt(arg, 1))
126
+		info, err := GetConsoleScreenBufferInfo()
127
+		if err != nil {
128
+			return false
129
+		}
130
+		switch r {
131
+		case 'A': // up
132
+			info.dwCursorPosition.y -= count
133
+		case 'B': // down
134
+			info.dwCursorPosition.y += count
135
+		case 'C': // right
136
+			info.dwCursorPosition.x += count
137
+		case 'D': // left
138
+			info.dwCursorPosition.x -= count
139
+		}
140
+		SetConsoleCursorPosition(&info.dwCursorPosition)
141
+		return false
142
+	}
143
+
144
+	switch r {
145
+	case 'J':
146
+		killLines()
147
+	case 'K':
148
+		eraseLine()
149
+	case 'm':
150
+		color := word(0)
151
+		for _, item := range arg {
152
+			var c int
153
+			c, err = strconv.Atoi(item)
154
+			if err != nil {
155
+				w.WriteString("[" + strings.Join(arg, ";") + "m")
156
+				break
157
+			}
158
+			if c >= 30 && c < 40 {
159
+				color ^= COLOR_FINTENSITY
160
+				color |= ColorTableFg[c-30]
161
+			} else if c >= 40 && c < 50 {
162
+				color ^= COLOR_BINTENSITY
163
+				color |= ColorTableBg[c-40]
164
+			} else if c == 4 {
165
+				color |= COMMON_LVB_UNDERSCORE | ColorTableFg[7]
166
+			} else { // unknown code treat as reset
167
+				color = ColorTableFg[7]
168
+			}
169
+		}
170
+		if err != nil {
171
+			break
172
+		}
173
+		kernel.SetConsoleTextAttribute(stdout, uintptr(color))
174
+	case '\007': // set title
175
+	case ';':
176
+		if len(arg) == 0 || arg[len(arg)-1] != "" {
177
+			arg = append(arg, "")
178
+			*argptr = arg
179
+		}
180
+		return true
181
+	default:
182
+		if len(arg) == 0 {
183
+			arg = append(arg, "")
184
+		}
185
+		arg[len(arg)-1] += string(r)
186
+		*argptr = arg
187
+		return true
188
+	}
189
+	*argptr = nil
190
+	return false
191
+}
192
+
193
+func (a *ANSIWriter) Write(b []byte) (int, error) {
194
+	a.Lock()
195
+	defer a.Unlock()
196
+
197
+	off := 0
198
+	for len(b) > off {
199
+		r, size := utf8.DecodeRune(b[off:])
200
+		if size == 0 {
201
+			return off, io.ErrShortWrite
202
+		}
203
+		off += size
204
+		a.ctx.process(r)
205
+	}
206
+	a.ctx.Flush()
207
+	return off, nil
208
+}
209
+
210
+func killLines() error {
211
+	sbi, err := GetConsoleScreenBufferInfo()
212
+	if err != nil {
213
+		return err
214
+	}
215
+
216
+	size := (sbi.dwCursorPosition.y - sbi.dwSize.y) * sbi.dwSize.x
217
+	size += sbi.dwCursorPosition.x
218
+
219
+	var written int
220
+	kernel.FillConsoleOutputAttribute(stdout, uintptr(ColorTableFg[7]),
221
+		uintptr(size),
222
+		sbi.dwCursorPosition.ptr(),
223
+		uintptr(unsafe.Pointer(&written)),
224
+	)
225
+	return kernel.FillConsoleOutputCharacterW(stdout, uintptr(' '),
226
+		uintptr(size),
227
+		sbi.dwCursorPosition.ptr(),
228
+		uintptr(unsafe.Pointer(&written)),
229
+	)
230
+}
231
+
232
+func eraseLine() error {
233
+	sbi, err := GetConsoleScreenBufferInfo()
234
+	if err != nil {
235
+		return err
236
+	}
237
+
238
+	size := sbi.dwSize.x
239
+	sbi.dwCursorPosition.x = 0
240
+	var written int
241
+	return kernel.FillConsoleOutputCharacterW(stdout, uintptr(' '),
242
+		uintptr(size),
243
+		sbi.dwCursorPosition.ptr(),
244
+		uintptr(unsafe.Pointer(&written)),
245
+	)
246
+}

+ 283
- 0
vendor/github.com/chzyer/readline/complete.go View File

@@ -0,0 +1,283 @@
1
+package readline
2
+
3
+import (
4
+	"bufio"
5
+	"bytes"
6
+	"fmt"
7
+	"io"
8
+)
9
+
10
+type AutoCompleter interface {
11
+	// Readline will pass the whole line and current offset to it
12
+	// Completer need to pass all the candidates, and how long they shared the same characters in line
13
+	// Example:
14
+	//   [go, git, git-shell, grep]
15
+	//   Do("g", 1) => ["o", "it", "it-shell", "rep"], 1
16
+	//   Do("gi", 2) => ["t", "t-shell"], 2
17
+	//   Do("git", 3) => ["", "-shell"], 3
18
+	Do(line []rune, pos int) (newLine [][]rune, length int)
19
+}
20
+
21
+type TabCompleter struct{}
22
+
23
+func (t *TabCompleter) Do([]rune, int) ([][]rune, int) {
24
+	return [][]rune{[]rune("\t")}, 0
25
+}
26
+
27
+type opCompleter struct {
28
+	w     io.Writer
29
+	op    *Operation
30
+	width int
31
+
32
+	inCompleteMode  bool
33
+	inSelectMode    bool
34
+	candidate       [][]rune
35
+	candidateSource []rune
36
+	candidateOff    int
37
+	candidateChoise int
38
+	candidateColNum int
39
+}
40
+
41
+func newOpCompleter(w io.Writer, op *Operation, width int) *opCompleter {
42
+	return &opCompleter{
43
+		w:     w,
44
+		op:    op,
45
+		width: width,
46
+	}
47
+}
48
+
49
+func (o *opCompleter) doSelect() {
50
+	if len(o.candidate) == 1 {
51
+		o.op.buf.WriteRunes(o.candidate[0])
52
+		o.ExitCompleteMode(false)
53
+		return
54
+	}
55
+	o.nextCandidate(1)
56
+	o.CompleteRefresh()
57
+}
58
+
59
+func (o *opCompleter) nextCandidate(i int) {
60
+	o.candidateChoise += i
61
+	o.candidateChoise = o.candidateChoise % len(o.candidate)
62
+	if o.candidateChoise < 0 {
63
+		o.candidateChoise = len(o.candidate) + o.candidateChoise
64
+	}
65
+}
66
+
67
+func (o *opCompleter) OnComplete() bool {
68
+	if o.width == 0 {
69
+		return false
70
+	}
71
+	if o.IsInCompleteSelectMode() {
72
+		o.doSelect()
73
+		return true
74
+	}
75
+
76
+	buf := o.op.buf
77
+	rs := buf.Runes()
78
+
79
+	if o.IsInCompleteMode() && o.candidateSource != nil && runes.Equal(rs, o.candidateSource) {
80
+		o.EnterCompleteSelectMode()
81
+		o.doSelect()
82
+		return true
83
+	}
84
+
85
+	o.ExitCompleteSelectMode()
86
+	o.candidateSource = rs
87
+	newLines, offset := o.op.cfg.AutoComplete.Do(rs, buf.idx)
88
+	if len(newLines) == 0 {
89
+		o.ExitCompleteMode(false)
90
+		return true
91
+	}
92
+
93
+	// only Aggregate candidates in non-complete mode
94
+	if !o.IsInCompleteMode() {
95
+		if len(newLines) == 1 {
96
+			buf.WriteRunes(newLines[0])
97
+			o.ExitCompleteMode(false)
98
+			return true
99
+		}
100
+
101
+		same, size := runes.Aggregate(newLines)
102
+		if size > 0 {
103
+			buf.WriteRunes(same)
104
+			o.ExitCompleteMode(false)
105
+			return true
106
+		}
107
+	}
108
+
109
+	o.EnterCompleteMode(offset, newLines)
110
+	return true
111
+}
112
+
113
+func (o *opCompleter) IsInCompleteSelectMode() bool {
114
+	return o.inSelectMode
115
+}
116
+
117
+func (o *opCompleter) IsInCompleteMode() bool {
118
+	return o.inCompleteMode
119
+}
120
+
121
+func (o *opCompleter) HandleCompleteSelect(r rune) bool {
122
+	next := true
123
+	switch r {
124
+	case CharEnter, CharCtrlJ:
125
+		next = false
126
+		o.op.buf.WriteRunes(o.op.candidate[o.op.candidateChoise])
127
+		o.ExitCompleteMode(false)
128
+	case CharLineStart:
129
+		num := o.candidateChoise % o.candidateColNum
130
+		o.nextCandidate(-num)
131
+	case CharLineEnd:
132
+		num := o.candidateColNum - o.candidateChoise%o.candidateColNum - 1
133
+		o.candidateChoise += num
134
+		if o.candidateChoise >= len(o.candidate) {
135
+			o.candidateChoise = len(o.candidate) - 1
136
+		}
137
+	case CharBackspace:
138
+		o.ExitCompleteSelectMode()
139
+		next = false
140
+	case CharTab, CharForward:
141
+		o.doSelect()
142
+	case CharBell, CharInterrupt:
143
+		o.ExitCompleteMode(true)
144
+		next = false
145
+	case CharNext:
146
+		tmpChoise := o.candidateChoise + o.candidateColNum
147
+		if tmpChoise >= o.getMatrixSize() {
148
+			tmpChoise -= o.getMatrixSize()
149
+		} else if tmpChoise >= len(o.candidate) {
150
+			tmpChoise += o.candidateColNum
151
+			tmpChoise -= o.getMatrixSize()
152
+		}
153
+		o.candidateChoise = tmpChoise
154
+	case CharBackward:
155
+		o.nextCandidate(-1)
156
+	case CharPrev:
157
+		tmpChoise := o.candidateChoise - o.candidateColNum
158
+		if tmpChoise < 0 {
159
+			tmpChoise += o.getMatrixSize()
160
+			if tmpChoise >= len(o.candidate) {
161
+				tmpChoise -= o.candidateColNum
162
+			}
163
+		}
164
+		o.candidateChoise = tmpChoise
165
+	default:
166
+		next = false
167
+		o.ExitCompleteSelectMode()
168
+	}
169
+	if next {
170
+		o.CompleteRefresh()
171
+		return true
172
+	}
173
+	return false
174
+}
175
+
176
+func (o *opCompleter) getMatrixSize() int {
177
+	line := len(o.candidate) / o.candidateColNum
178
+	if len(o.candidate)%o.candidateColNum != 0 {
179
+		line++
180
+	}
181
+	return line * o.candidateColNum
182
+}
183
+
184
+func (o *opCompleter) OnWidthChange(newWidth int) {
185
+	o.width = newWidth
186
+}
187
+
188
+func (o *opCompleter) CompleteRefresh() {
189
+	if !o.inCompleteMode {
190
+		return
191
+	}
192
+	lineCnt := o.op.buf.CursorLineCount()
193
+	colWidth := 0
194
+	for _, c := range o.candidate {
195
+		w := runes.WidthAll(c)
196
+		if w > colWidth {
197
+			colWidth = w
198
+		}
199
+	}
200
+	colWidth += o.candidateOff + 1
201
+	same := o.op.buf.RuneSlice(-o.candidateOff)
202
+
203
+	// -1 to avoid reach the end of line
204
+	width := o.width - 1
205
+	colNum := width / colWidth
206
+	colWidth += (width - (colWidth * colNum)) / colNum
207
+
208
+	o.candidateColNum = colNum
209
+	buf := bufio.NewWriter(o.w)
210
+	buf.Write(bytes.Repeat([]byte("\n"), lineCnt))
211
+
212
+	colIdx := 0
213
+	lines := 1
214
+	buf.WriteString("\033[J")
215
+	for idx, c := range o.candidate {
216
+		inSelect := idx == o.candidateChoise && o.IsInCompleteSelectMode()
217
+		if inSelect {
218
+			buf.WriteString("\033[30;47m")
219
+		}
220
+		buf.WriteString(string(same))
221
+		buf.WriteString(string(c))
222
+		buf.Write(bytes.Repeat([]byte(" "), colWidth-len(c)-len(same)))
223
+
224
+		if inSelect {
225
+			buf.WriteString("\033[0m")
226
+		}
227
+
228
+		colIdx++
229
+		if colIdx == colNum {
230
+			buf.WriteString("\n")
231
+			lines++
232
+			colIdx = 0
233
+		}
234
+	}
235
+
236
+	// move back
237
+	fmt.Fprintf(buf, "\033[%dA\r", lineCnt-1+lines)
238
+	fmt.Fprintf(buf, "\033[%dC", o.op.buf.idx+o.op.buf.PromptLen())
239
+	buf.Flush()
240
+}
241
+
242
+func (o *opCompleter) aggCandidate(candidate [][]rune) int {
243
+	offset := 0
244
+	for i := 0; i < len(candidate[0]); i++ {
245
+		for j := 0; j < len(candidate)-1; j++ {
246
+			if i > len(candidate[j]) {
247
+				goto aggregate
248
+			}
249
+			if candidate[j][i] != candidate[j+1][i] {
250
+				goto aggregate
251
+			}
252
+		}
253
+		offset = i
254
+	}
255
+aggregate:
256
+	return offset
257
+}
258
+
259
+func (o *opCompleter) EnterCompleteSelectMode() {
260
+	o.inSelectMode = true
261
+	o.candidateChoise = -1
262
+	o.CompleteRefresh()
263
+}
264
+
265
+func (o *opCompleter) EnterCompleteMode(offset int, candidate [][]rune) {
266
+	o.inCompleteMode = true
267
+	o.candidate = candidate
268
+	o.candidateOff = offset
269
+	o.CompleteRefresh()
270
+}
271
+
272
+func (o *opCompleter) ExitCompleteSelectMode() {
273
+	o.inSelectMode = false
274
+	o.candidate = nil
275
+	o.candidateChoise = -1
276
+	o.candidateOff = -1
277
+	o.candidateSource = nil
278
+}
279
+
280
+func (o *opCompleter) ExitCompleteMode(revent bool) {
281
+	o.inCompleteMode = false
282
+	o.ExitCompleteSelectMode()
283
+}

+ 165
- 0
vendor/github.com/chzyer/readline/complete_helper.go View File

@@ -0,0 +1,165 @@
1
+package readline
2
+
3
+import (
4
+	"bytes"
5
+	"strings"
6
+)
7
+
8
+// Caller type for dynamic completion
9
+type DynamicCompleteFunc func(string) []string
10
+
11
+type PrefixCompleterInterface interface {
12
+	Print(prefix string, level int, buf *bytes.Buffer)
13
+	Do(line []rune, pos int) (newLine [][]rune, length int)
14
+	GetName() []rune
15
+	GetChildren() []PrefixCompleterInterface
16
+	SetChildren(children []PrefixCompleterInterface)
17
+}
18
+
19
+type DynamicPrefixCompleterInterface interface {
20
+	PrefixCompleterInterface
21
+	IsDynamic() bool
22
+	GetDynamicNames(line []rune) [][]rune
23
+}
24
+
25
+type PrefixCompleter struct {
26
+	Name     []rune
27
+	Dynamic  bool
28
+	Callback DynamicCompleteFunc
29
+	Children []PrefixCompleterInterface
30
+}
31
+
32
+func (p *PrefixCompleter) Tree(prefix string) string {
33
+	buf := bytes.NewBuffer(nil)
34
+	p.Print(prefix, 0, buf)
35
+	return buf.String()
36
+}
37
+
38
+func Print(p PrefixCompleterInterface, prefix string, level int, buf *bytes.Buffer) {
39
+	if strings.TrimSpace(string(p.GetName())) != "" {
40
+		buf.WriteString(prefix)
41
+		if level > 0 {
42
+			buf.WriteString("├")
43
+			buf.WriteString(strings.Repeat("─", (level*4)-2))
44
+			buf.WriteString(" ")
45
+		}
46
+		buf.WriteString(string(p.GetName()) + "\n")
47
+		level++
48
+	}
49
+	for _, ch := range p.GetChildren() {
50
+		ch.Print(prefix, level, buf)
51
+	}
52
+}
53
+
54
+func (p *PrefixCompleter) Print(prefix string, level int, buf *bytes.Buffer) {
55
+	Print(p, prefix, level, buf)
56
+}
57
+
58
+func (p *PrefixCompleter) IsDynamic() bool {
59
+	return p.Dynamic
60
+}
61
+
62
+func (p *PrefixCompleter) GetName() []rune {
63
+	return p.Name
64
+}
65
+
66
+func (p *PrefixCompleter) GetDynamicNames(line []rune) [][]rune {
67
+	var names = [][]rune{}
68
+	for _, name := range p.Callback(string(line)) {
69
+		names = append(names, []rune(name+" "))
70
+	}
71
+	return names
72
+}
73
+
74
+func (p *PrefixCompleter) GetChildren() []PrefixCompleterInterface {
75
+	return p.Children
76
+}
77
+
78
+func (p *PrefixCompleter) SetChildren(children []PrefixCompleterInterface) {
79
+	p.Children = children
80
+}
81
+
82
+func NewPrefixCompleter(pc ...PrefixCompleterInterface) *PrefixCompleter {
83
+	return PcItem("", pc...)
84
+}
85
+
86
+func PcItem(name string, pc ...PrefixCompleterInterface) *PrefixCompleter {
87
+	name += " "
88
+	return &PrefixCompleter{
89
+		Name:     []rune(name),
90
+		Dynamic:  false,
91
+		Children: pc,
92
+	}
93
+}
94
+
95
+func PcItemDynamic(callback DynamicCompleteFunc, pc ...PrefixCompleterInterface) *PrefixCompleter {
96
+	return &PrefixCompleter{
97
+		Callback: callback,
98
+		Dynamic:  true,
99
+		Children: pc,
100
+	}
101
+}
102
+
103
+func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int) {
104
+	return doInternal(p, line, pos, line)
105
+}
106
+
107
+func Do(p PrefixCompleterInterface, line []rune, pos int) (newLine [][]rune, offset int) {
108
+	return doInternal(p, line, pos, line)
109
+}
110
+
111
+func doInternal(p PrefixCompleterInterface, line []rune, pos int, origLine []rune) (newLine [][]rune, offset int) {
112
+	line = runes.TrimSpaceLeft(line[:pos])
113
+	goNext := false
114
+	var lineCompleter PrefixCompleterInterface
115
+	for _, child := range p.GetChildren() {
116
+		childNames := make([][]rune, 1)
117
+
118
+		childDynamic, ok := child.(DynamicPrefixCompleterInterface)
119
+		if ok && childDynamic.IsDynamic() {
120
+			childNames = childDynamic.GetDynamicNames(origLine)
121
+		} else {
122
+			childNames[0] = child.GetName()
123
+		}
124
+
125
+		for _, childName := range childNames {
126
+			if len(line) >= len(childName) {
127
+				if runes.HasPrefix(line, childName) {
128
+					if len(line) == len(childName) {
129
+						newLine = append(newLine, []rune{' '})
130
+					} else {
131
+						newLine = append(newLine, childName)
132
+					}
133
+					offset = len(childName)
134
+					lineCompleter = child
135
+					goNext = true
136
+				}
137
+			} else {
138
+				if runes.HasPrefix(childName, line) {
139
+					newLine = append(newLine, childName[len(line):])
140
+					offset = len(line)
141
+					lineCompleter = child
142
+				}
143
+			}
144
+		}
145
+	}
146
+
147
+	if len(newLine) != 1 {
148
+		return
149
+	}
150
+
151
+	tmpLine := make([]rune, 0, len(line))
152
+	for i := offset; i < len(line); i++ {
153
+		if line[i] == ' ' {
154
+			continue
155
+		}
156
+
157
+		tmpLine = append(tmpLine, line[i:]...)
158
+		return doInternal(lineCompleter, tmpLine, len(tmpLine), origLine)
159
+	}
160
+
161
+	if goNext {
162
+		return doInternal(lineCompleter, nil, 0, origLine)
163
+	}
164
+	return
165
+}

+ 82
- 0
vendor/github.com/chzyer/readline/complete_segment.go View File

@@ -0,0 +1,82 @@
1
+package readline
2
+
3
+type SegmentCompleter interface {
4
+	// a
5
+	// |- a1
6
+	// |--- a11
7
+	// |- a2
8
+	// b
9
+	// input:
10
+	//   DoTree([], 0) [a, b]
11
+	//   DoTree([a], 1) [a]
12
+	//   DoTree([a, ], 0) [a1, a2]
13
+	//   DoTree([a, a], 1) [a1, a2]
14
+	//   DoTree([a, a1], 2) [a1]
15
+	//   DoTree([a, a1, ], 0) [a11]
16
+	//   DoTree([a, a1, a], 1) [a11]
17
+	DoSegment([][]rune, int) [][]rune
18
+}
19
+
20
+type dumpSegmentCompleter struct {
21
+	f func([][]rune, int) [][]rune
22
+}
23
+
24
+func (d *dumpSegmentCompleter) DoSegment(segment [][]rune, n int) [][]rune {
25
+	return d.f(segment, n)
26
+}
27
+
28
+func SegmentFunc(f func([][]rune, int) [][]rune) AutoCompleter {
29
+	return &SegmentComplete{&dumpSegmentCompleter{f}}
30
+}
31
+
32
+func SegmentAutoComplete(completer SegmentCompleter) *SegmentComplete {
33
+	return &SegmentComplete{
34
+		SegmentCompleter: completer,
35
+	}
36
+}
37
+
38
+type SegmentComplete struct {
39
+	SegmentCompleter
40
+}
41
+
42
+func RetSegment(segments [][]rune, cands [][]rune, idx int) ([][]rune, int) {
43
+	ret := make([][]rune, 0, len(cands))
44
+	lastSegment := segments[len(segments)-1]
45
+	for _, cand := range cands {
46
+		if !runes.HasPrefix(cand, lastSegment) {
47
+			continue
48
+		}
49
+		ret = append(ret, cand[len(lastSegment):])
50
+	}
51
+	return ret, idx
52
+}
53
+
54
+func SplitSegment(line []rune, pos int) ([][]rune, int) {
55
+	segs := [][]rune{}
56
+	lastIdx := -1
57
+	line = line[:pos]
58
+	pos = 0
59
+	for idx, l := range line {
60
+		if l == ' ' {
61
+			pos = 0
62
+			segs = append(segs, line[lastIdx+1:idx])
63
+			lastIdx = idx
64
+		} else {
65
+			pos++
66
+		}
67
+	}
68
+	segs = append(segs, line[lastIdx+1:])
69
+	return segs, pos
70
+}
71
+
72
+func (c *SegmentComplete) Do(line []rune, pos int) (newLine [][]rune, offset int) {
73
+
74
+	segment, idx := SplitSegment(line, pos)
75
+
76
+	cands := c.DoSegment(segment, idx)
77
+	newLine, offset = RetSegment(segment, cands, idx)
78
+	for idx := range newLine {
79
+		newLine[idx] = append(newLine[idx], ' ')
80
+	}
81
+	return newLine, offset
82
+}

+ 312
- 0
vendor/github.com/chzyer/readline/history.go View File

@@ -0,0 +1,312 @@
1
+package readline
2
+
3
+import (
4
+	"bufio"
5
+	"container/list"
6
+	"fmt"
7
+	"os"
8
+	"strings"
9
+	"sync"
10
+)
11
+
12
+type hisItem struct {
13
+	Source  []rune
14
+	Version int64
15
+	Tmp     []rune
16
+}
17
+
18
+func (h *hisItem) Clean() {
19
+	h.Source = nil
20
+	h.Tmp = nil
21
+}
22
+
23
+type opHistory struct {
24
+	cfg        *Config
25
+	history    *list.List
26
+	historyVer int64
27
+	current    *list.Element
28
+	fd         *os.File
29
+	fdLock     sync.Mutex
30
+}
31
+
32
+func newOpHistory(cfg *Config) (o *opHistory) {
33
+	o = &opHistory{
34
+		cfg:     cfg,
35
+		history: list.New(),
36
+	}
37
+	return o
38
+}
39
+
40
+func (o *opHistory) Reset() {
41
+	o.history = list.New()
42
+	o.current = nil
43
+}
44
+
45
+func (o *opHistory) IsHistoryClosed() bool {
46
+	o.fdLock.Lock()
47
+	defer o.fdLock.Unlock()
48
+	return o.fd.Fd() == ^(uintptr(0))
49
+}
50
+
51
+func (o *opHistory) Init() {
52
+	if o.IsHistoryClosed() {
53
+		o.initHistory()
54
+	}
55
+}
56
+
57
+func (o *opHistory) initHistory() {
58
+	if o.cfg.HistoryFile != "" {
59
+		o.historyUpdatePath(o.cfg.HistoryFile)
60
+	}
61
+}
62
+
63
+// only called by newOpHistory
64
+func (o *opHistory) historyUpdatePath(path string) {
65
+	o.fdLock.Lock()
66
+	defer o.fdLock.Unlock()
67
+	f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
68
+	if err != nil {
69
+		return
70
+	}
71
+	o.fd = f
72
+	r := bufio.NewReader(o.fd)
73
+	total := 0
74
+	for ; ; total++ {
75
+		line, err := r.ReadString('\n')
76
+		if err != nil {
77
+			break
78
+		}
79
+		// ignore the empty line
80
+		line = strings.TrimSpace(line)
81
+		if len(line) == 0 {
82
+			continue
83
+		}
84
+		o.Push([]rune(line))
85
+		o.Compact()
86
+	}
87
+	if total > o.cfg.HistoryLimit {
88
+		o.rewriteLocked()
89
+	}
90
+	o.historyVer++
91
+	o.Push(nil)
92
+	return
93
+}
94
+
95
+func (o *opHistory) Compact() {
96
+	for o.history.Len() > o.cfg.HistoryLimit && o.history.Len() > 0 {
97
+		o.history.Remove(o.history.Front())
98
+	}
99
+}
100
+
101
+func (o *opHistory) Rewrite() {
102
+	o.fdLock.Lock()
103
+	defer o.fdLock.Unlock()
104
+	o.rewriteLocked()
105
+}
106
+
107
+func (o *opHistory) rewriteLocked() {
108
+	if o.cfg.HistoryFile == "" {
109
+		return
110
+	}
111
+
112
+	tmpFile := o.cfg.HistoryFile + ".tmp"
113
+	fd, err := os.OpenFile(tmpFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC|os.O_APPEND, 0666)
114
+	if err != nil {
115
+		return
116
+	}
117
+
118
+	buf := bufio.NewWriter(fd)
119
+	for elem := o.history.Front(); elem != nil; elem = elem.Next() {
120
+		buf.WriteString(string(elem.Value.(*hisItem).Source))
121
+	}
122
+	buf.Flush()
123
+
124
+	// replace history file
125
+	if err = os.Rename(tmpFile, o.cfg.HistoryFile); err != nil {
126
+		fd.Close()
127
+		return
128
+	}
129
+
130
+	if o.fd != nil {
131
+		o.fd.Close()
132
+	}
133
+	// fd is write only, just satisfy what we need.
134
+	o.fd = fd
135
+}
136
+
137
+func (o *opHistory) Close() {
138
+	o.fdLock.Lock()
139
+	defer o.fdLock.Unlock()
140
+	if o.fd != nil {
141
+		o.fd.Close()
142
+	}
143
+}
144
+
145
+func (o *opHistory) FindBck(isNewSearch bool, rs []rune, start int) (int, *list.Element) {
146
+	for elem := o.current; elem != nil; elem = elem.Prev() {
147
+		item := o.showItem(elem.Value)
148
+		if isNewSearch {
149
+			start += len(rs)
150
+		}
151
+		if elem == o.current {
152
+			if len(item) >= start {
153
+				item = item[:start]
154
+			}
155
+		}
156
+		idx := runes.IndexAllBckEx(item, rs, o.cfg.HistorySearchFold)
157
+		if idx < 0 {
158
+			continue
159
+		}
160
+		return idx, elem
161
+	}
162
+	return -1, nil
163
+}
164
+
165
+func (o *opHistory) FindFwd(isNewSearch bool, rs []rune, start int) (int, *list.Element) {
166
+	for elem := o.current; elem != nil; elem = elem.Next() {
167
+		item := o.showItem(elem.Value)
168
+		if isNewSearch {
169
+			start -= len(rs)
170
+			if start < 0 {
171
+				start = 0
172
+			}
173
+		}
174
+		if elem == o.current {
175
+			if len(item)-1 >= start {
176
+				item = item[start:]
177
+			} else {
178
+				continue
179
+			}
180
+		}
181
+		idx := runes.IndexAllEx(item, rs, o.cfg.HistorySearchFold)
182
+		if idx < 0 {
183
+			continue
184
+		}
185
+		if elem == o.current {
186
+			idx += start
187
+		}
188
+		return idx, elem
189
+	}
190
+	return -1, nil
191
+}
192
+
193
+func (o *opHistory) showItem(obj interface{}) []rune {
194
+	item := obj.(*hisItem)
195
+	if item.Version == o.historyVer {
196
+		return item.Tmp
197
+	}
198
+	return item.Source
199
+}
200
+
201
+func (o *opHistory) Prev() []rune {
202
+	if o.current == nil {
203
+		return nil
204
+	}
205
+	current := o.current.Prev()
206
+	if current == nil {
207
+		return nil
208
+	}
209
+	o.current = current
210
+	return runes.Copy(o.showItem(current.Value))
211
+}
212
+
213
+func (o *opHistory) Next() ([]rune, bool) {
214
+	if o.current == nil {
215
+		return nil, false
216
+	}
217
+	current := o.current.Next()
218
+	if current == nil {
219
+		return nil, false
220
+	}
221
+
222
+	o.current = current
223
+	return runes.Copy(o.showItem(current.Value)), true
224
+}
225
+
226
+func (o *opHistory) debug() {
227
+	Debug("-------")
228
+	for item := o.history.Front(); item != nil; item = item.Next() {
229
+		Debug(fmt.Sprintf("%+v", item.Value))
230
+	}
231
+}
232
+
233
+// save history
234
+func (o *opHistory) New(current []rune) (err error) {
235
+	current = runes.Copy(current)
236
+
237
+	// if just use last command without modify
238
+	// just clean lastest history
239
+	if back := o.history.Back(); back != nil {
240
+		prev := back.Prev()
241
+		if prev != nil {
242
+			if runes.Equal(current, prev.Value.(*hisItem).Source) {
243
+				o.current = o.history.Back()
244
+				o.current.Value.(*hisItem).Clean()
245
+				o.historyVer++
246
+				return nil
247
+			}
248
+		}
249
+	}
250
+
251
+	if len(current) == 0 {
252
+		o.current = o.history.Back()
253
+		if o.current != nil {
254
+			o.current.Value.(*hisItem).Clean()
255
+			o.historyVer++
256
+			return nil
257
+		}
258
+	}
259
+
260
+	if o.current != o.history.Back() {
261
+		// move history item to current command
262
+		currentItem := o.current.Value.(*hisItem)
263
+		// set current to last item
264
+		o.current = o.history.Back()
265
+
266
+		current = runes.Copy(currentItem.Tmp)
267
+	}
268
+
269
+	// err only can be a IO error, just report
270
+	err = o.Update(current, true)
271
+
272
+	// push a new one to commit current command
273
+	o.historyVer++
274
+	o.Push(nil)
275
+	return
276
+}
277
+
278
+func (o *opHistory) Revert() {
279
+	o.historyVer++
280
+	o.current = o.history.Back()
281
+}
282
+
283
+func (o *opHistory) Update(s []rune, commit bool) (err error) {
284
+	o.fdLock.Lock()
285
+	defer o.fdLock.Unlock()
286
+	s = runes.Copy(s)
287
+	if o.current == nil {
288
+		o.Push(s)
289
+		o.Compact()
290
+		return
291
+	}
292
+	r := o.current.Value.(*hisItem)
293
+	r.Version = o.historyVer
294
+	if commit {
295
+		r.Source = s
296
+		if o.fd != nil {
297
+			// just report the error
298
+			_, err = o.fd.Write([]byte(string(r.Source) + "\n"))
299
+		}
300
+	} else {
301
+		r.Tmp = append(r.Tmp[:0], s...)
302
+	}
303
+	o.current.Value = r
304
+	o.Compact()
305
+	return
306
+}
307
+
308
+func (o *opHistory) Push(s []rune) {
309
+	s = runes.Copy(s)
310
+	elem := o.history.PushBack(&hisItem{Source: s})
311
+	o.current = elem
312
+}

+ 504
- 0
vendor/github.com/chzyer/readline/operation.go View File

@@ -0,0 +1,504 @@
1
+package readline
2
+
3
+import (
4
+	"errors"
5
+	"io"
6
+)
7
+
8
+var (
9
+	ErrInterrupt = errors.New("Interrupt")
10
+)
11
+
12
+type InterruptError struct {
13
+	Line []rune
14
+}
15
+
16
+func (*InterruptError) Error() string {
17
+	return "Interrupted"
18
+}
19
+
20
+type Operation struct {
21
+	cfg     *Config
22
+	t       *Terminal
23
+	buf     *RuneBuffer
24
+	outchan chan []rune
25
+	errchan chan error
26
+	w       io.Writer
27
+
28
+	history *opHistory
29
+	*opSearch
30
+	*opCompleter
31
+	*opPassword
32
+	*opVim
33
+}
34
+
35
+func (o *Operation) SetBuffer(what string) {
36
+	o.buf.Set([]rune(what))
37
+}
38
+
39
+type wrapWriter struct {
40
+	r      *Operation
41
+	t      *Terminal
42
+	target io.Writer
43
+}
44
+
45
+func (w *wrapWriter) Write(b []byte) (int, error) {
46
+	if !w.t.IsReading() {
47
+		return w.target.Write(b)
48
+	}
49
+
50
+	var (
51
+		n   int
52
+		err error
53
+	)
54
+	w.r.buf.Refresh(func() {
55
+		n, err = w.target.Write(b)
56
+	})
57
+
58
+	if w.r.IsSearchMode() {
59
+		w.r.SearchRefresh(-1)
60
+	}
61
+	if w.r.IsInCompleteMode() {
62
+		w.r.CompleteRefresh()
63
+	}
64
+	return n, err
65
+}
66
+
67
+func NewOperation(t *Terminal, cfg *Config) *Operation {
68
+	width := cfg.FuncGetWidth()
69
+	op := &Operation{
70
+		t:       t,
71
+		buf:     NewRuneBuffer(t, cfg.Prompt, cfg, width),
72
+		outchan: make(chan []rune),
73
+		errchan: make(chan error),
74
+	}
75
+	op.w = op.buf.w
76
+	op.SetConfig(cfg)
77
+	op.opVim = newVimMode(op)
78
+	op.opCompleter = newOpCompleter(op.buf.w, op, width)
79
+	op.opPassword = newOpPassword(op)
80
+	op.cfg.FuncOnWidthChanged(func() {
81
+		newWidth := cfg.FuncGetWidth()
82
+		op.opCompleter.OnWidthChange(newWidth)
83
+		op.opSearch.OnWidthChange(newWidth)
84
+		op.buf.OnWidthChange(newWidth)
85
+	})
86
+	go op.ioloop()
87
+	return op
88
+}
89
+
90
+func (o *Operation) SetPrompt(s string) {
91
+	o.buf.SetPrompt(s)
92
+}
93
+
94
+func (o *Operation) SetMaskRune(r rune) {
95
+	o.buf.SetMask(r)
96
+}
97
+
98
+func (o *Operation) ioloop() {
99
+	for {
100
+		keepInSearchMode := false
101
+		keepInCompleteMode := false
102
+		r := o.t.ReadRune()
103
+		if o.cfg.FuncFilterInputRune != nil {
104
+			var process bool
105
+			r, process = o.cfg.FuncFilterInputRune(r)
106
+			if !process {
107
+				o.buf.Refresh(nil) // to refresh the line
108
+				continue           // ignore this rune
109
+			}
110
+		}
111
+
112
+		if r == 0 { // io.EOF
113
+			if o.buf.Len() == 0 {
114
+				o.buf.Clean()
115
+				select {
116
+				case o.errchan <- io.EOF:
117
+				}
118
+				break
119
+			} else {
120
+				// if stdin got io.EOF and there is something left in buffer,
121
+				// let's flush them by sending CharEnter.
122
+				// And we will got io.EOF int next loop.
123
+				r = CharEnter
124
+			}
125
+		}
126
+		isUpdateHistory := true
127
+
128
+		if o.IsInCompleteSelectMode() {
129
+			keepInCompleteMode = o.HandleCompleteSelect(r)
130
+			if keepInCompleteMode {
131
+				continue
132
+			}
133