Mercurial > vim
comparison src/terminal.c @ 11670:3b2afa2b77b3 v8.0.0718
patch 8.0.0718: output of job in terminal is not displayed
commit https://github.com/vim/vim/commit/cb8bbe9bf3214d07580d6b43d6539416884153bd
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jul 16 13:48:22 2017 +0200
patch 8.0.0718: output of job in terminal is not displayed
Problem: Output of job in terminal is not displayed.
Solution: Connect the job output to the terminal.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 16 Jul 2017 14:00:03 +0200 |
parents | 26265ac3b7ed |
children | 1ce1376fbbf8 |
comparison
equal
deleted
inserted
replaced
11669:20bedd70c837 | 11670:3b2afa2b77b3 |
---|---|
26 * TODO: | 26 * TODO: |
27 * - free b_term when closing terminal. | 27 * - free b_term when closing terminal. |
28 * - remove term from first_term list when closing terminal. | 28 * - remove term from first_term list when closing terminal. |
29 * - set buffer options to be scratch, hidden, nomodifiable, etc. | 29 * - set buffer options to be scratch, hidden, nomodifiable, etc. |
30 * - set buffer name to command, add (1) to avoid duplicates. | 30 * - set buffer name to command, add (1) to avoid duplicates. |
31 * - if buffer is wiped, cleanup terminal, may stop job. | |
32 * - if the job ends, write "-- JOB ENDED --" in the terminal | |
31 * - command line completion (command name) | 33 * - command line completion (command name) |
32 * - support fixed size when 'termsize' is "rowsXcols". | 34 * - support fixed size when 'termsize' is "rowsXcols". |
33 * - support minimal size when 'termsize' is "rows*cols". | 35 * - support minimal size when 'termsize' is "rows*cols". |
34 * - support minimal size when 'termsize' is empty. | 36 * - support minimal size when 'termsize' is empty. |
35 * - implement ":buf {term-buf-name}" | 37 * - implement ":buf {term-buf-name}" |
38 * - implement term_sendkeys() send keystrokes to a terminal | 40 * - implement term_sendkeys() send keystrokes to a terminal |
39 * - implement term_wait() wait for screen to be updated | 41 * - implement term_wait() wait for screen to be updated |
40 * - implement term_scrape() inspect terminal screen | 42 * - implement term_scrape() inspect terminal screen |
41 * - implement term_open() open terminal window | 43 * - implement term_open() open terminal window |
42 * - implement term_getjob() | 44 * - implement term_getjob() |
45 * - implement 'termkey' | |
43 */ | 46 */ |
44 | 47 |
45 #include "vim.h" | 48 #include "vim.h" |
46 | 49 |
47 #ifdef FEAT_TERMINAL | 50 #ifdef FEAT_TERMINAL |
52 struct terminal_S { | 55 struct terminal_S { |
53 term_T *tl_next; | 56 term_T *tl_next; |
54 | 57 |
55 VTerm *tl_vterm; | 58 VTerm *tl_vterm; |
56 job_T *tl_job; | 59 job_T *tl_job; |
60 buf_T *tl_buffer; | |
57 | 61 |
58 /* Range of screen rows to update. Zero based. */ | 62 /* Range of screen rows to update. Zero based. */ |
59 int tl_dirty_row_start; /* -1 if nothing dirty */ | 63 int tl_dirty_row_start; /* -1 if nothing dirty */ |
60 int tl_dirty_row_end; /* row below last one to update */ | 64 int tl_dirty_row_end; /* row below last one to update */ |
61 | 65 |
97 win_T *old_curwin = curwin; | 101 win_T *old_curwin = curwin; |
98 typval_T argvars[2]; | 102 typval_T argvars[2]; |
99 term_T *term; | 103 term_T *term; |
100 VTerm *vterm; | 104 VTerm *vterm; |
101 VTermScreen *screen; | 105 VTermScreen *screen; |
106 jobopt_T opt; | |
102 | 107 |
103 if (check_restricted() || check_secure()) | 108 if (check_restricted() || check_secure()) |
104 return; | 109 return; |
105 | 110 |
106 term = (term_T *)alloc_clear(sizeof(term_T)); | 111 term = (term_T *)alloc_clear(sizeof(term_T)); |
118 { | 123 { |
119 /* split failed */ | 124 /* split failed */ |
120 vim_free(term); | 125 vim_free(term); |
121 return; | 126 return; |
122 } | 127 } |
128 term->tl_buffer = curbuf; | |
123 | 129 |
124 curbuf->b_term = term; | 130 curbuf->b_term = term; |
125 term->tl_next = first_term; | 131 term->tl_next = first_term; |
126 first_term = term; | 132 first_term = term; |
127 | 133 |
143 | 149 |
144 vterm = vterm_new(rows, cols); | 150 vterm = vterm_new(rows, cols); |
145 term->tl_vterm = vterm; | 151 term->tl_vterm = vterm; |
146 screen = vterm_obtain_screen(vterm); | 152 screen = vterm_obtain_screen(vterm); |
147 vterm_screen_set_callbacks(screen, &screen_callbacks, term); | 153 vterm_screen_set_callbacks(screen, &screen_callbacks, term); |
154 /* TODO: depends on 'encoding'. */ | |
155 vterm_set_utf8(vterm, 1); | |
156 /* Required to initialize most things. */ | |
157 vterm_screen_reset(screen, 1 /* hard */); | |
158 | |
159 /* By default NL means CR-NL. */ | |
160 vterm_input_write(vterm, "\x1b[20h", 5); | |
148 | 161 |
149 argvars[0].v_type = VAR_STRING; | 162 argvars[0].v_type = VAR_STRING; |
150 argvars[0].vval.v_string = eap->arg; | 163 argvars[0].vval.v_string = eap->arg; |
151 argvars[1].v_type = VAR_UNKNOWN; | 164 |
152 term->tl_job = job_start(argvars); | 165 clear_job_options(&opt); |
153 | 166 opt.jo_mode = MODE_RAW; |
154 /* TODO: setup channels to/from job */ | 167 opt.jo_out_mode = MODE_RAW; |
168 opt.jo_err_mode = MODE_RAW; | |
169 opt.jo_set = JO_MODE | JO_OUT_MODE | JO_ERR_MODE; | |
170 opt.jo_io[PART_OUT] = JIO_BUFFER; | |
171 opt.jo_io[PART_ERR] = JIO_BUFFER; | |
172 opt.jo_set |= JO_OUT_IO + (JO_OUT_IO << (PART_ERR - PART_OUT)); | |
173 opt.jo_io_buf[PART_OUT] = curbuf->b_fnum; | |
174 opt.jo_io_buf[PART_ERR] = curbuf->b_fnum; | |
175 opt.jo_set |= JO_OUT_BUF + (JO_OUT_BUF << (PART_ERR - PART_OUT)); | |
176 | |
177 term->tl_job = job_start(argvars, &opt); | |
178 | |
179 /* TODO: setup channel to job */ | |
155 /* Setup pty, see mch_call_shell(). */ | 180 /* Setup pty, see mch_call_shell(). */ |
181 } | |
182 | |
183 /* | |
184 * Invoked when "msg" output from a job was received. Write it to the terminal | |
185 * of "buffer". | |
186 */ | |
187 void | |
188 write_to_term(buf_T *buffer, char_u *msg, channel_T *channel) | |
189 { | |
190 size_t len = STRLEN(msg); | |
191 VTerm *vterm = buffer->b_term->tl_vterm; | |
192 | |
193 ch_logn(channel, "writing %d bytes to terminal", (int)len); | |
194 vterm_input_write(vterm, (char *)msg, len); | |
195 vterm_screen_flush_damage(vterm_obtain_screen(vterm)); | |
196 | |
197 /* TODO: only update once in a while. */ | |
198 update_screen(0); | |
199 setcursor(); | |
200 out_flush(); | |
201 } | |
202 | |
203 /* | |
204 * Called to update the window that contains the terminal. | |
205 */ | |
206 void | |
207 term_update_window(win_T *wp) | |
208 { | |
209 int vterm_rows; | |
210 int vterm_cols; | |
211 VTerm *vterm = wp->w_buffer->b_term->tl_vterm; | |
212 VTermScreen *screen = vterm_obtain_screen(vterm); | |
213 VTermPos pos; | |
214 | |
215 vterm_get_size(vterm, &vterm_rows, &vterm_cols); | |
216 | |
217 /* TODO: Only redraw what changed. */ | |
218 for (pos.row = 0; pos.row < wp->w_height; ++pos.row) | |
219 { | |
220 int off = screen_get_current_line_off(); | |
221 | |
222 if (pos.row < vterm_rows) | |
223 for (pos.col = 0; pos.col < wp->w_width && pos.col < vterm_cols; | |
224 ++pos.col) | |
225 { | |
226 VTermScreenCell cell; | |
227 int c; | |
228 | |
229 vterm_screen_get_cell(screen, pos, &cell); | |
230 /* TODO: use cell.attrs and colors */ | |
231 /* TODO: use cell.width */ | |
232 /* TODO: multi-byte chars */ | |
233 c = cell.chars[0]; | |
234 ScreenLines[off] = c == NUL ? ' ' : c; | |
235 ScreenAttrs[off] = 0; | |
236 ++off; | |
237 } | |
238 | |
239 screen_line(wp->w_winrow + pos.row, wp->w_wincol, pos.col, wp->w_width, | |
240 FALSE); | |
241 } | |
156 } | 242 } |
157 | 243 |
158 static int | 244 static int |
159 handle_damage(VTermRect rect, void *user) | 245 handle_damage(VTermRect rect, void *user) |
160 { | 246 { |
161 term_T *term = (term_T *)user; | 247 term_T *term = (term_T *)user; |
162 | 248 |
163 term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row); | 249 term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row); |
164 term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row); | 250 term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row); |
251 redraw_buf_later(term->tl_buffer, NOT_VALID); | |
165 return 1; | 252 return 1; |
166 } | 253 } |
167 | 254 |
168 static int | 255 static int |
169 handle_moverect(VTermRect dest, VTermRect src, void *user) | 256 handle_moverect(VTermRect dest, VTermRect src, void *user) |
170 { | 257 { |
258 term_T *term = (term_T *)user; | |
259 | |
171 /* TODO */ | 260 /* TODO */ |
261 redraw_buf_later(term->tl_buffer, NOT_VALID); | |
172 return 1; | 262 return 1; |
173 } | 263 } |
174 | 264 |
175 static int | 265 static int |
176 handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user) | 266 handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user) |
177 { | 267 { |
178 /* TODO: handle moving the cursor. */ | 268 term_T *term = (term_T *)user; |
269 win_T *wp; | |
270 int is_current = FALSE; | |
271 | |
272 FOR_ALL_WINDOWS(wp) | |
273 { | |
274 if (wp->w_buffer == term->tl_buffer) | |
275 { | |
276 /* TODO: limit to window size? */ | |
277 wp->w_wrow = pos.row; | |
278 wp->w_wcol = pos.col; | |
279 if (wp == curwin) | |
280 is_current = TRUE; | |
281 } | |
282 } | |
283 | |
284 if (is_current) | |
285 { | |
286 setcursor(); | |
287 out_flush(); | |
288 } | |
289 | |
179 return 1; | 290 return 1; |
180 } | 291 } |
181 | 292 |
182 static int | 293 static int |
183 handle_resize(int rows, int cols, void *user) | 294 handle_resize(int rows, int cols, void *user) |
184 { | 295 { |
296 term_T *term = (term_T *)user; | |
297 | |
185 /* TODO: handle terminal resize. */ | 298 /* TODO: handle terminal resize. */ |
299 redraw_buf_later(term->tl_buffer, NOT_VALID); | |
186 return 1; | 300 return 1; |
187 } | 301 } |
188 | 302 |
189 /* TODO: Use win_del_lines() to make scroll up efficient. */ | 303 /* TODO: Use win_del_lines() to make scroll up efficient. */ |
190 | 304 |
199 * - Write keys to vterm: vterm_keyboard_key() | 313 * - Write keys to vterm: vterm_keyboard_key() |
200 * - read the output (xterm escape sequences): vterm_output_read() | 314 * - read the output (xterm escape sequences): vterm_output_read() |
201 * - Write output to channel. | 315 * - Write output to channel. |
202 */ | 316 */ |
203 | 317 |
204 /* TODO: function to read job output from the channel. | |
205 * write to vterm: vterm_input_write() | |
206 * This will invoke screen callbacks. | |
207 * call vterm_screen_flush_damage() | |
208 */ | |
209 | |
210 #endif /* FEAT_TERMINAL */ | 318 #endif /* FEAT_TERMINAL */ |