comparison src/terminal.c @ 11684:1ce1376fbbf8 v8.0.0725

patch 8.0.0725: a terminal window does not handle keyboard input commit https://github.com/vim/vim/commit/938783d0ab5678c259ceb62b15be72abe69362fa Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 16 20:13:26 2017 +0200 patch 8.0.0725: a terminal window does not handle keyboard input Problem: A terminal window does not handle keyboard input. Solution: Add terminal_loop(). ":term bash -i" sort of works now.
author Christian Brabandt <cb@256bit.org>
date Sun, 16 Jul 2017 20:15:03 +0200
parents 3b2afa2b77b3
children ce434212d682
comparison
equal deleted inserted replaced
11683:0cc8e85e29d4 11684:1ce1376fbbf8
13 * For a terminal one VTerm is constructed. This uses libvterm. A copy of 13 * For a terminal one VTerm is constructed. This uses libvterm. A copy of
14 * that library is in the libvterm directory. 14 * that library is in the libvterm directory.
15 * 15 *
16 * The VTerm invokes callbacks when its screen contents changes. The line 16 * The VTerm invokes callbacks when its screen contents changes. The line
17 * range is stored in tl_dirty_row_start and tl_dirty_row_end. Once in a 17 * range is stored in tl_dirty_row_start and tl_dirty_row_end. Once in a
18 * while, if the window is visible, the screen contents is drawn. 18 * while, if the terminal window is visible, the screen contents is drawn.
19 * 19 *
20 * If the terminal window has keyboard focus, typed keys are converted to the 20 * If the terminal window has keyboard focus, typed keys are converted to the
21 * terminal encoding and writting to the job over a channel. 21 * terminal encoding and writting to the job over a channel.
22 * 22 *
23 * If the job produces output, it is written to the VTerm. 23 * If the job produces output, it is written to the VTerm.
24 * This will result in screen updates. 24 * This will result in screen updates.
25 * 25 *
26 * TODO: 26 * TODO:
27 * - pressing Enter sends two CR and/or NL characters to "bash -i"?
27 * - free b_term when closing terminal. 28 * - free b_term when closing terminal.
28 * - remove term from first_term list when closing terminal. 29 * - remove term from first_term list when closing terminal.
29 * - set buffer options to be scratch, hidden, nomodifiable, etc. 30 * - set buffer options to be scratch, hidden, nomodifiable, etc.
30 * - set buffer name to command, add (1) to avoid duplicates. 31 * - set buffer name to command, add (1) to avoid duplicates.
31 * - if buffer is wiped, cleanup terminal, may stop job. 32 * - if buffer is wiped, cleanup terminal, may stop job.
32 * - if the job ends, write "-- JOB ENDED --" in the terminal 33 * - if the job ends, write "-- JOB ENDED --" in the terminal
33 * - command line completion (command name) 34 * - when closing window and job ended, delete the terminal
35 * - when closing window and job has not ended, make terminal hidden?
36 * - Use a pty for I/O with the job.
37 * - Windows implementation:
38 * (WiP): https://github.com/mattn/vim/tree/terminal
39 * src/os_win32.c mch_open_terminal()
40 Using winpty ?
41 * - command line completion for :terminal
34 * - support fixed size when 'termsize' is "rowsXcols". 42 * - support fixed size when 'termsize' is "rowsXcols".
35 * - support minimal size when 'termsize' is "rows*cols". 43 * - support minimal size when 'termsize' is "rows*cols".
36 * - support minimal size when 'termsize' is empty. 44 * - support minimal size when 'termsize' is empty.
37 * - implement ":buf {term-buf-name}" 45 * - implement ":buf {term-buf-name}"
38 * - implement term_getsize() 46 * - implement term_getsize()
155 vterm_set_utf8(vterm, 1); 163 vterm_set_utf8(vterm, 1);
156 /* Required to initialize most things. */ 164 /* Required to initialize most things. */
157 vterm_screen_reset(screen, 1 /* hard */); 165 vterm_screen_reset(screen, 1 /* hard */);
158 166
159 /* By default NL means CR-NL. */ 167 /* By default NL means CR-NL. */
168 /* TODO: this causes two prompts when using ":term bash -i". */
160 vterm_input_write(vterm, "\x1b[20h", 5); 169 vterm_input_write(vterm, "\x1b[20h", 5);
161 170
162 argvars[0].v_type = VAR_STRING; 171 argvars[0].v_type = VAR_STRING;
163 argvars[0].vval.v_string = eap->arg; 172 argvars[0].vval.v_string = eap->arg;
164 173
300 return 1; 309 return 1;
301 } 310 }
302 311
303 /* TODO: Use win_del_lines() to make scroll up efficient. */ 312 /* TODO: Use win_del_lines() to make scroll up efficient. */
304 313
305 /* TODO: function to update the window. 314
306 * Get the screen contents from vterm with vterm_screen_get_cell(). 315 /*
307 * put in current_ScreenLine and call screen_line(). 316 * Wait for input and send it to the job.
308 */
309
310 /* TODO: function to wait for input and send it to the job.
311 * Return when a CTRL-W command is typed that moves to another window. 317 * Return when a CTRL-W command is typed that moves to another window.
312 * Convert special keys to vterm keys: 318 */
313 * - Write keys to vterm: vterm_keyboard_key() 319 void
314 * - read the output (xterm escape sequences): vterm_output_read() 320 terminal_loop(void)
315 * - Write output to channel. 321 {
316 */ 322 VTerm *vterm = curbuf->b_term->tl_vterm;
323 char buf[200];
324
325 for (;;)
326 {
327 int c;
328 VTermKey key = VTERM_KEY_NONE;
329 VTermModifier mod = VTERM_MOD_NONE;
330 size_t len;
331
332 update_screen(0);
333 setcursor();
334 out_flush();
335
336 c = vgetc();
337 switch (c)
338 {
339 case Ctrl_W:
340 stuffcharReadbuff(Ctrl_W);
341 return;
342
343 case CAR: key = VTERM_KEY_ENTER; break;
344 case ESC: key = VTERM_KEY_ESCAPE; break;
345 case K_BS: key = VTERM_KEY_BACKSPACE; break;
346 case K_DEL: key = VTERM_KEY_DEL; break;
347 case K_DOWN: key = VTERM_KEY_DOWN; break;
348 case K_END: key = VTERM_KEY_END; break;
349 case K_F10: key = VTERM_KEY_FUNCTION(10); break;
350 case K_F11: key = VTERM_KEY_FUNCTION(11); break;
351 case K_F12: key = VTERM_KEY_FUNCTION(12); break;
352 case K_F1: key = VTERM_KEY_FUNCTION(1); break;
353 case K_F2: key = VTERM_KEY_FUNCTION(2); break;
354 case K_F3: key = VTERM_KEY_FUNCTION(3); break;
355 case K_F4: key = VTERM_KEY_FUNCTION(4); break;
356 case K_F5: key = VTERM_KEY_FUNCTION(5); break;
357 case K_F6: key = VTERM_KEY_FUNCTION(6); break;
358 case K_F7: key = VTERM_KEY_FUNCTION(7); break;
359 case K_F8: key = VTERM_KEY_FUNCTION(8); break;
360 case K_F9: key = VTERM_KEY_FUNCTION(9); break;
361 case K_HOME: key = VTERM_KEY_HOME; break;
362 case K_INS: key = VTERM_KEY_INS; break;
363 case K_K0: key = VTERM_KEY_KP_0; break;
364 case K_K1: key = VTERM_KEY_KP_1; break;
365 case K_K2: key = VTERM_KEY_KP_2; break;
366 case K_K3: key = VTERM_KEY_KP_3; break;
367 case K_K4: key = VTERM_KEY_KP_4; break;
368 case K_K5: key = VTERM_KEY_KP_5; break;
369 case K_K6: key = VTERM_KEY_KP_6; break;
370 case K_K7: key = VTERM_KEY_KP_7; break;
371 case K_K8: key = VTERM_KEY_KP_8; break;
372 case K_K9: key = VTERM_KEY_KP_9; break;
373 case K_KDEL: key = VTERM_KEY_DEL; break; /* TODO */
374 case K_KDIVIDE: key = VTERM_KEY_KP_DIVIDE; break;
375 case K_KEND: key = VTERM_KEY_KP_1; break; /* TODO */
376 case K_KENTER: key = VTERM_KEY_KP_ENTER; break;
377 case K_KHOME: key = VTERM_KEY_KP_7; break; /* TODO */
378 case K_KINS: key = VTERM_KEY_KP_0; break; /* TODO */
379 case K_KMINUS: key = VTERM_KEY_KP_MINUS; break;
380 case K_KMULTIPLY: key = VTERM_KEY_KP_MULT; break;
381 case K_KPAGEDOWN: key = VTERM_KEY_KP_3; break; /* TODO */
382 case K_KPAGEUP: key = VTERM_KEY_KP_9; break; /* TODO */
383 case K_KPLUS: key = VTERM_KEY_KP_PLUS; break;
384 case K_KPOINT: key = VTERM_KEY_KP_PERIOD; break;
385 case K_LEFT: key = VTERM_KEY_LEFT; break;
386 case K_PAGEDOWN: key = VTERM_KEY_PAGEDOWN; break;
387 case K_PAGEUP: key = VTERM_KEY_PAGEUP; break;
388 case K_RIGHT: key = VTERM_KEY_RIGHT; break;
389 case K_UP: key = VTERM_KEY_UP; break;
390 case TAB: key = VTERM_KEY_TAB; break;
391 }
392
393 /*
394 * Convert special keys to vterm keys:
395 * - Write keys to vterm: vterm_keyboard_key()
396 * - Write output to channel.
397 */
398 if (key != VTERM_KEY_NONE)
399 /* Special key, let vterm convert it. */
400 vterm_keyboard_key(vterm, key, mod);
401 else
402 /* Normal character, let vterm convert it. */
403 vterm_keyboard_unichar(vterm, c, mod);
404
405 /* Read back the converted escape sequence. */
406 len = vterm_output_read(vterm, buf, sizeof(buf));
407
408 /* TODO: if FAIL is returned, stop? */
409 channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN,
410 (char_u *)buf, len, NULL);
411 }
412 }
317 413
318 #endif /* FEAT_TERMINAL */ 414 #endif /* FEAT_TERMINAL */