2626#include < dlfcn.h>
2727#include < getopt.h>
2828#include < unistd.h>
29+ #include < termios.h>
30+ #include < stdlib.h>
2931
3032#include < algorithm>
3133#include < cerrno>
@@ -66,6 +68,32 @@ using namespace std::string_view_literals;
6668bool display_modules = false ;
6769bool display_list_logos = false ;
6870
71+ struct termios orig_termios;
72+
73+ static void disable_raw_mode ()
74+ {
75+ tcsetattr (STDIN_FILENO, TCSAFLUSH, &orig_termios);
76+ }
77+
78+ static void enable_raw_mode ()
79+ {
80+ tcgetattr (STDIN_FILENO, &orig_termios);
81+ atexit (disable_raw_mode);
82+
83+ struct termios raw = orig_termios;
84+ raw.c_lflag &= ~(ECHO | ICANON); // Disable echo and canonical mode
85+ tcsetattr (STDIN_FILENO, TCSAFLUSH, &raw);
86+ }
87+
88+ static int kbhit ()
89+ {
90+ struct timeval tv = {0L , 0L };
91+ fd_set fds;
92+ FD_ZERO (&fds);
93+ FD_SET (STDIN_FILENO, &fds);
94+ return select (STDIN_FILENO + 1 , &fds, NULL , NULL , &tv) > 0 ;
95+ }
96+
6997// Print the version and some other infos, then exit successfully
7098static void version ()
7199{
@@ -158,7 +186,7 @@ GUI/TERMINAL OPTIONS:
158186
159187LIVE MODE:
160188 --loop-ms <NUM> Run in live mode, updating every <NUM> milliseconds (min: 50).
161- Use inferior <NUM> than 50 to disable (default) .
189+ Use inferior <NUM> than 200 to disable. Press 'q' to exit .
162190
163191EXAMPLES:
164192 1. Minimal output with default logo:
@@ -657,7 +685,7 @@ int main(int argc, char* argv[])
657685 moduleMap.emplace (module .name , module );
658686 }
659687
660- is_live_mode = (config.loop_ms > 50 );
688+ is_live_mode = (config.loop_ms >= 200 );
661689
662690 if (config.source_path .empty () || config.source_path == " off" )
663691 config.args_disable_source = true ;
@@ -700,7 +728,6 @@ int main(int argc, char* argv[])
700728 if (!config.wrap_lines )
701729 {
702730 // https://en.cppreference.com/w/c/program/exit
703- // if something goes wrong like a segfault, then re-enable the cursor again
704731 std::atexit (enable_cursor);
705732
706733 // hide cursor and disable line wrapping
@@ -709,10 +736,23 @@ int main(int argc, char* argv[])
709736
710737 if (is_live_mode)
711738 {
739+ enable_raw_mode ();
712740 const std::chrono::milliseconds sleep_ms{ config.loop_ms };
713741
714742 while (true )
715743 {
744+ if (kbhit ())
745+ {
746+ char c;
747+ read (STDIN_FILENO, &c, 1 );
748+ if (c == ' q' || c == ' Q' )
749+ {
750+ info (" exiting...\n " );
751+ disable_raw_mode ();
752+ break ;
753+ }
754+ }
755+
716756 // clear screen and go to position 0, 0
717757 write (STDOUT_FILENO, " \33 [H\33 [2J" , 7 );
718758 fmt::print (" \033 [0;0H" );
0 commit comments