Commit Graph

43 Commits

Author SHA1 Message Date
Björn Linse
a1508c9f6d nvim__screenshot 2020-09-05 13:33:21 +02:00
Justin M. Keyes
44d45e29ea API/nvim_list_uis(): include "chan" field for TUI
Even though it's always zero currently, it's less confusing if all UIs
have the same fields.
2019-09-12 17:04:05 -07:00
Justin M. Keyes
6dd56d0902 UIAttach, UIDetach
doc: ginit.vim, gvimrc
fix #3656
2019-09-12 17:04:05 -07:00
Rui Abreu Ferreira
e9cf515888 UIAttach, UIDetach 2019-09-12 15:52:54 -07:00
Björn Linse
69bdc4f072 ui/compositor: add redraws needed due to intersected doublewidth chars. 2019-02-02 16:31:49 +01:00
Justin M. Keyes
7fdb45e0f8 preserve_exit: Ignore SIGHUP
closes #9274
ref #9028

If stdin closed then read_error_exit calls preserve_exit. Handling
SIGHUP during preserve_exit would cause a premature teardown, and
conflicts with e.g. ui_bridge_stop which waits for TUI to teardown.

Vim ignores SIGHUP in its prepare_to_exit and getout_preserve_modified
routines:

    /* Ignore SIGHUP, because a dropped connection causes a read error, which
     * makes Vim exit and then handling SIGHUP causes various reentrance
     * problems. */
    signal(SIGHUP, SIG_IGN);
2018-11-27 01:14:55 +01:00
Justin M. Keyes
a2d03d9b1a refactor: Rename get_term_attr_entry
Rename get_term_attr_entry to hl_get_term_attr, similar to
hl_get_syn_attr, hl_get_ui_attr.
2018-11-27 01:14:55 +01:00
Ricky Zhou
8fd3725cc8 tui: Hint wrapped lines to terminals.
Previously, when neovim would wrap a line across multiple lines,
terminal emulators could not detect that the lines represent a single
wrapped line as opposed to several separate lines. As a result, many
terminals' selection/copying functionality would treat a wrapped line as
several newline-delimited lines.

Fix this by reenabling a "special trick" from Vim. When a line is
wrapped, write the last character of that line followed by the first
character of the next line to the terminal. This hints to the terminal
that the next line is a continuation of the current line.

Extends the raw_line event with a "wrap" parameter which controls when
to do wrap hinting.
2018-09-03 03:25:02 -07:00
Björn Linse
1adb01c120 ui: use line-based rather than char-based updates in screen.c
Add ext_newgrid and ext_hlstate extensions. These use predefined
highlights and line-segment based updates, for efficiency and
simplicity.. The ext_hlstate extension in addition allows semantic
identification of builtin and syntax highlights.

Reimplement the old char-based updates in the remote UI layer, for
compatibility. For the moment, this is still the default. The bulitin
TUI uses the new line-based protocol.

cmdline uses curwin cursor position when ext_cmdline is active.
2018-07-21 13:21:58 +02:00
Björn Linse
b8331e1a1c tui: handle termguicolors rgb value in bridge for now
When/if TUI/bridge teardown is refactored to use events, this
commit can be reverted.
2018-06-02 17:44:48 +02:00
ZyX
43df2edd20 ui_bridge: Silence PVS/V547: assuming stopped may be changed via ptr 2018-04-22 20:21:55 +03:00
Björn Linse
8b05da1577 ui_bridge: make sure TUI receives no more UI events after "stop" event 2018-02-22 10:26:45 +01:00
Björn Linse
6e5cb0debd ui: refactor ui options 2018-02-13 20:48:51 +01:00
Björn Linse
5d8da126d0 ui/tui: highlighting refactor
Make HlAttr contain highlighting state for both color modes (cterm and rgb).
This allows us to implement termguicolors completely in the TUI.

Simplify some logic duplicated between ui.c and screen.c. Also avoid
some superfluous highlighting reset events.
2018-02-11 10:29:32 +01:00
Justin M. Keyes
c6fe06bbc0 tui: fix use-after-free after UI stop event #7922
ui_bridge:ui_bridge_stop() calls ui_detach_impl() last, so the check for
ui_active() in ui:ui_refresh() doesn't help: tui_main() already freed
the `ui` object.

There is a race between ui_bridge_stop (thread T0) and tui_main (thread T1).
UIBridgeData.stopped could be set while ui_bridge_stop() is in the
middle of loop_poll_events(), which may invoke tui_scheduler() on T0.
The pointers in tui_scheduler() may be invalid by then.

Solution(?): Use the `UI.data` field as a "stopped" flag and check it in
tui_scheduler().

ASAN use-after-free report observed in #7908:

    = ==20066==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000000cd0 at pc 0x00000182abed bp 0x7ffe23b07070 sp 0x7ffe23b07068
    = READ of size 8 at 0x611000000cd0 thread T0
    =     0 0x182abec in tui_scheduler /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:393:23
    =     1 0x1876afd in ui_bridge_update_fg /home/travis/build/neovim/neovim/build/src/nvim/auto/ui_events_bridge.generated.h:205:3
    =     2 0x186c130 in ui_resize /home/travis/build/neovim/neovim/src/nvim/ui.c:310:3
    =     3 0x146b9c2 in screen_resize /home/travis/build/neovim/neovim/src/nvim/screen.c:7483:3
    =     4 0x186a6f0 in ui_refresh /home/travis/build/neovim/neovim/src/nvim/ui.c:284:3
    =     5 0x186bbe0 in ui_refresh_event /home/travis/build/neovim/neovim/src/nvim/ui.c:297:3
    =     6 0xa2219a in multiqueue_process_events /home/travis/build/neovim/neovim/src/nvim/event/multiqueue.c:150:7
    =     7 0xa1bd7f in loop_poll_events /home/travis/build/neovim/neovim/src/nvim/event/loop.c:63:3
    =     8 0x1872709 in ui_bridge_stop /home/travis/build/neovim/neovim/src/nvim/ui_bridge.c:121:5
    =     9 0x1864247 in ui_builtin_stop /home/travis/build/neovim/neovim/src/nvim/ui.c:143:3
    =     10 0x1249ec8 in mch_exit /home/travis/build/neovim/neovim/src/nvim/os_unix.c:140:3
    =     11 0xe56ba9 in getout /home/travis/build/neovim/neovim/src/nvim/main.c:671:3
    =     12 0xfc4c8f in preserve_exit /home/travis/build/neovim/neovim/src/nvim/misc1.c:2653:3
    =     13 0x1247c02 in deadly_signal /home/travis/build/neovim/neovim/src/nvim/os/signal.c:137:3
    =     14 0x1247921 in on_signal /home/travis/build/neovim/neovim/src/nvim/os/signal.c:162:9
    =     15 0xa35618 in signal_event /home/travis/build/neovim/neovim/src/nvim/event/signal.c:47:3
    =     16 0xa2219a in multiqueue_process_events /home/travis/build/neovim/neovim/src/nvim/event/multiqueue.c:150:7
    =     17 0xa1bd7f in loop_poll_events /home/travis/build/neovim/neovim/src/nvim/event/loop.c:63:3
    =     18 0x1237bd6 in input_poll /home/travis/build/neovim/neovim/src/nvim/os/input.c:349:3
    =     19 0x123334f in inbuf_poll /home/travis/build/neovim/neovim/src/nvim/os/input.c:372:24
    =     20 0x123316d in os_inchar /home/travis/build/neovim/neovim/src/nvim/os/input.c:110:19
    =     21 0x170d20e in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:55:13
    =     22 0xbd7441 in command_line_enter /home/travis/build/neovim/neovim/src/nvim/ex_getln.c:384:3
    =     23 0xbd0a60 in getcmdline /home/travis/build/neovim/neovim/src/nvim/ex_getln.c:1920:10
    =     24 0xbdb365 in getexline /home/travis/build/neovim/neovim/src/nvim/ex_getln.c:2100:10
    =     25 0xb00a6b in do_cmdline /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:528:47
    =     26 0x10a7837 in nv_colon /home/travis/build/neovim/neovim/src/nvim/normal.c:4552:18
    =     27 0x1091e15 in normal_execute /home/travis/build/neovim/neovim/src/nvim/normal.c:1136:3
    =     28 0x170d439 in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:67:26
    =     29 0x104ee14 in normal_enter /home/travis/build/neovim/neovim/src/nvim/normal.c:466:3
    =     30 0xe4295c in main /home/travis/build/neovim/neovim/src/nvim/main.c:572:3
    =     31 0x2b2ba340bf44 in __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:287
    =     32 0x44d24b in _start (/home/travis/build/neovim/neovim/build/bin/nvim+0x44d24b)
    =
    = 0x611000000cd0 is located 16 bytes inside of 240-byte region [0x611000000cc0,0x611000000db0)
    = freed by thread T1 here:
    =     0 0x4ee0e2 in __interceptor_free /local/mnt/workspace/tmp/ubuntu_rel/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:47:3
    =     1 0xf4f6d4 in xfree /home/travis/build/neovim/neovim/src/nvim/memory.c:133:3
    =     2 0x182a963 in tui_main /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:383:3
    =     3 0x18792b0 in ui_thread_run /home/travis/build/neovim/neovim/src/nvim/ui_bridge.c:106:3
    =     4 0x2b2ba2697183 in start_thread /build/eglibc-ripdx6/eglibc-2.19/nptl/pthread_create.c:312
    =
    = previously allocated by thread T0 here:
    =     0 0x4ee61a in calloc /local/mnt/workspace/tmp/ubuntu_rel/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:76:3
    =     1 0xf4f787 in xcalloc /home/travis/build/neovim/neovim/src/nvim/memory.c:147:15
    =     2 0x182000a in tui_start /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:127:12
    =     3 0x1863f7c in ui_builtin_start /home/travis/build/neovim/neovim/src/nvim/ui.c:125:3
    =     4 0xe41bb9 in main /home/travis/build/neovim/neovim/src/nvim/main.c:457:5
    =     5 0x2b2ba340bf44 in __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:287
    =
    = Thread T1 created by T0 here:
    =     0 0x4d774d in __interceptor_pthread_create /local/mnt/workspace/tmp/ubuntu_rel/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:317:3
    =     1 0x1aae6b0 in uv_thread_create /home/travis/nvim-deps/build/src/libuv/src/unix/thread.c:75
    =     2 0x18217fa in tui_start /home/travis/build/neovim/neovim/src/nvim/tui/tui.c:159:10
    =     3 0x1863f7c in ui_builtin_start /home/travis/build/neovim/neovim/src/nvim/ui.c:125:3
    =     4 0xe41bb9 in main /home/travis/build/neovim/neovim/src/nvim/main.c:457:5
    =     5 0x2b2ba340bf44 in __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:287

---

Alternative attempt:

    commit 6ad9c02491606a0c31e907f38c9931f324327aa5
    Author: Justin M. Keyes <justinkz@gmail.com>
    Date:   Sat Jan 27 15:12:58 2018 +0100

        tui: fix use-after-free: swap in empty scheduler

        This should make life easier for UIs like VimR which implement their own
        in-process bridged UI: they don't need to worry that their `scheduler`
        might receive an invalid pointer.

        To avoid that, ui_bridge_stopped() swaps in an empty scheduler. Note
        that this requires the call to loop_poll_events() to be moved into the
        critical section.

    diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
    index 779585416f80..491052d19d3b 100644
    --- a/src/nvim/ui_bridge.c
    +++ b/src/nvim/ui_bridge.c
    @@ -93,10 +93,18 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
       return &rv->bridge;
     }

    +static void ui_bridge_null_scheduler(Event event, void *d)
    +{
    +  WLOG("ignoring event (bridge stopped)");
    +}
    +
     void ui_bridge_stopped(UIBridgeData *bridge)
     {
       uv_mutex_lock(&bridge->mutex);
       bridge->stopped = true;
    +  // Replace with an empty scheduler, so that the UI internal scheduler does
    +  // not get invoked with an invalid pointer. #7922
    +  bridge->scheduler = ui_bridge_null_scheduler;
       uv_mutex_unlock(&bridge->mutex);
     }

    @@ -111,14 +119,11 @@ static void ui_bridge_stop(UI *b)
       UIBridgeData *bridge = (UIBridgeData *)b;
       bool stopped = bridge->stopped = false;
       UI_BRIDGE_CALL(b, stop, 1, b);
    -  for (;;) {
    +  while (!stopped) {
         uv_mutex_lock(&bridge->mutex);
         stopped = bridge->stopped;
    -    uv_mutex_unlock(&bridge->mutex);
    -    if (stopped) {
    -      break;
    -    }
         loop_poll_events(&main_loop, 10);  // Process one event (at most).
    +    uv_mutex_unlock(&bridge->mutex);
       }
       uv_thread_join(&bridge->ui_thread);
       uv_mutex_destroy(&bridge->mutex);
2018-01-28 03:08:04 +01:00
Björn Linse
34057045be ui: forward relevant option updates to UIs (#7520)
also make termguicolors mutable after startup
2017-12-12 18:23:19 +01:00
Justin M. Keyes
3aa24042a8 tui: dump termcap info if -V3 ('verbose' >= 3)
Get terminal debugging info by starting Nvim with 'verbose' level 3:

    nvim -V3log

This is like Vim's `:set termcap`, which was removed in Nvim (and would
be very awkward to restore because of the decoupled UI).
2017-12-05 01:45:39 +01:00
Justin M. Keyes
13f5bc9586 log: all UI events, not just UI-bridge
Rename ui_bridge.c:UI_CALL to UI_BRIDGE_CALL.
2017-07-22 21:26:03 +02:00
Björn Linse
489d10c57c api: generate ui events 2017-05-10 16:14:10 +02:00
Justin M. Keyes
8f59d14839 event: Remove "priority" concept.
It was replaced by the "child queue" concept (MultiQueue).
2017-04-28 19:20:09 +02:00
Justin M. Keyes
00843902d3 api/ui: externalize tabline
- Work with a bool[] array parallel to the UIWidget enum.
- Rename some functions.
- Documentation.
2017-04-26 03:41:24 +02:00
Dongdong Zhou
88023d5123 api/ui: externalize tabline 2017-04-26 02:15:31 +02:00
Justin M. Keyes
10f119ab87 Merge #6539 'More cursor shape modes' 2017-04-21 19:09:50 +02:00
Björn Linse
7ea5c78687 ui: use an array for mode styles 2017-04-21 12:32:38 +02:00
Björn Linse
9cdbbd4982 ui: support more cursor shape modes
throttle unneccessary cursor shape events
2017-04-21 12:32:38 +02:00
ZyX
c2f3e361c5 *: Add comment to all C files 2017-04-19 19:11:50 +03:00
Justin M. Keyes
3ccd59ee82 'guicursor': enabled=false if 'guicursor' is empty
Closes #6429
Closes #6430
2017-04-04 14:19:26 +02:00
Matthieu Coudron
dd4a5fcbb6 tui: 'guicursor' shape #6044
Closes #2583
2017-04-01 23:14:05 +02:00
Justin M. Keyes
043f85210a tui: "backpressure": Drop messages to avoid flooding.
Closes #1234

multiqueue:
- Implement multiqueue_size()
- Rename MultiQueueItem.parent to MultiQueueItem.parent_item, to avoid confusion
  with MultiQueue.parent.
2016-12-09 18:51:17 +01:00
Justin M. Keyes
c9b9f052cc Revert "tui: Move ui_bridge module to tui/ namespace."
ui_bridge.c is useful for libnvim consumers, not just the built-in TUI.

This reverts commit beb2e4f095.
2016-10-13 16:05:06 +02:00
Justin M. Keyes
beb2e4f095 tui: Move ui_bridge module to tui/ namespace. 2016-09-28 03:29:54 +02:00
Justin M. Keyes
9c2f4ce20d doc: minor comment tweaks 2016-09-28 03:01:57 +02:00
Björn Linse
e968d72cae api/ui: use ui options instead of one method per feature
Use new nvim_ui_ prefix to avoid breaking change.
2016-08-29 10:17:31 +02:00
ZyX
739f066afe *: Also fix the adjacent errors 2016-06-11 00:08:58 +03:00
ZyX
d359bb3f60 *: Fix errors from new linter checks 2016-06-11 00:08:57 +03:00
ZyX
77540a0458 *: Rename main loop variable from loop to main_loop
Current name is inappropriate for the following reasons:

1. It is often masked by local `loop` variables.
2. It cannot be searched for. There are many `loop` variables where `loop` is
   some local variable. There are many cases when “loop” word is used in
   a comment.
3. It is in any case bad idea to use a generic name as a name of the global
   variable. Best if global has module prefix: this is why it is in `main.h`:
   `main_loop` both stands for “a main loop” and “a loop defined in `main.*`”.

Since I have no idea how to list every occurrence of this variable method used
to rename it is “remove it from globals.h, try to compile, fix errors”. Thus if
some occurrence was hidden under false `#if` branch it was not replaced.
2016-05-30 20:58:15 +03:00
Björn Linse
dd539366fc api: refactor remote ui to use API dispatch generation 2016-05-27 13:18:04 +02:00
AdnoC
244cfe86b5 syntax: Add support for the "special" color used for undercurls 2016-05-17 16:31:42 -04:00
Thiago de Arruda
0dac666098 ui_bridge: Fix race condition that results in deadlock.
Fixed by waiting until the UI thread finishes processing events. Close #3541.
2015-10-31 08:03:49 -03:00
Thiago de Arruda
1f90cbb4ae ugrid: Increase cell size to allow unicode composition
Close #3323
2015-09-18 14:35:26 -03:00
Thiago de Arruda
29b998be68 ui_bridge: Fix passing NULL pointer to memcpy 2015-09-18 14:35:26 -03:00
Björn Linse
fa5827b144 encoding: simplify handling of encoding in TUI 2015-09-08 10:53:44 +02:00
Thiago de Arruda
9f9710aab4 ui: Implement module for thread-safe communication with U
The ui_bridge.c module implements a surrogate UI that forwards calls to another
thread.
2015-09-06 09:18:53 -03:00