@@ -3,6 +3,7 @@ package cmd
33import (
44 "bufio"
55 "os"
6+ "os/signal"
67 "unicode/utf8"
78
89 "github.com/zix99/rare/cmd/helpers"
@@ -27,40 +28,56 @@ func filterFunction(c *cli.Context, fileGlobs ...string) error {
2728
2829 stdout := bufio .NewWriter (os .Stdout )
2930
31+ exitSignal := make (chan os.Signal , 1 )
32+ signal .Notify (exitSignal , os .Interrupt )
33+ interrupted := false
34+
35+ readChan := extractor .ReadFull ()
36+
3037OUTER_LOOP:
31- for matchBatch := range extractor .ReadFull () {
32- for _ , match := range matchBatch {
33- if writeLines {
34- color .WriteString (stdout , color .BrightGreen , match .Source )
35- stdout .WriteByte (' ' )
36- color .WriteUint64 (stdout , color .BrightYellow , match .LineNumber )
37- stdout .WriteString (": " )
38+ for {
39+ select {
40+ case <- exitSignal :
41+ interrupted = true
42+ break OUTER_LOOP
43+ case matchBatch , more := <- readChan :
44+ if ! more {
45+ break OUTER_LOOP
3846 }
3947
40- switch {
41- case customExtractor :
42- stdout .WriteString (match .Extracted )
43- case onlyText && ! utf8 .ValidString (match .Line ):
44- color .WriteString (stdout , color .BrightBlue , "Binary Match" )
45- case len (match .Indices ) == 2 :
46- // Single match, highlight entire phrase
47- color .WrapIndices (stdout , match .Line , match .Indices )
48- default :
49- // Multi-match groups, highlight individual groups
50- color .WrapIndices (stdout , match .Line , match .Indices [2 :])
48+ for _ , match := range matchBatch {
49+ if writeLines {
50+ color .WriteString (stdout , color .BrightGreen , match .Source )
51+ stdout .WriteByte (' ' )
52+ color .WriteUint64 (stdout , color .BrightYellow , match .LineNumber )
53+ stdout .WriteString (": " )
54+ }
55+
56+ switch {
57+ case customExtractor :
58+ stdout .WriteString (match .Extracted )
59+ case onlyText && ! utf8 .ValidString (match .Line ):
60+ color .WriteString (stdout , color .BrightBlue , "Binary Match" )
61+ case len (match .Indices ) == 2 :
62+ // Single match, highlight entire phrase
63+ color .WrapIndices (stdout , match .Line , match .Indices )
64+ default :
65+ // Multi-match groups, highlight individual groups
66+ color .WrapIndices (stdout , match .Line , match .Indices [2 :])
67+ }
68+ stdout .WriteByte ('\n' )
69+
70+ readLines ++
71+ if numLineLimit > 0 && readLines >= numLineLimit {
72+ break OUTER_LOOP
73+ }
5174 }
52- stdout .WriteByte ('\n' )
5375
54- readLines ++
55- if numLineLimit > 0 && readLines >= numLineLimit {
56- break OUTER_LOOP
76+ // Flush after each batch to make file-following work as expected
77+ if err := stdout . Flush (); err != nil {
78+ logger . Fatal ( helpers . ExitCodeOutputError , err )
5779 }
5880 }
59-
60- // Flush after each batch to make file-following work as expected
61- if err := stdout .Flush (); err != nil {
62- logger .Fatal (helpers .ExitCodeOutputError , err )
63- }
6481 }
6582
6683 // Final flush
@@ -80,7 +97,7 @@ OUTER_LOOP:
8097 }
8198 os .Stderr .WriteString ("\n " )
8299
83- return helpers .DetermineErrorState (batcher , extractor , nil )
100+ return helpers .DetermineErrorState (interrupted , batcher , extractor , nil )
84101}
85102
86103func getFilterArgs (isSearch bool ) []cli.Flag {
0 commit comments