Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/term: Cannot differentiate a CTRL+C from CTRL+D #62385

Open
Matir opened this issue Aug 30, 2023 · 6 comments
Open

x/term: Cannot differentiate a CTRL+C from CTRL+D #62385

Matir opened this issue Aug 30, 2023 · 6 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@Matir
Copy link

Matir commented Aug 30, 2023

What version of Go are you using (go version)?

$ go version
go version go1.21rc2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/matir/.cache/go-build'
GOENV='/home/matir/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/matir/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/matir/go:/home/matir/Projects/Go:/usr/share/gocode'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go-1.21'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go-1.21/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21rc2'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build893724784=/tmp/go-build -gno-record-gcc-switches'

What did you do?

package main

import (
  "fmt"
  "io"
  "os"

  "golang.org/x/term"
)

func main() {
  s, err := term.MakeRaw(int(os.Stdin.Fd()))
  if err != nil {
    panic(err)
  }
  defer term.Restore(int(os.Stdin.Fd()), s)
  rw := struct{
    io.Reader
    io.Writer
  }{
    os.Stdin,
    os.Stdout,
  }
  t := term.NewTerminal(rw, "> ")
  for {
    _, err := t.ReadLine()
    if err == io.EOF {
      fmt.Println("Did I get CTRL+C or CTRL+D (EOF)?")
      break
    }
  }
}

What did you expect to see?

I'd like to know if a user input CTRL+C (along with the ability to react to it; i.e., it advances the "line" buffer and gives me a callback or handler) so that I can emulate the typical shell behavior or clearing the input when a user hits CTRL+C while providing input.

What did you see instead?

I get io.EOF for CTRL+C. If I ignore it and call ReadLine again, I am repeatedly given the same error because t.remainder is not advanced.

@gopherbot gopherbot added this to the Unreleased milestone Aug 30, 2023
@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 31, 2023
@dmitshur
Copy link
Contributor

CC @tklauser, @hyangah.

@Matir
Copy link
Author

Matir commented Aug 31, 2023

In our particular case, we basically want Ctrl+C to be equivalent to Ctrl+U (yes, we could use Ctrl+U, but muscle memory and all that). I can see a few options here, and I'm happy to contribute a CL on gerrit if there's some guidance on which approach would be most appropriate:

  1. A flag set via a function on the Terminal struct to make x/term internally handle Ctrl+C as Ctrl+U equivalent (clear input line)
  2. Returning a different error on Ctrl+C (but I recognize this might break existing users) and removing the character from the input so a subsequent call to ReadLine doesn't just repeat it.
  3. Providing the ability to call a callback on special characters like that, along with functions to clear the current input buffer/line.
  4. Something else I haven't considered?

@kor44
Copy link

kor44 commented Oct 17, 2023

In our particular case, we basically want Ctrl+C to be equivalent to Ctrl+U (yes, we could use Ctrl+U, but muscle memory and all that). I can see a few options here, and I'm happy to contribute a CL on gerrit if there's some guidance on which approach would be most appropriate:

1. A flag set via a function on the `Terminal` struct to make `x/term` internally handle Ctrl+C as Ctrl+U equivalent (clear input line)

2. Returning a different error on Ctrl+C (but I recognize this might break existing users) _and_ removing the character from the input so a subsequent call to `ReadLine` doesn't just repeat it.

3. Providing the ability to call a callback on special characters like that, along with functions to clear the current input buffer/line.

4. Something else I haven't considered?

Hi, I met with the same problem, but in my case I need to ignore Ctrl+C.
I this option #3 (Providing the ability to call a callback on special characters) is the best decision

@forrejam
Copy link

I would vote for option 3 too, have you got a working PR?

@kor44
Copy link

kor44 commented Mar 23, 2024

I would vote for option 3 too, have you got a working PR?

No

@malko
Copy link

malko commented May 2, 2024

my vote for option 3 it provide more flexibility, and let programmers decide how they want to react in their particular context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants