diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/cmd/pprof/readlineui.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/pprof/readlineui.go')
-rw-r--r-- | src/cmd/pprof/readlineui.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/cmd/pprof/readlineui.go b/src/cmd/pprof/readlineui.go new file mode 100644 index 0000000..0c9fafd --- /dev/null +++ b/src/cmd/pprof/readlineui.go @@ -0,0 +1,120 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains a driver.UI implementation +// that provides the readline functionality if possible. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build !appengine +// +build !android + +package main + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/google/pprof/driver" + "golang.org/x/crypto/ssh/terminal" +) + +func init() { + newUI = newReadlineUI +} + +// readlineUI implements driver.UI interface using the +// golang.org/x/crypto/ssh/terminal package. +// The upstream pprof command implements the same functionality +// using the github.com/chzyer/readline package. +type readlineUI struct { + term *terminal.Terminal +} + +func newReadlineUI() driver.UI { + // disable readline UI in dumb terminal. (golang.org/issue/26254) + if v := strings.ToLower(os.Getenv("TERM")); v == "" || v == "dumb" { + return nil + } + // test if we can use terminal.ReadLine + // that assumes operation in the raw mode. + oldState, err := terminal.MakeRaw(0) + if err != nil { + return nil + } + terminal.Restore(0, oldState) + + rw := struct { + io.Reader + io.Writer + }{os.Stdin, os.Stderr} + return &readlineUI{term: terminal.NewTerminal(rw, "")} +} + +// Read returns a line of text (a command) read from the user. +// prompt is printed before reading the command. +func (r *readlineUI) ReadLine(prompt string) (string, error) { + r.term.SetPrompt(prompt) + + // skip error checking because we tested it + // when creating this readlineUI initially. + oldState, _ := terminal.MakeRaw(0) + defer terminal.Restore(0, oldState) + + s, err := r.term.ReadLine() + return s, err +} + +// Print shows a message to the user. +// It formats the text as fmt.Print would and adds a final \n if not already present. +// For line-based UI, Print writes to standard error. +// (Standard output is reserved for report data.) +func (r *readlineUI) Print(args ...interface{}) { + r.print(false, args...) +} + +// PrintErr shows an error message to the user. +// It formats the text as fmt.Print would and adds a final \n if not already present. +// For line-based UI, PrintErr writes to standard error. +func (r *readlineUI) PrintErr(args ...interface{}) { + r.print(true, args...) +} + +func (r *readlineUI) print(withColor bool, args ...interface{}) { + text := fmt.Sprint(args...) + if !strings.HasSuffix(text, "\n") { + text += "\n" + } + if withColor { + text = colorize(text) + } + fmt.Fprint(r.term, text) +} + +// colorize prints the msg in red using ANSI color escapes. +func colorize(msg string) string { + const red = 31 + var colorEscape = fmt.Sprintf("\033[0;%dm", red) + var colorResetEscape = "\033[0m" + return colorEscape + msg + colorResetEscape +} + +// IsTerminal reports whether the UI is known to be tied to an +// interactive terminal (as opposed to being redirected to a file). +func (r *readlineUI) IsTerminal() bool { + const stdout = 1 + return terminal.IsTerminal(stdout) +} + +// WantBrowser indicates whether browser should be opened with the -http option. +func (r *readlineUI) WantBrowser() bool { + return r.IsTerminal() +} + +// SetAutoComplete instructs the UI to call complete(cmd) to obtain +// the auto-completion of cmd, if the UI supports auto-completion at all. +func (r *readlineUI) SetAutoComplete(complete func(string) string) { + // TODO: Implement auto-completion support. +} |