comparison command-window.cpp @ 11:b652a5528fb1

handle EOF on input; more misc refactoring
author John W. Eaton <jwe@octave.org>
date Thu, 23 May 2019 13:42:57 -0400
parents 822a2fe5bb51
children 894be158b32d
comparison
equal deleted inserted replaced
10:69f5d5e42d2b 11:b652a5528fb1
18 #include <readline/readline.h> 18 #include <readline/readline.h>
19 #include <readline/history.h> 19 #include <readline/history.h>
20 20
21 namespace calc 21 namespace calc
22 { 22 {
23 // We could eliminate this global variable and the global
24 // command_window::the_command_window variable if readline callbacks
25 // could be defined as C++ lambda functions. Then the lambdas could
26 // have direct access to the command_window object and it could
27 // contain the next available character.
28
23 static int available_char = 0; 29 static int available_char = 0;
24 30
25 // vvvvv readline vvvvv 31 // vvvvv readline vvvvv
26 32
27 static int getc (FILE *) 33 static int getc (FILE *)
37 emit command_window::the_command_window->redisplay_signal (); 43 emit command_window::the_command_window->redisplay_signal ();
38 } 44 }
39 45
40 static void prep_term (int) 46 static void prep_term (int)
41 { 47 {
48 // Anything to do here?
42 } 49 }
43 50
44 static void deprep_term (void) 51 static void deprep_term (void)
45 { 52 {
53 // Anything to do here?
46 } 54 }
47 55
48 static void accept_line (char *line) 56 static void accept_line (char *line)
49 { 57 {
50 if (command_window::the_command_window) 58 if (command_window::the_command_window)
51 command_window::the_command_window->accept_line (line ? line : ""); 59 {
60 if (! line)
61 command_window::the_command_window->eof ();
62 else
63 command_window::the_command_window->accept_line (line);
64 }
52 } 65 }
53 66
54 static void display_completion_matches (char **matches, int num_matches, 67 static void display_completion_matches (char **matches, int num_matches,
55 int /* max_length */) 68 int /* max_length */)
56 { 69 {
68 81
69 emit command_window::the_command_window->redisplay_signal (); 82 emit command_window::the_command_window->redisplay_signal ();
70 } 83 }
71 } 84 }
72 85
73 void readline_init (void) 86 static void readline_init (void)
74 { 87 {
75 rl_initialize (); 88 rl_initialize ();
76 89
77 rl_getc_function = getc; 90 rl_getc_function = getc;
78 rl_redisplay_function = redisplay; 91 rl_redisplay_function = redisplay;
81 rl_completion_display_matches_hook = display_completion_matches; 94 rl_completion_display_matches_hook = display_completion_matches;
82 95
83 rl_callback_handler_install (">> ", accept_line); 96 rl_callback_handler_install (">> ", accept_line);
84 } 97 }
85 98
86 void readline_fini (void) 99 static void readline_fini (void)
87 { 100 {
88 rl_callback_handler_remove (); 101 rl_callback_handler_remove ();
89 } 102 }
90 103
91 // ^^^^^ readline ^^^^^ 104 // ^^^^^ readline ^^^^^
92 105
93 command_window *command_window::the_command_window = nullptr; 106 command_window *command_window::the_command_window = nullptr;
94 107
95 command_window::command_window (QWidget *p) 108 command_window::command_window (QWidget *p)
96 : QTextEdit (p), 109 : QTextEdit (p), m_buffer (new QTextDocument ()),
97 m_buffer (new QTextDocument ()),
98 m_interpreter (new calc::qt_interpreter ()), 110 m_interpreter (new calc::qt_interpreter ()),
99 beg_mark (), prompt_mark () 111 beg_mark (), prompt_mark ()
100 { 112 {
101 if (the_command_window) 113 if (the_command_window)
102 { 114 {
124 connect (this, SIGNAL (redisplay_signal (void)), 136 connect (this, SIGNAL (redisplay_signal (void)),
125 this, SLOT (redisplay (void))); 137 this, SLOT (redisplay (void)));
126 138
127 connect (this, SIGNAL (accept_line_signal (const QString&)), 139 connect (this, SIGNAL (accept_line_signal (const QString&)),
128 m_interpreter, SLOT (accept_input_line (const QString&))); 140 m_interpreter, SLOT (accept_input_line (const QString&)));
141
142 connect (this, SIGNAL (eof_signal (void)),
143 this, SLOT (close (void)));
129 144
130 insert_at_end 145 insert_at_end
131 ("Qt Example Calculator.\n" 146 ("Qt Example Calculator.\n"
132 "Available operations: + - * / ^ ()\n" 147 "Available operations: + - * / ^ ()\n"
133 "Semicolon terminates statement.\n" 148 "Semicolon terminates statement.\n"
134 "Up Arrow key moves to previous line in the command history.\n" 149 "Up Arrow key moves to previous line in the command history.\n"
135 "Down Arrow key moves to next line in the comand history.\n\n"); 150 "Down Arrow key moves to next line in the comand history.\n\n");
136 151
137 beg_mark = set_mark (); 152 beg_mark = set_mark ();
138 153
154 readline_init ();
155
139 // Defer initializing and executing the interpreter until after the main 156 // Defer initializing and executing the interpreter until after the main
140 // window and QApplication are running to prevent race conditions 157 // window and QApplication are running to prevent race conditions
141 QTimer::singleShot (0, m_interpreter, SLOT (execute (void))); 158 QTimer::singleShot (0, m_interpreter, SLOT (execute (void)));
142 } 159 }
143 160
161 command_window::~command_window (void)
162 {
163 readline_fini ();
164 }
165
144 // Accept an input line, parse and possibly execute it. 166 // Accept an input line, parse and possibly execute it.
145 167
146 void command_window::accept_line (const std::string& line) 168 void command_window::accept_line (const std::string& line)
147 { 169 {
148 insert_at_end ("\n"); 170 insert_at_end ("\n");
152 add_history (line.c_str ()); 174 add_history (line.c_str ());
153 using_history (); 175 using_history ();
154 176
155 emit accept_line_signal (QString::fromStdString (line)); 177 emit accept_line_signal (QString::fromStdString (line));
156 } 178 }
179 }
180
181 void command_window::eof (void)
182 {
183 emit eof_signal ();
157 } 184 }
158 185
159 void command_window::insert_at_end (const std::string& text) 186 void command_window::insert_at_end (const std::string& text)
160 { 187 {
161 scroll_to_bottom (); 188 scroll_to_bottom ();