@@ -581,7 +581,7 @@ void Query::draw()
581581void Query::disp (int row)
582582{
583583 Screen::normal ();
584- if (row < rows_)
584+ if (row < rows_ + append_ )
585585 {
586586 if (selected_[row])
587587 Screen::select ();
@@ -683,7 +683,7 @@ void Query::redraw()
683683 }
684684 else
685685 {
686- // do not show dots
686+ // reset to 4 to do not show dots
687687 tick_ = 4 ;
688688
689689 if (error_ == -1 )
@@ -698,7 +698,7 @@ void Query::redraw()
698698 if (row_ < 0 )
699699 row_ = 0 ;
700700
701- int end = row_ + maxrows_ - 2 ;
701+ int end = row_ + append_ + maxrows_ - 2 ;
702702
703703 for (int i = row_; i < end; ++i)
704704 disp (i);
@@ -919,6 +919,7 @@ void Query::query()
919919 search_thread_.join ();
920920
921921 // join the stdin sender thread
922+ stdin_stop = true ;
922923 if (stdin_thread_.joinable ())
923924 stdin_thread_.join ();
924925}
@@ -1482,6 +1483,8 @@ void Query::query_ui()
14821483// start a new search, cancel the previous search when still running
14831484void Query::search ()
14841485{
1486+ stop_stdin ();
1487+
14851488 bool cancel = !eof_;
14861489
14871490 if (cancel)
@@ -1494,6 +1497,22 @@ void Query::search()
14941497 Static::cancel_ugrep ();
14951498 }
14961499
1500+ if (search_thread_.joinable ())
1501+ {
1502+ if (cancel && error_ == -1 )
1503+ {
1504+ const int banlen = 256 ;
1505+ char banner[banlen];
1506+ snprintf (banner, banlen, " restarting: please be patient while I cancel searching large files...%*s" , banlen - 70 , " " );
1507+ Screen::normal ();
1508+ Screen::invert ();
1509+ Screen::put (maxrows_ - 1 , 0 , banner);
1510+ Screen::normal ();
1511+ }
1512+
1513+ search_thread_.join ();
1514+ }
1515+
14971516#ifdef OS_WIN
14981517
14991518 hPipe_ = nonblocking_pipe (search_pipe_);
@@ -1522,23 +1541,8 @@ void Query::search()
15221541
15231542#endif
15241543
1525- if (search_thread_.joinable ())
1526- {
1527- if (cancel && error_ == -1 )
1528- {
1529- const int banlen = 256 ;
1530- char banner[banlen];
1531- snprintf (banner, banlen, " restarting: please be patient while I cancel searching large files...%*s" , banlen - 70 , " " );
1532- Screen::normal ();
1533- Screen::invert ();
1534- Screen::put (maxrows_ - 1 , 0 , banner);
1535- Screen::normal ();
1536- }
1537-
1538- search_thread_.join ();
1539- }
1540-
15411544 eof_ = false ;
1545+ append_ = false ;
15421546 row_ = 0 ;
15431547 rows_ = 0 ;
15441548 skip_ = 0 ;
@@ -1568,7 +1572,7 @@ void Query::search()
15681572
15691573 set_flags ();
15701574
1571- set_stdin ();
1575+ start_stdin ();
15721576
15731577 if (error_ == -1 )
15741578 {
@@ -1668,19 +1672,19 @@ bool Query::update()
16681672 fetch (row_ - (row_ % Screen::rows) + 2 * Screen::rows);
16691673
16701674 // display the viewable portion when updated
1671- if (rows_ > begin && begin < row_ + maxrows_ - 2 )
1675+ if (rows_ + append_ > begin && begin < row_ + append_ + maxrows_ - 2 )
16721676 {
16731677 Screen::normal ();
16741678
1675- if (begin + maxrows_ - 2 > rows_)
1676- begin = rows_ - maxrows_ + 2 ;
1679+ int end = rows_ + append_;
1680+
1681+ if (begin + maxrows_ - 2 > end)
1682+ begin = end - maxrows_ + 2 ;
16771683 if (begin < 0 )
16781684 begin = 0 ;
16791685 if (begin < row_)
16801686 begin = row_;
16811687
1682- int end = rows_;
1683-
16841688 if (end > row_ + maxrows_ - 2 )
16851689 end = row_ + maxrows_ - 2 ;
16861690
@@ -1690,9 +1694,11 @@ bool Query::update()
16901694
16911695 if (error_ == -1 )
16921696 {
1693- if (tick_ < 8 && rows_ < row_ + maxrows_ - 2 )
1697+ int end = rows_ + append_;
1698+
1699+ if (tick_ < 8 && end < row_ + maxrows_ - 2 )
16941700 {
1695- int row = rows_ - row_ + 1 ;
1701+ int row = end - row_ + 1 ;
16961702
16971703 // no dots and clear below when we hit eof
16981704 if (eof_)
@@ -4115,34 +4121,22 @@ void Query::get_stdin()
41154121 // if standard input is searched, then buffer all its text
41164122 if (flag_stdin)
41174123 {
4118- reflex::BufferedInput input (stdin, flag_encoding_type);
4124+ #ifndef OS_WIN
4125+ fcntl (0 , F_SETFL, fcntl (0 , F_GETFL) | O_NONBLOCK);
4126+ #endif
41194127
4120- while (true )
4121- {
4122- size_t len = input.get (buffer_, QUERY_BUFFER_SIZE);
4123- if (len == 0 )
4124- break ;
4125- stdin_buffer_.append (buffer_, len);
4126- }
4128+ stdin_input_ = stdin;
4129+ stdin_input_.file_encoding (flag_encoding_type);
4130+ stdin_buffer_.clear ();
41274131 }
41284132}
41294133
4130- void Query::set_stdin ()
4134+ // start a new stdin sender thread and pipe from sender to the search engine
4135+ void Query::start_stdin ()
41314136{
41324137 // if standard input is searched, start thread to reproduce its text on demand
41334138 if (flag_stdin)
41344139 {
4135- // close the stdin pipe when open
4136- if (Static::source != stdin && Static::source != NULL )
4137- {
4138- fclose (Static::source);
4139- Static::source = NULL ;
4140- }
4141-
4142- // join the stdin_sender
4143- if (stdin_thread_.joinable ())
4144- stdin_thread_.join ();
4145-
41464140 // create a new pipe
41474141 if (pipe (stdin_pipe_) < 0 )
41484142 {
@@ -4156,19 +4150,61 @@ void Query::set_stdin()
41564150 Static::source = fdopen (stdin_pipe_[0 ], " rb" );
41574151
41584152 // run stdin_sender in the background to push buffered standard input down the pipe
4153+ stdin_stop = false ;
41594154 stdin_thread_ = std::thread (Query::stdin_sender, stdin_pipe_[1 ]);
41604155 }
41614156}
41624157
4158+ // stop stdin sender thread
4159+ void Query::stop_stdin ()
4160+ {
4161+ if (flag_stdin)
4162+ {
4163+ // close the stdin pipe when open
4164+ if (Static::source != stdin && Static::source != NULL )
4165+ fclose (Static::source);
4166+
4167+ // join the stdin_sender
4168+ stdin_stop = true ;
4169+ if (stdin_thread_.joinable ())
4170+ stdin_thread_.join ();
4171+ }
4172+ }
4173+
41634174// push standard input down the specified pipe fd
4164- ssize_t Query::stdin_sender (int fd)
4175+ void Query::stdin_sender (int fd)
41654176{
41664177 // write the stdin data all at once, we can ignore the return value
4167- ssize_t nwritten = write (fd, stdin_buffer_.c_str (), stdin_buffer_. size () );
4178+ ssize_t len = stdin_buffer_. size (), nwritten = write (fd, stdin_buffer_.c_str (), len );
41684179
4169- close (fd);
4180+ #ifndef OS_WIN
4181+ while (!stdin_stop && !feof (stdin) && nwritten == len)
4182+ {
4183+ len = stdin_input_.file_get (buffer_, QUERY_BUFFER_SIZE);
4184+ if (len == 0 )
4185+ {
4186+ struct timeval tv;
4187+ fd_set rfds, efds;
4188+ FD_ZERO (&rfds);
4189+ FD_ZERO (&efds);
4190+ FD_SET (0 , &rfds);
4191+ FD_SET (0 , &efds);
4192+ tv.tv_sec = 0 ;
4193+ tv.tv_usec = 10000 ; // 10ms timeout
4194+ clearerr (stdin);
4195+ if (::select (0 + 1 , &rfds, NULL , &efds, &tv) >= 0 && FD_ISSET (0 , &efds) != 0 )
4196+ break ;
4197+ nwritten = 0 ;
4198+ }
4199+ else
4200+ {
4201+ stdin_buffer_.append (buffer_, len);
4202+ nwritten = write (fd, buffer_, len);
4203+ }
4204+ }
4205+ #endif
41704206
4171- return nwritten ;
4207+ close (fd) ;
41724208}
41734209
41744210// true if view_[ref] has a valid filename/filepath identified by three \0 markers and differs from the given filename, then assigns filename
@@ -4413,9 +4449,11 @@ size_t Query::buflen_ = 0;
44134449char Query::buffer_[QUERY_BUFFER_SIZE];
44144450int Query::search_pipe_[2 ];
44154451std::thread Query::search_thread_;
4452+ reflex::Input Query::stdin_input_;
44164453std::string Query::stdin_buffer_;
44174454int Query::stdin_pipe_[2 ];
44184455std::thread Query::stdin_thread_;
4456+ volatile bool Query::stdin_stop = false ;
44194457size_t Query::searched_ = 0 ;
44204458size_t Query::found_ = 0 ;
44214459int Query::tick_ = 0 ;
0 commit comments