Implement configurable detach key
Implement configurable detach keys (for `attach`, exec`, `run` and `start`) using the client-side configuration - Adds a `--detach-keys` flag to `attach`, `exec`, `run` and `start` commands. - Adds a new configuration field (in `~/.docker/config.json`) to configure the default escape keys for docker client. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
4fef057438
commit
b30831bbe7
2 changed files with 109 additions and 0 deletions
66
term/ascii.go
Normal file
66
term/ascii.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ASCII list the possible supported ASCII key sequence
|
||||||
|
var ASCII = []string{
|
||||||
|
"ctrl-@",
|
||||||
|
"ctrl-a",
|
||||||
|
"ctrl-b",
|
||||||
|
"ctrl-c",
|
||||||
|
"ctrl-d",
|
||||||
|
"ctrl-e",
|
||||||
|
"ctrl-f",
|
||||||
|
"ctrl-g",
|
||||||
|
"ctrl-h",
|
||||||
|
"ctrl-i",
|
||||||
|
"ctrl-j",
|
||||||
|
"ctrl-k",
|
||||||
|
"ctrl-l",
|
||||||
|
"ctrl-m",
|
||||||
|
"ctrl-n",
|
||||||
|
"ctrl-o",
|
||||||
|
"ctrl-p",
|
||||||
|
"ctrl-q",
|
||||||
|
"ctrl-r",
|
||||||
|
"ctrl-s",
|
||||||
|
"ctrl-t",
|
||||||
|
"ctrl-u",
|
||||||
|
"ctrl-v",
|
||||||
|
"ctrl-w",
|
||||||
|
"ctrl-x",
|
||||||
|
"ctrl-y",
|
||||||
|
"ctrl-z",
|
||||||
|
"ctrl-[",
|
||||||
|
"ctrl-\\",
|
||||||
|
"ctrl-]",
|
||||||
|
"ctrl-^",
|
||||||
|
"ctrl-_",
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBytes converts a string representing a suite of key-sequence to the corresponding ASCII code.
|
||||||
|
func ToBytes(keys string) ([]byte, error) {
|
||||||
|
codes := []byte{}
|
||||||
|
next:
|
||||||
|
for _, key := range strings.Split(keys, ",") {
|
||||||
|
if len(key) != 1 {
|
||||||
|
for code, ctrl := range ASCII {
|
||||||
|
if ctrl == key {
|
||||||
|
codes = append(codes, byte(code))
|
||||||
|
continue next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if key == "DEL" {
|
||||||
|
codes = append(codes, 127)
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("Unknown character: '%s'", key)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
codes = append(codes, byte(key[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return codes, nil
|
||||||
|
}
|
43
term/ascii_test.go
Normal file
43
term/ascii_test.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package term
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestToBytes(t *testing.T) {
|
||||||
|
codes, err := ToBytes("ctrl-a,a")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(codes) != 2 {
|
||||||
|
t.Fatalf("Expected 2 codes, got %d", len(codes))
|
||||||
|
}
|
||||||
|
if codes[0] != 1 || codes[1] != 97 {
|
||||||
|
t.Fatalf("Expected '1' '97', got '%d' '%d'", codes[0], codes[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
codes, err = ToBytes("shift-z")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
codes, err = ToBytes("ctrl-@,ctrl-[,~,ctrl-o")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(codes) != 4 {
|
||||||
|
t.Fatalf("Expected 4 codes, got %d", len(codes))
|
||||||
|
}
|
||||||
|
if codes[0] != 0 || codes[1] != 27 || codes[2] != 126 || codes[3] != 15 {
|
||||||
|
t.Fatalf("Expected '0' '27' '126', '15', got '%d' '%d' '%d' '%d'", codes[0], codes[1], codes[2], codes[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
codes, err = ToBytes("DEL,+")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(codes) != 2 {
|
||||||
|
t.Fatalf("Expected 2 codes, got %d", len(codes))
|
||||||
|
}
|
||||||
|
if codes[0] != 127 || codes[1] != 43 {
|
||||||
|
t.Fatalf("Expected '127 '43'', got '%d' '%d'", codes[0], codes[1])
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue