aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/ui.txt31
-rw-r--r--src/nvim/api/ui.c1
-rw-r--r--test/functional/ui/screen.lua21
3 files changed, 39 insertions, 14 deletions
diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt
index 0d4bdc7f41..a0f1b0770e 100644
--- a/runtime/doc/ui.txt
+++ b/runtime/doc/ui.txt
@@ -18,9 +18,9 @@ the grid ("externalized").
*ui-options*
-The |nvim_ui_attach()| API method is used to tell Nvim that your program wants to draw the
-Nvim screen grid with a size of width × height cells. This is typically done
-by an embedder, see |ui-startup| below for details, but an UI can also
+The |nvim_ui_attach()| API method is used to tell Nvim that your program wants to
+draw the Nvim screen grid with a size of width × height cells. This is typically
+done by an embedder, see |ui-startup| below for details, but an UI can also
connect to a running nvim instance and invoke this method. `options` must be
a dictionary with these (optional) keys:
`rgb` Decides the color format. *ui-rgb*
@@ -45,13 +45,17 @@ Nvim sends msgpack-rpc notifications to all attached UIs, with method name
Each update event is itself an array whose first element is the event name and
remaining elements are event-parameter tuples. This allows multiple events of
the same kind to be sent in a row without the event name being repeated. This
-batching is mostly used for "put", because each "put" event puts contents in
-one screen cell, but clients must be prepared for multiple argument sets being
-batched for all event kinds.
-
-Events must be handled in-order. The user should only see the updated screen
-state after all events in the same "redraw" batch are processed (not any
-intermediate state after processing only part of the array).
+batching is mostly used for "grid_line", because each "grid_line" event puts
+contents in one screen line, but clients must be prepared for multiple argument
+sets being batched for all event kinds.
+
+Events must be handled in-order. A "flush" event is sent when nvim is done
+redrawing the entire screen (so that all windows have a consistent view of
+buffer state, options etc). Clients should be prepared that several "redraw"
+batches are sent before the entire screen has been redrawn, and only the last
+batch will end in "flush". The user should only see the final state when
+"flush" is sent, and not any intermediate state after processing only part of
+the batch array, nor after a batch not ending with "flush".
By default, Nvim sends |ui-global| and |ui-grid-old| events; these suffice to
implement a terminal-like interface. However there are two revisions of the
@@ -81,7 +85,7 @@ to do early initialization. As soon as the UI invokes |nvim_ui_attach()|, the
startup will continue.
A simple UI only need to do a single |nvim_ui_attach()| request and then
-be prepared to handle any UI event. A more featureful UI, which might do
+be prepared to handle any UI event. A more featureful UI, which might need
additional configuration of the nvim process, should use the following startup
procedure:
@@ -199,6 +203,11 @@ the editor.
["visual_bell"]
Notify the user with an audible or visual bell, respectively.
+["flush"]
+ Nvim is done redrawing the screen. For an implementation that renders
+ to an internal buffer, this is the time to display the redrawn parts
+ to the user.
+
==============================================================================
Grid Events (line-based) *ui-linegrid*
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 9c16525a6b..01f8c9f71c 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -511,6 +511,7 @@ static void remote_ui_flush(UI *ui)
if (!ui->ui_ext[kUILinegrid]) {
remote_ui_cursor_goto(ui, data->cursor_row, data->cursor_col);
}
+ push_call(ui, "flush", (Array)ARRAY_DICT_INIT);
rpc_send_event(data->channel_id, "redraw", data->buffer);
data->buffer = (Array)ARRAY_DICT_INIT;
}
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 0b265d6867..691bf9f64c 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -386,9 +386,13 @@ function Screen:wait(check, timeout)
local err, checked = false
local success_seen = false
local failure_after_success = false
+ local did_flush = true
local function notification_cb(method, args)
assert(method == 'redraw')
- self:_redraw(args)
+ did_flush = self:_redraw(args)
+ if not did_flush then
+ return
+ end
err = check()
checked = true
if not err then
@@ -402,7 +406,9 @@ function Screen:wait(check, timeout)
return true
end
run(nil, notification_cb, nil, timeout or self.timeout)
- if not checked then
+ if not did_flush then
+ err = "no flush received"
+ elseif not checked then
err = check()
end
@@ -431,7 +437,8 @@ function Screen:sleep(ms)
end
function Screen:_redraw(updates)
- for _, update in ipairs(updates) do
+ local did_flush = false
+ for k, update in ipairs(updates) do
-- print('--')
-- print(require('inspect')(update))
local method = update[1]
@@ -446,7 +453,11 @@ function Screen:_redraw(updates)
self._on_event(method, update[i])
end
end
+ if k == #updates and method == "flush" then
+ did_flush = true
+ end
end
+ return did_flush
end
function Screen:set_on_event_handler(callback)
@@ -472,6 +483,10 @@ function Screen:_handle_resize(width, height)
}
end
+function Screen:_handle_flush()
+end
+
+
function Screen:_handle_grid_resize(grid, width, height)
assert(grid == 1)
self:_handle_resize(width, height)