Mercurial > vim
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 */ |