diff --git a/README.md b/README.md index 94673d1..c6401ba 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,18 @@ Default value for StickySelection is false. OnCancel is equivalent to `--on-cancel` command line option. +### MaxScanBufferSize + +```json +{ + "MaxScanBufferSize": 256 +} +``` + +Controls the buffer sized used by `bufio.Scanner`, which is responsible for +reading the input lines. If you believe that your input has very long lines +that prohibit peco from reading them, try increasing this number + ## Keymaps Example: diff --git a/interface.go b/interface.go index 1816bed..98c9d2c 100644 --- a/interface.go +++ b/interface.go @@ -78,6 +78,7 @@ type Peco struct { keymap Keymap layoutType string location Location + maxScanBufferSize int mutex sync.Mutex onCancel string prompt string @@ -167,9 +168,9 @@ type Screen interface { // Termbox just hands out the processing to the termbox library type Termbox struct { - mutex sync.Mutex - resumeCh chan(struct{}) - suspendCh chan(struct{}) + mutex sync.Mutex + resumeCh chan (struct{}) + suspendCh chan (struct{}) } // View handles the drawing/updating the screen @@ -299,6 +300,7 @@ type Config struct { Command []CommandConfig QueryExecutionDelay int StickySelection bool + MaxScanBufferSize int // If this is true, then the prefix for single key jump mode // is displayed by default. diff --git a/peco.go b/peco.go index 0da9d92..9155cc2 100644 --- a/peco.go +++ b/peco.go @@ -503,6 +503,11 @@ func (p *Peco) ApplyConfig(opts CLIOptions) error { } } + p.maxScanBufferSize = 256 + if v := p.config.MaxScanBufferSize; v > 0 { + p.maxScanBufferSize = v + } + p.enableSep = opts.OptEnableNullSep if i := opts.OptInitialIndex; i >= 0 { diff --git a/source.go b/source.go index c3516ad..9b269fa 100644 --- a/source.go +++ b/source.go @@ -77,7 +77,12 @@ func (s *Source) Setup(ctx context.Context, state *Peco) { // Note: this will be a no-op if notify.Do has been called before defer notify.Do(notifycb) + if pdebug.Enabled { + pdebug.Printf("Source: using buffer size of %dkb", state.maxScanBufferSize) + } + scanbuf := make([]byte, state.maxScanBufferSize*1024) scanner := bufio.NewScanner(s.in) + scanner.Buffer(scanbuf, 0) defer func() { if util.IsTty(s.in) { return @@ -95,7 +100,18 @@ func (s *Source) Setup(ctx context.Context, state *Peco) { } defer close(lines) - for scanner.Scan() { + for loop := true; loop; { + if !scanner.Scan() { + switch err := scanner.Err(); err { + case nil: // if error was io.EOF, returns nil + loop = false + default: + if pdebug.Enabled { + pdebug.Printf("err: %s", err) + } + } + continue + } lines <- scanner.Text() scanned++ }