github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/pty/readline.go (about)

     1  package pty
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  )
     7  
     8  var ErrInterrupted = errors.New("interrupted")
     9  
    10  const (
    11  	keyCtrlC     = 3
    12  	keyBackspace = 127
    13  )
    14  
    15  func ReadLine(reader io.Reader) ([]byte, error) {
    16  	var buf [1]byte
    17  	var ret []byte
    18  
    19  	for {
    20  		n, err := reader.Read(buf[:])
    21  		if n > 0 {
    22  			switch buf[0] {
    23  			case '\b', keyBackspace:
    24  				if len(ret) > 0 {
    25  					ret = ret[:len(ret)-1]
    26  				}
    27  			case '\r', '\n':
    28  				return ret, nil
    29  			case keyCtrlC:
    30  				return nil, ErrInterrupted
    31  			default:
    32  				if isPrintableChar(buf[0]) {
    33  					ret = append(ret, buf[0])
    34  				}
    35  			}
    36  			continue
    37  		}
    38  		if err != nil {
    39  			if err == io.EOF && len(ret) > 0 {
    40  				return ret, nil
    41  			}
    42  			return ret, err
    43  		}
    44  	}
    45  }
    46  
    47  func isPrintableChar(b byte) bool {
    48  	return b >= 32
    49  }