mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 11:15:14 -07:00
Revert "[WIP] "abstract_ui" fixes and improvements"
This commit is contained in:
parent
4c55c34efa
commit
d7e18b5c95
@ -45,7 +45,7 @@ function! s:Highlight_Matching_Pair()
|
|||||||
|
|
||||||
" Avoid that we remove the popup menu.
|
" Avoid that we remove the popup menu.
|
||||||
" Return when there are no colors (looks like the cursor jumps).
|
" Return when there are no colors (looks like the cursor jumps).
|
||||||
if pumvisible() || (&term != 'abstract_ui' && &t_Co < 8 && !has("gui_running"))
|
if pumvisible() || (&t_Co < 8 && !has("gui_running"))
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -2294,7 +2294,8 @@ static int pum_wanted(void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* The display looks bad on a B&W display. */
|
/* The display looks bad on a B&W display. */
|
||||||
if (!abstract_ui && t_colors < 8)
|
if (t_colors < 8
|
||||||
|
)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -14440,7 +14440,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv)
|
|||||||
if (modec != 't' && modec != 'c' && modec != 'g')
|
if (modec != 't' && modec != 'c' && modec != 'g')
|
||||||
modec = 0; /* replace invalid with current */
|
modec = 0; /* replace invalid with current */
|
||||||
} else {
|
} else {
|
||||||
if (abstract_ui || t_colors > 1)
|
if (t_colors > 1)
|
||||||
modec = 'c';
|
modec = 'c';
|
||||||
else
|
else
|
||||||
modec = 't';
|
modec = 't';
|
||||||
|
@ -71,7 +71,6 @@
|
|||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/ex_cmds_defs.h"
|
#include "nvim/ex_cmds_defs.h"
|
||||||
#include "nvim/mouse.h"
|
#include "nvim/mouse.h"
|
||||||
#include "nvim/msgpack_rpc/channel.h"
|
|
||||||
|
|
||||||
static int quitmore = 0;
|
static int quitmore = 0;
|
||||||
static int ex_pressedreturn = FALSE;
|
static int ex_pressedreturn = FALSE;
|
||||||
@ -5399,16 +5398,10 @@ static void ex_stop(exarg_T *eap)
|
|||||||
/*
|
/*
|
||||||
* Disallow suspending for "rvim".
|
* Disallow suspending for "rvim".
|
||||||
*/
|
*/
|
||||||
if (!check_restricted()) {
|
if (!check_restricted()
|
||||||
if (!eap->forceit) {
|
) {
|
||||||
|
if (!eap->forceit)
|
||||||
autowrite_all();
|
autowrite_all();
|
||||||
}
|
|
||||||
|
|
||||||
if (abstract_ui) {
|
|
||||||
channel_close(last_message_source);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
windgoto((int)Rows - 1, 0);
|
windgoto((int)Rows - 1, 0);
|
||||||
out_char('\n');
|
out_char('\n');
|
||||||
out_flush();
|
out_flush();
|
||||||
|
@ -1245,9 +1245,6 @@ EXTERN int curr_tmode INIT(= TMODE_COOK); /* contains current terminal mode */
|
|||||||
EXTERN bool embedded_mode INIT(= false);
|
EXTERN bool embedded_mode INIT(= false);
|
||||||
// Using the "abstract_ui" termcap
|
// Using the "abstract_ui" termcap
|
||||||
EXTERN bool abstract_ui INIT(= false);
|
EXTERN bool abstract_ui INIT(= false);
|
||||||
// Id of the last channel sent a message to nvim. Used to determine the target
|
|
||||||
// of channel-specific actions such as suspending
|
|
||||||
EXTERN uint64_t last_message_source INIT(= 0);
|
|
||||||
|
|
||||||
/// Used to track the status of external functions.
|
/// Used to track the status of external functions.
|
||||||
/// Currently only used for iconv().
|
/// Currently only used for iconv().
|
||||||
|
@ -281,7 +281,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
event_init();
|
event_init();
|
||||||
|
|
||||||
if (!abstract_ui) {
|
if (abstract_ui) {
|
||||||
|
t_colors = 256;
|
||||||
|
} else {
|
||||||
// Print a warning if stdout is not a terminal TODO(tarruda): Remove this
|
// Print a warning if stdout is not a terminal TODO(tarruda): Remove this
|
||||||
// check once the new terminal UI is implemented
|
// check once the new terminal UI is implemented
|
||||||
check_tty(¶ms);
|
check_tty(¶ms);
|
||||||
|
@ -45,7 +45,6 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
size_t pending_requests;
|
|
||||||
PMap(cstr_t) *subscribed_events;
|
PMap(cstr_t) *subscribed_events;
|
||||||
bool is_job, closed;
|
bool is_job, closed;
|
||||||
msgpack_unpacker *unpacker;
|
msgpack_unpacker *unpacker;
|
||||||
@ -84,6 +83,7 @@ static uint64_t next_id = 1;
|
|||||||
static PMap(uint64_t) *channels = NULL;
|
static PMap(uint64_t) *channels = NULL;
|
||||||
static PMap(cstr_t) *event_strings = NULL;
|
static PMap(cstr_t) *event_strings = NULL;
|
||||||
static msgpack_sbuffer out_buffer;
|
static msgpack_sbuffer out_buffer;
|
||||||
|
static size_t pending_requests = 0;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "msgpack_rpc/channel.c.generated.h"
|
# include "msgpack_rpc/channel.c.generated.h"
|
||||||
@ -103,7 +103,14 @@ void channel_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (abstract_ui) {
|
if (abstract_ui) {
|
||||||
|
// Add handler for "attach_ui"
|
||||||
remote_ui_init();
|
remote_ui_init();
|
||||||
|
String method = cstr_as_string("attach_ui");
|
||||||
|
MsgpackRpcRequestHandler handler = {.fn = remote_ui_attach, .defer = true};
|
||||||
|
msgpack_rpc_add_method_handler(method, handler);
|
||||||
|
method = cstr_as_string("detach_ui");
|
||||||
|
handler.fn = remote_ui_detach;
|
||||||
|
msgpack_rpc_add_method_handler(method, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,21 +200,20 @@ bool channel_send_event(uint64_t id, char *name, Array args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel) {
|
if (pending_requests) {
|
||||||
if (channel->pending_requests) {
|
DelayedNotification p = {
|
||||||
DelayedNotification p = {
|
.channel = channel,
|
||||||
.channel = channel,
|
.method = cstr_to_string(name),
|
||||||
.method = cstr_to_string(name),
|
.args = args
|
||||||
.args = args
|
};
|
||||||
};
|
// Pending request, queue the notification for sending later
|
||||||
// Pending request, queue the notification for sending later
|
*kl_pushp(DelayedNotification, delayed_notifications) = p;
|
||||||
*kl_pushp(DelayedNotification, delayed_notifications) = p;
|
} else {
|
||||||
} else {
|
if (channel) {
|
||||||
send_event(channel, name, args);
|
send_event(channel, name, args);
|
||||||
|
} else {
|
||||||
|
broadcast_event(name, args);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// TODO(tarruda): Implement event broadcasting in vimscript
|
|
||||||
broadcast_event(name, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -240,10 +246,10 @@ Object channel_send_call(uint64_t id,
|
|||||||
// Push the frame
|
// Push the frame
|
||||||
ChannelCallFrame frame = {request_id, false, false, NIL};
|
ChannelCallFrame frame = {request_id, false, false, NIL};
|
||||||
kv_push(ChannelCallFrame *, channel->call_stack, &frame);
|
kv_push(ChannelCallFrame *, channel->call_stack, &frame);
|
||||||
channel->pending_requests++;
|
pending_requests++;
|
||||||
event_poll_until(-1, frame.returned);
|
event_poll_until(-1, frame.returned);
|
||||||
(void)kv_pop(channel->call_stack);
|
(void)kv_pop(channel->call_stack);
|
||||||
channel->pending_requests--;
|
pending_requests--;
|
||||||
|
|
||||||
if (frame.errored) {
|
if (frame.errored) {
|
||||||
api_set_error(err, Exception, "%s", frame.result.data.string.data);
|
api_set_error(err, Exception, "%s", frame.result.data.string.data);
|
||||||
@ -255,7 +261,7 @@ Object channel_send_call(uint64_t id,
|
|||||||
free_channel(channel);
|
free_channel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->pending_requests) {
|
if (!pending_requests) {
|
||||||
send_delayed_notifications();
|
send_delayed_notifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +492,6 @@ static void on_request_event(Event event)
|
|||||||
{
|
{
|
||||||
RequestEvent *e = event.data;
|
RequestEvent *e = event.data;
|
||||||
Channel *channel = e->channel;
|
Channel *channel = e->channel;
|
||||||
last_message_source = channel->id;
|
|
||||||
MsgpackRpcRequestHandler handler = e->handler;
|
MsgpackRpcRequestHandler handler = e->handler;
|
||||||
Array args = e->args;
|
Array args = e->args;
|
||||||
uint64_t request_id = e->request_id;
|
uint64_t request_id = e->request_id;
|
||||||
@ -639,7 +644,6 @@ static void close_channel(Channel *channel)
|
|||||||
uv_handle_t *handle = (uv_handle_t *)channel->data.streams.uv;
|
uv_handle_t *handle = (uv_handle_t *)channel->data.streams.uv;
|
||||||
if (handle) {
|
if (handle) {
|
||||||
uv_close(handle, close_cb);
|
uv_close(handle, close_cb);
|
||||||
free_channel(channel);
|
|
||||||
} else {
|
} else {
|
||||||
event_push((Event) { .handler = on_stdio_close }, false);
|
event_push((Event) { .handler = on_stdio_close }, false);
|
||||||
}
|
}
|
||||||
@ -683,7 +687,6 @@ static Channel *register_channel(void)
|
|||||||
rv->closed = false;
|
rv->closed = false;
|
||||||
rv->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
|
rv->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
|
||||||
rv->id = next_id++;
|
rv->id = next_id++;
|
||||||
rv->pending_requests = 0;
|
|
||||||
rv->subscribed_events = pmap_new(cstr_t)();
|
rv->subscribed_events = pmap_new(cstr_t)();
|
||||||
rv->next_request_id = 1;
|
rv->next_request_id = 1;
|
||||||
kv_init(rv->call_stack);
|
kv_init(rv->call_stack);
|
||||||
|
@ -26,44 +26,18 @@ static PMap(uint64_t) *connected_uis = NULL;
|
|||||||
void remote_ui_init(void)
|
void remote_ui_init(void)
|
||||||
{
|
{
|
||||||
connected_uis = pmap_new(uint64_t)();
|
connected_uis = pmap_new(uint64_t)();
|
||||||
// Add handler for "attach_ui"
|
|
||||||
String method = cstr_as_string("ui_attach");
|
|
||||||
MsgpackRpcRequestHandler handler = {.fn = remote_ui_attach, .defer = false};
|
|
||||||
msgpack_rpc_add_method_handler(method, handler);
|
|
||||||
method = cstr_as_string("ui_detach");
|
|
||||||
handler.fn = remote_ui_detach;
|
|
||||||
msgpack_rpc_add_method_handler(method, handler);
|
|
||||||
method = cstr_as_string("ui_try_resize");
|
|
||||||
handler.fn = remote_ui_try_resize;
|
|
||||||
msgpack_rpc_add_method_handler(method, handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remote_ui_disconnect(uint64_t channel_id)
|
Object remote_ui_attach(uint64_t channel_id, uint64_t request_id, Array args,
|
||||||
{
|
Error *error)
|
||||||
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
|
|
||||||
if (!ui) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UIData *data = ui->data;
|
|
||||||
// destroy pending screen updates
|
|
||||||
api_free_array(data->buffer);
|
|
||||||
pmap_del(uint64_t)(connected_uis, channel_id);
|
|
||||||
free(ui->data);
|
|
||||||
ui_detach(ui);
|
|
||||||
free(ui);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
|
|
||||||
Array args, Error *error)
|
|
||||||
{
|
{
|
||||||
if (pmap_has(uint64_t)(connected_uis, channel_id)) {
|
if (pmap_has(uint64_t)(connected_uis, channel_id)) {
|
||||||
api_set_error(error, Exception, _("UI already attached for channel"));
|
api_set_error(error, Exception, _("UI already attached for channel"));
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.size != 3 || args.items[0].type != kObjectTypeInteger
|
if (args.size != 2 || args.items[0].type != kObjectTypeInteger
|
||||||
|| args.items[1].type != kObjectTypeInteger
|
|| args.items[1].type != kObjectTypeInteger
|
||||||
|| args.items[2].type != kObjectTypeBoolean
|
|
||||||
|| args.items[0].data.integer <= 0 || args.items[1].data.integer <= 0) {
|
|| args.items[0].data.integer <= 0 || args.items[1].data.integer <= 0) {
|
||||||
api_set_error(error, Validation,
|
api_set_error(error, Validation,
|
||||||
_("Arguments must be a pair of positive integers "
|
_("Arguments must be a pair of positive integers "
|
||||||
@ -76,7 +50,6 @@ static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
|
|||||||
UI *ui = xcalloc(1, sizeof(UI));
|
UI *ui = xcalloc(1, sizeof(UI));
|
||||||
ui->width = (int)args.items[0].data.integer;
|
ui->width = (int)args.items[0].data.integer;
|
||||||
ui->height = (int)args.items[1].data.integer;
|
ui->height = (int)args.items[1].data.integer;
|
||||||
ui->rgb = args.items[2].data.boolean;
|
|
||||||
ui->data = data;
|
ui->data = data;
|
||||||
ui->resize = remote_ui_resize;
|
ui->resize = remote_ui_resize;
|
||||||
ui->clear = remote_ui_clear;
|
ui->clear = remote_ui_clear;
|
||||||
@ -94,16 +67,16 @@ static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
|
|||||||
ui->put = remote_ui_put;
|
ui->put = remote_ui_put;
|
||||||
ui->bell = remote_ui_bell;
|
ui->bell = remote_ui_bell;
|
||||||
ui->visual_bell = remote_ui_visual_bell;
|
ui->visual_bell = remote_ui_visual_bell;
|
||||||
ui->update_fg = remote_ui_update_fg;
|
|
||||||
ui->update_bg = remote_ui_update_bg;
|
|
||||||
ui->flush = remote_ui_flush;
|
ui->flush = remote_ui_flush;
|
||||||
|
ui->suspend = remote_ui_suspend;
|
||||||
pmap_put(uint64_t)(connected_uis, channel_id, ui);
|
pmap_put(uint64_t)(connected_uis, channel_id, ui);
|
||||||
ui_attach(ui);
|
ui_attach(ui);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object remote_ui_detach(uint64_t channel_id, uint64_t request_id,
|
Object remote_ui_detach(uint64_t channel_id, uint64_t request_id, Array args,
|
||||||
Array args, Error *error)
|
Error *error)
|
||||||
{
|
{
|
||||||
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
|
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
|
||||||
api_set_error(error, Exception, _("UI is not attached for channel"));
|
api_set_error(error, Exception, _("UI is not attached for channel"));
|
||||||
@ -113,30 +86,21 @@ static Object remote_ui_detach(uint64_t channel_id, uint64_t request_id,
|
|||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object remote_ui_try_resize(uint64_t channel_id, uint64_t request_id,
|
void remote_ui_disconnect(uint64_t channel_id)
|
||||||
Array args, Error *error)
|
|
||||||
{
|
{
|
||||||
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
|
|
||||||
api_set_error(error, Exception, _("UI is not attached for channel"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.size != 2 || args.items[0].type != kObjectTypeInteger
|
|
||||||
|| args.items[1].type != kObjectTypeInteger
|
|
||||||
|| args.items[0].data.integer <= 0 || args.items[1].data.integer <= 0) {
|
|
||||||
api_set_error(error, Validation,
|
|
||||||
_("Arguments must be a pair of positive integers "
|
|
||||||
"representing the remote screen width/height"));
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
|
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
|
||||||
ui->width = (int)args.items[0].data.integer;
|
if (!ui) {
|
||||||
ui->height = (int)args.items[1].data.integer;
|
return;
|
||||||
ui_refresh();
|
}
|
||||||
return NIL;
|
UIData *data = ui->data;
|
||||||
|
// destroy pending screen updates
|
||||||
|
api_free_array(data->buffer);
|
||||||
|
pmap_del(uint64_t)(connected_uis, channel_id);
|
||||||
|
free(ui->data);
|
||||||
|
ui_detach(ui);
|
||||||
|
free(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void push_call(UI *ui, char *name, Array args)
|
static void push_call(UI *ui, char *name, Array args)
|
||||||
{
|
{
|
||||||
Array call = ARRAY_DICT_INIT;
|
Array call = ARRAY_DICT_INIT;
|
||||||
@ -250,6 +214,10 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
|
|||||||
PUT(hl, "bold", BOOLEAN_OBJ(true));
|
PUT(hl, "bold", BOOLEAN_OBJ(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attrs.standout) {
|
||||||
|
PUT(hl, "standout", BOOLEAN_OBJ(true));
|
||||||
|
}
|
||||||
|
|
||||||
if (attrs.underline) {
|
if (attrs.underline) {
|
||||||
PUT(hl, "underline", BOOLEAN_OBJ(true));
|
PUT(hl, "underline", BOOLEAN_OBJ(true));
|
||||||
}
|
}
|
||||||
@ -298,23 +266,15 @@ static void remote_ui_visual_bell(UI *ui)
|
|||||||
push_call(ui, "visual_bell", args);
|
push_call(ui, "visual_bell", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remote_ui_update_fg(UI *ui, int fg)
|
|
||||||
{
|
|
||||||
Array args = ARRAY_DICT_INIT;
|
|
||||||
ADD(args, INTEGER_OBJ(fg));
|
|
||||||
push_call(ui, "update_fg", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remote_ui_update_bg(UI *ui, int bg)
|
|
||||||
{
|
|
||||||
Array args = ARRAY_DICT_INIT;
|
|
||||||
ADD(args, INTEGER_OBJ(bg));
|
|
||||||
push_call(ui, "update_bg", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remote_ui_flush(UI *ui)
|
static void remote_ui_flush(UI *ui)
|
||||||
{
|
{
|
||||||
UIData *data = ui->data;
|
UIData *data = ui->data;
|
||||||
channel_send_event(data->channel_id, "redraw", data->buffer);
|
channel_send_event(data->channel_id, "redraw", data->buffer);
|
||||||
data->buffer = (Array)ARRAY_DICT_INIT;
|
data->buffer = (Array)ARRAY_DICT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remote_ui_suspend(UI *ui)
|
||||||
|
{
|
||||||
|
UIData *data = ui->data;
|
||||||
|
remote_ui_disconnect(data->channel_id);
|
||||||
|
}
|
||||||
|
@ -187,20 +187,14 @@ size_t input_enqueue(String keys)
|
|||||||
unsigned int new_size = trans_special((uint8_t **)&ptr, buf, false);
|
unsigned int new_size = trans_special((uint8_t **)&ptr, buf, false);
|
||||||
|
|
||||||
if (!new_size) {
|
if (!new_size) {
|
||||||
if (*ptr == '<') {
|
|
||||||
// Invalid key sequence, skip until the next '>' or until *end
|
|
||||||
do {
|
|
||||||
ptr++;
|
|
||||||
} while (ptr < end && *ptr != '>');
|
|
||||||
ptr++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// copy the character unmodified
|
// copy the character unmodified
|
||||||
*buf = (uint8_t)*ptr++;
|
*buf = (uint8_t)*ptr++;
|
||||||
new_size = 1;
|
new_size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_size = handle_mouse_event(&ptr, buf, new_size);
|
new_size = handle_mouse_event(&ptr, buf, new_size);
|
||||||
|
// TODO(tarruda): Don't produce past unclosed '<' characters, except if
|
||||||
|
// there's a lot of characters after the '<'
|
||||||
rbuffer_write(input_buffer, (char *)buf, new_size);
|
rbuffer_write(input_buffer, (char *)buf, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "nvim/option_defs.h"
|
#include "nvim/option_defs.h"
|
||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
|
#include "nvim/ui.h"
|
||||||
|
|
||||||
#define DYNAMIC_BUFFER_INIT {NULL, 0, 0}
|
#define DYNAMIC_BUFFER_INIT {NULL, 0, 0}
|
||||||
|
|
||||||
@ -413,7 +414,6 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
|
|||||||
|
|
||||||
char *start = output;
|
char *start = output;
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
int lastrow = (int)Rows - 1;
|
|
||||||
while (off < remaining) {
|
while (off < remaining) {
|
||||||
if (output[off] == NL) {
|
if (output[off] == NL) {
|
||||||
// Insert the line
|
// Insert the line
|
||||||
@ -421,8 +421,10 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
|
|||||||
if (to_buffer) {
|
if (to_buffer) {
|
||||||
ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false);
|
ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false);
|
||||||
} else {
|
} else {
|
||||||
screen_del_lines(0, 0, 1, (int)Rows, true, NULL);
|
// pending data from the output buffer has been flushed to the screen,
|
||||||
screen_puts_len((char_u *)output, (int)off, lastrow, 0, 0);
|
// safe to call ui_write directly
|
||||||
|
ui_write((char_u *)output, (int)off);
|
||||||
|
ui_write((char_u *)"\r\n", 2);
|
||||||
}
|
}
|
||||||
size_t skip = off + 1;
|
size_t skip = off + 1;
|
||||||
output += skip;
|
output += skip;
|
||||||
@ -446,8 +448,8 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
|
|||||||
// remember that the NL was missing
|
// remember that the NL was missing
|
||||||
curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
|
curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
|
||||||
} else {
|
} else {
|
||||||
screen_del_lines(0, 0, 1, (int)Rows, true, NULL);
|
ui_write((char_u *)output, (int)remaining);
|
||||||
screen_puts_len((char_u *)output, (int)remaining, lastrow, 0, 0);
|
ui_write((char_u *)"\r\n", 2);
|
||||||
}
|
}
|
||||||
output += remaining;
|
output += remaining;
|
||||||
} else if (to_buffer) {
|
} else if (to_buffer) {
|
||||||
|
@ -4548,7 +4548,7 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
|
|||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = fillchar_vsep(&hl);
|
c = fillchar_vsep(&hl);
|
||||||
if (ScreenLines[off_to] != ((schar_T)c)
|
if (ScreenLines[off_to] != c
|
||||||
|| (enc_utf8 && (int)ScreenLinesUC[off_to]
|
|| (enc_utf8 && (int)ScreenLinesUC[off_to]
|
||||||
!= (c >= 0x80 ? c : 0))
|
!= (c >= 0x80 ? c : 0))
|
||||||
|| ScreenAttrs[off_to] != hl) {
|
|| ScreenAttrs[off_to] != hl) {
|
||||||
@ -6150,7 +6150,8 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* it's a "normal" terminal when not in a GUI or cterm */
|
/* it's a "normal" terminal when not in a GUI or cterm */
|
||||||
norm_term = (!abstract_ui && t_colors <= 1);
|
norm_term = (
|
||||||
|
t_colors <= 1);
|
||||||
for (row = start_row; row < end_row; ++row) {
|
for (row = start_row; row < end_row; ++row) {
|
||||||
if (has_mbyte
|
if (has_mbyte
|
||||||
) {
|
) {
|
||||||
@ -6674,7 +6675,7 @@ static void linecopy(int to, int from, win_T *wp)
|
|||||||
*/
|
*/
|
||||||
int can_clear(char_u *p)
|
int can_clear(char_u *p)
|
||||||
{
|
{
|
||||||
return *p != NUL && ((!abstract_ui && t_colors <= 1)
|
return *p != NUL && (t_colors <= 1
|
||||||
|| cterm_normal_bg_color == 0 || *T_UT != NUL);
|
|| cterm_normal_bg_color == 0 || *T_UT != NUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7701,7 +7702,8 @@ static void draw_tabline(void)
|
|||||||
int attr_fill = hl_attr(HLF_TPF);
|
int attr_fill = hl_attr(HLF_TPF);
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int room;
|
int room;
|
||||||
int use_sep_chars = !abstract_ui && t_colors < 8;
|
int use_sep_chars = (t_colors < 8
|
||||||
|
);
|
||||||
|
|
||||||
redraw_tabline = FALSE;
|
redraw_tabline = FALSE;
|
||||||
|
|
||||||
@ -8186,9 +8188,6 @@ void screen_resize(int width, int height, int mustset)
|
|||||||
check_shellsize();
|
check_shellsize();
|
||||||
|
|
||||||
if (abstract_ui) {
|
if (abstract_ui) {
|
||||||
// Clear the output buffer to ensure UIs don't receive redraw command meant
|
|
||||||
// for invalid screen sizes.
|
|
||||||
out_buf_clear();
|
|
||||||
ui_resize(width, height);
|
ui_resize(width, height);
|
||||||
} else {
|
} else {
|
||||||
mch_set_shellsize();
|
mch_set_shellsize();
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/syntax_defs.h"
|
#include "nvim/syntax_defs.h"
|
||||||
#include "nvim/term.h"
|
#include "nvim/term.h"
|
||||||
#include "nvim/ui.h"
|
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
|
|
||||||
@ -5984,7 +5983,7 @@ init_highlight (
|
|||||||
* With 8 colors brown is equal to yellow, need to use black for Search fg
|
* With 8 colors brown is equal to yellow, need to use black for Search fg
|
||||||
* to avoid Statement highlighted text disappears.
|
* to avoid Statement highlighted text disappears.
|
||||||
* Clear the attributes, needed when changing the t_Co value. */
|
* Clear the attributes, needed when changing the t_Co value. */
|
||||||
if (abstract_ui || t_colors > 8)
|
if (t_colors > 8)
|
||||||
do_highlight(
|
do_highlight(
|
||||||
(char_u *)(*p_bg == 'l'
|
(char_u *)(*p_bg == 'l'
|
||||||
? "Visual cterm=NONE ctermbg=LightGrey"
|
? "Visual cterm=NONE ctermbg=LightGrey"
|
||||||
@ -6037,7 +6036,6 @@ int load_colors(char_u *name)
|
|||||||
apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf);
|
apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf);
|
||||||
|
|
||||||
recursive = FALSE;
|
recursive = FALSE;
|
||||||
ui_refresh();
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -6433,9 +6431,7 @@ do_highlight (
|
|||||||
/* Use the _16 table to check if its a valid color name. */
|
/* Use the _16 table to check if its a valid color name. */
|
||||||
color = color_numbers_16[i];
|
color = color_numbers_16[i];
|
||||||
if (color >= 0) {
|
if (color >= 0) {
|
||||||
if (abstract_ui) {
|
if (t_colors == 8) {
|
||||||
color = color_numbers_256[i];
|
|
||||||
} else if (t_colors == 8) {
|
|
||||||
/* t_Co is 8: use the 8 colors table */
|
/* t_Co is 8: use the 8 colors table */
|
||||||
#if defined(__QNXNTO__)
|
#if defined(__QNXNTO__)
|
||||||
color = color_numbers_8_qansi[i];
|
color = color_numbers_8_qansi[i];
|
||||||
@ -6452,7 +6448,8 @@ do_highlight (
|
|||||||
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
|
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
|
||||||
}
|
}
|
||||||
color &= 7; /* truncate to 8 colors */
|
color &= 7; /* truncate to 8 colors */
|
||||||
} else if (t_colors == 16 || t_colors == 88 || t_colors == 256) {
|
} else if (t_colors == 16 || t_colors == 88
|
||||||
|
|| t_colors == 256) {
|
||||||
/*
|
/*
|
||||||
* Guess: if the termcap entry ends in 'm', it is
|
* Guess: if the termcap entry ends in 'm', it is
|
||||||
* probably an xterm-like terminal. Use the changed
|
* probably an xterm-like terminal. Use the changed
|
||||||
@ -6499,7 +6496,7 @@ do_highlight (
|
|||||||
if (color >= 0) {
|
if (color >= 0) {
|
||||||
if (termcap_active)
|
if (termcap_active)
|
||||||
term_bg_color(color);
|
term_bg_color(color);
|
||||||
if (!abstract_ui && t_colors < 16)
|
if (t_colors < 16)
|
||||||
i = (color == 0 || color == 4);
|
i = (color == 0 || color == 4);
|
||||||
else
|
else
|
||||||
i = (color < 7 || color == 8);
|
i = (color < 7 || color == 8);
|
||||||
@ -6645,10 +6642,6 @@ do_highlight (
|
|||||||
if (is_normal_group) {
|
if (is_normal_group) {
|
||||||
HL_TABLE()[idx].sg_term_attr = 0;
|
HL_TABLE()[idx].sg_term_attr = 0;
|
||||||
HL_TABLE()[idx].sg_cterm_attr = 0;
|
HL_TABLE()[idx].sg_cterm_attr = 0;
|
||||||
if (abstract_ui) {
|
|
||||||
// If the normal group has changed, it is simpler to refresh every UI
|
|
||||||
ui_refresh();
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
set_hl_attr(idx);
|
set_hl_attr(idx);
|
||||||
HL_TABLE()[idx].sg_scriptID = current_SID;
|
HL_TABLE()[idx].sg_scriptID = current_SID;
|
||||||
@ -6877,7 +6870,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
|
|||||||
if (char_attr <= HL_ALL && prim_attr <= HL_ALL)
|
if (char_attr <= HL_ALL && prim_attr <= HL_ALL)
|
||||||
return char_attr | prim_attr;
|
return char_attr | prim_attr;
|
||||||
|
|
||||||
if (abstract_ui || t_colors > 1) {
|
if (t_colors > 1) {
|
||||||
if (char_attr > HL_ALL)
|
if (char_attr > HL_ALL)
|
||||||
char_aep = syn_cterm_attr2entry(char_attr);
|
char_aep = syn_cterm_attr2entry(char_attr);
|
||||||
if (char_aep != NULL)
|
if (char_aep != NULL)
|
||||||
@ -6941,7 +6934,7 @@ int syn_attr2attr(int attr)
|
|||||||
{
|
{
|
||||||
attrentry_T *aep;
|
attrentry_T *aep;
|
||||||
|
|
||||||
if (abstract_ui || t_colors > 1)
|
if (t_colors > 1)
|
||||||
aep = syn_cterm_attr2entry(attr);
|
aep = syn_cterm_attr2entry(attr);
|
||||||
else
|
else
|
||||||
aep = syn_term_attr2entry(attr);
|
aep = syn_term_attr2entry(attr);
|
||||||
@ -7211,10 +7204,9 @@ set_hl_attr (
|
|||||||
* For the color term mode: If there are other than "normal"
|
* For the color term mode: If there are other than "normal"
|
||||||
* highlighting attributes, need to allocate an attr number.
|
* highlighting attributes, need to allocate an attr number.
|
||||||
*/
|
*/
|
||||||
if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0
|
if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0)
|
||||||
&& sgp->sg_rgb_fg == -1 && sgp->sg_rgb_bg == -1) {
|
|
||||||
sgp->sg_cterm_attr = sgp->sg_cterm;
|
sgp->sg_cterm_attr = sgp->sg_cterm;
|
||||||
} else {
|
else {
|
||||||
at_en.ae_attr = abstract_ui ? sgp->sg_gui : sgp->sg_cterm;
|
at_en.ae_attr = abstract_ui ? sgp->sg_gui : sgp->sg_cterm;
|
||||||
at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
|
at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
|
||||||
at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
|
at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
|
||||||
@ -7369,7 +7361,7 @@ int syn_id2attr(int hl_id)
|
|||||||
hl_id = syn_get_final_id(hl_id);
|
hl_id = syn_get_final_id(hl_id);
|
||||||
sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */
|
sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */
|
||||||
|
|
||||||
if (abstract_ui || t_colors > 1)
|
if (t_colors > 1)
|
||||||
attr = sgp->sg_cterm_attr;
|
attr = sgp->sg_cterm_attr;
|
||||||
else
|
else
|
||||||
attr = sgp->sg_term_attr;
|
attr = sgp->sg_term_attr;
|
||||||
|
@ -170,7 +170,6 @@ static struct builtin_term builtin_termcaps[] =
|
|||||||
{(int)KS_DL, "\033|d"},
|
{(int)KS_DL, "\033|d"},
|
||||||
{(int)KS_CDL, "\033|%p1%dD"},
|
{(int)KS_CDL, "\033|%p1%dD"},
|
||||||
{(int)KS_CS, "\033|%p1%d;%p2%dR"},
|
{(int)KS_CS, "\033|%p1%d;%p2%dR"},
|
||||||
{(int)KS_CSV, "\033|%p1%d;%p2%dV"},
|
|
||||||
{(int)KS_CL, "\033|C"},
|
{(int)KS_CL, "\033|C"},
|
||||||
// attributes switched on with 'h', off with * 'H'
|
// attributes switched on with 'h', off with * 'H'
|
||||||
{(int)KS_ME, "\033|31H"}, // HL_ALL
|
{(int)KS_ME, "\033|31H"}, // HL_ALL
|
||||||
@ -1818,20 +1817,17 @@ void term_write(char_u *s, size_t len)
|
|||||||
static char_u out_buf[OUT_SIZE + 1];
|
static char_u out_buf[OUT_SIZE + 1];
|
||||||
static int out_pos = 0; /* number of chars in out_buf */
|
static int out_pos = 0; /* number of chars in out_buf */
|
||||||
|
|
||||||
// Clear the output buffer
|
|
||||||
void out_buf_clear(void)
|
|
||||||
{
|
|
||||||
out_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* out_flush(): flush the output buffer
|
* out_flush(): flush the output buffer
|
||||||
*/
|
*/
|
||||||
void out_flush(void)
|
void out_flush(void)
|
||||||
{
|
{
|
||||||
int len = out_pos;
|
if (out_pos != 0) {
|
||||||
out_pos = 0;
|
/* set out_pos to 0 before ui_write, to avoid recursiveness */
|
||||||
ui_write(out_buf, len);
|
int len = out_pos;
|
||||||
|
out_pos = 0;
|
||||||
|
ui_write(out_buf, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
120
src/nvim/ui.c
120
src/nvim/ui.c
@ -60,8 +60,11 @@ static struct {
|
|||||||
int top, bot, left, right;
|
int top, bot, left, right;
|
||||||
} sr;
|
} sr;
|
||||||
static int current_highlight_mask = 0;
|
static int current_highlight_mask = 0;
|
||||||
|
static HlAttrs current_attrs = {
|
||||||
|
false, false, false, false, false, false, -1, -1
|
||||||
|
};
|
||||||
static bool cursor_enabled = true;
|
static bool cursor_enabled = true;
|
||||||
static int height, width;
|
static int height = INT_MAX, width = INT_MAX;
|
||||||
|
|
||||||
// This set of macros allow us to use UI_CALL to invoke any function on
|
// This set of macros allow us to use UI_CALL to invoke any function on
|
||||||
// registered UI instances. The functions can have 0-5 arguments(configurable
|
// registered UI instances. The functions can have 0-5 arguments(configurable
|
||||||
@ -95,10 +98,6 @@ void ui_write(uint8_t *s, int len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!len) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char_u *tofree = NULL;
|
char_u *tofree = NULL;
|
||||||
|
|
||||||
if (output_conv.vc_type != CONV_NONE) {
|
if (output_conv.vc_type != CONV_NONE) {
|
||||||
@ -121,7 +120,9 @@ void ui_write(uint8_t *s, int len)
|
|||||||
*/
|
*/
|
||||||
void ui_suspend(void)
|
void ui_suspend(void)
|
||||||
{
|
{
|
||||||
if (!abstract_ui) {
|
if (abstract_ui) {
|
||||||
|
UI_CALL(suspend);
|
||||||
|
} else {
|
||||||
mch_suspend();
|
mch_suspend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,31 +165,8 @@ void ui_cursor_shape(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_refresh(void)
|
void ui_resize(int width, int height)
|
||||||
{
|
{
|
||||||
if (!ui_count) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int width = INT_MAX, height = INT_MAX;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ui_count; i++) {
|
|
||||||
UI *ui = uis[i];
|
|
||||||
width = ui->width < width ? ui->width : width;
|
|
||||||
height = ui->height < height ? ui->height : height;
|
|
||||||
}
|
|
||||||
|
|
||||||
screen_resize(width, height, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ui_resize(int new_width, int new_height)
|
|
||||||
{
|
|
||||||
width = new_width;
|
|
||||||
height = new_height;
|
|
||||||
|
|
||||||
UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1));
|
|
||||||
UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1));
|
|
||||||
|
|
||||||
sr.top = 0;
|
sr.top = 0;
|
||||||
sr.bot = height - 1;
|
sr.bot = height - 1;
|
||||||
sr.left = 0;
|
sr.left = 0;
|
||||||
@ -262,7 +240,7 @@ void ui_attach(UI *ui)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uis[ui_count++] = ui;
|
uis[ui_count++] = ui;
|
||||||
ui_refresh();
|
resized(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_detach(UI *ui)
|
void ui_detach(UI *ui)
|
||||||
@ -289,8 +267,17 @@ void ui_detach(UI *ui)
|
|||||||
|
|
||||||
ui_count--;
|
ui_count--;
|
||||||
|
|
||||||
|
if (ui->width == width || ui->height == height) {
|
||||||
|
// It is possible that the UI being detached had the smallest screen,
|
||||||
|
// so check for the new minimum dimensions
|
||||||
|
width = height = INT_MAX;
|
||||||
|
for (size_t i = 0; i < ui_count; i++) {
|
||||||
|
check_dimensions(uis[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ui_count) {
|
if (ui_count) {
|
||||||
ui_refresh();
|
screen_resize(width, height, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +295,8 @@ static void highlight_start(int mask)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_highlight_args(current_highlight_mask);
|
set_highlight_args(current_highlight_mask, ¤t_attrs);
|
||||||
|
UI_CALL(highlight_set, current_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void highlight_stop(int mask)
|
static void highlight_stop(int mask)
|
||||||
@ -321,12 +309,12 @@ static void highlight_stop(int mask)
|
|||||||
current_highlight_mask &= ~mask;
|
current_highlight_mask &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_highlight_args(current_highlight_mask);
|
set_highlight_args(current_highlight_mask, ¤t_attrs);
|
||||||
|
UI_CALL(highlight_set, current_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_highlight_args(int mask)
|
static void set_highlight_args(int mask, HlAttrs *attrs)
|
||||||
{
|
{
|
||||||
HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1 };
|
|
||||||
attrentry_T *aep = NULL;
|
attrentry_T *aep = NULL;
|
||||||
|
|
||||||
if (mask > HL_ALL) {
|
if (mask > HL_ALL) {
|
||||||
@ -334,40 +322,18 @@ static void set_highlight_args(int mask)
|
|||||||
mask = aep ? aep->ae_attr : 0;
|
mask = aep ? aep->ae_attr : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb_attrs.bold = mask & HL_BOLD;
|
attrs->bold = mask & HL_BOLD;
|
||||||
rgb_attrs.underline = mask & HL_UNDERLINE;
|
attrs->standout = mask & HL_STANDOUT;
|
||||||
rgb_attrs.undercurl = mask & HL_UNDERCURL;
|
attrs->underline = mask & HL_UNDERLINE;
|
||||||
rgb_attrs.italic = mask & HL_ITALIC;
|
attrs->undercurl = mask & HL_UNDERCURL;
|
||||||
rgb_attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT);
|
attrs->italic = mask & HL_ITALIC;
|
||||||
HlAttrs cterm_attrs = rgb_attrs;
|
attrs->reverse = mask & HL_INVERSE;
|
||||||
|
attrs->foreground = aep && aep->fg_color >= 0 ? aep->fg_color : normal_fg;
|
||||||
if (aep) {
|
attrs->background = aep && aep->bg_color >= 0 ? aep->bg_color : normal_bg;
|
||||||
if (aep->fg_color != normal_fg) {
|
|
||||||
rgb_attrs.foreground = aep->fg_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aep->bg_color != normal_bg) {
|
|
||||||
rgb_attrs.background = aep->bg_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cterm_normal_fg_color != aep->ae_u.cterm.fg_color) {
|
|
||||||
cterm_attrs.foreground = aep->ae_u.cterm.fg_color - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cterm_normal_bg_color != aep->ae_u.cterm.bg_color) {
|
|
||||||
cterm_attrs.background = aep->ae_u.cterm.bg_color - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_abstract_ui_codes(uint8_t *ptr, int len)
|
static void parse_abstract_ui_codes(uint8_t *ptr, int len)
|
||||||
{
|
{
|
||||||
if (!ui_count) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int arg1 = 0, arg2 = 0;
|
int arg1 = 0, arg2 = 0;
|
||||||
uint8_t *end = ptr + len, *p, c;
|
uint8_t *end = ptr + len, *p, c;
|
||||||
bool update_cursor = false;
|
bool update_cursor = false;
|
||||||
@ -478,9 +444,6 @@ static void parse_abstract_ui_codes(uint8_t *ptr, int len)
|
|||||||
UI_CALL(put, NULL, 0);
|
UI_CALL(put, NULL, 0);
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
if (col >= width) {
|
|
||||||
ui_linefeed();
|
|
||||||
}
|
|
||||||
p += clen;
|
p += clen;
|
||||||
}
|
}
|
||||||
ptr = p;
|
ptr = p;
|
||||||
@ -494,6 +457,25 @@ static void parse_abstract_ui_codes(uint8_t *ptr, int len)
|
|||||||
UI_CALL(flush);
|
UI_CALL(flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void resized(UI *ui)
|
||||||
|
{
|
||||||
|
check_dimensions(ui);
|
||||||
|
screen_resize(width, height, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_dimensions(UI *ui)
|
||||||
|
{
|
||||||
|
// The internal screen dimensions are always the minimum required to fit on
|
||||||
|
// all connected screens
|
||||||
|
if (ui->width < width) {
|
||||||
|
width = ui->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ui->height < height) {
|
||||||
|
height = ui->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ui_linefeed(void)
|
static void ui_linefeed(void)
|
||||||
{
|
{
|
||||||
int new_col = 0;
|
int new_col = 0;
|
||||||
|
@ -6,14 +6,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool bold, underline, undercurl, italic, reverse;
|
bool bold, standout, underline, undercurl, italic, reverse;
|
||||||
int foreground, background;
|
int foreground, background;
|
||||||
} HlAttrs;
|
} HlAttrs;
|
||||||
|
|
||||||
typedef struct ui_t UI;
|
typedef struct ui_t UI;
|
||||||
|
|
||||||
struct ui_t {
|
struct ui_t {
|
||||||
bool rgb;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
void *data;
|
void *data;
|
||||||
void (*resize)(UI *ui, int rows, int columns);
|
void (*resize)(UI *ui, int rows, int columns);
|
||||||
@ -33,8 +32,7 @@ struct ui_t {
|
|||||||
void (*bell)(UI *ui);
|
void (*bell)(UI *ui);
|
||||||
void (*visual_bell)(UI *ui);
|
void (*visual_bell)(UI *ui);
|
||||||
void (*flush)(UI *ui);
|
void (*flush)(UI *ui);
|
||||||
void (*update_fg)(UI *ui, int fg);
|
void (*suspend)(UI *ui);
|
||||||
void (*update_bg)(UI *ui, int bg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
@ -23,18 +23,18 @@ describe('visual block shift and tab characters', function()
|
|||||||
abcdefghijklmnopqrstuvwxyz]])
|
abcdefghijklmnopqrstuvwxyz]])
|
||||||
|
|
||||||
feed('gg')
|
feed('gg')
|
||||||
feed([[fe<C-v>4jR<esc>ugvr1:'<lt>,'>yank A<cr>]])
|
feed([[fe<C-v>4jR<esc>ugvr1:'<,'>yank A<cr>]])
|
||||||
execute('/^abcdefgh')
|
execute('/^abcdefgh')
|
||||||
feed('<C-v>4jI <esc>j<lt><lt>11|D')
|
feed('<C-v>4jI <esc>j<<11|D')
|
||||||
feed('j7|a <esc>')
|
feed('j7|a <esc>')
|
||||||
feed('j7|a <esc>')
|
feed('j7|a <esc>')
|
||||||
feed('j7|a <esc>4k13|<C-v>4j<lt>')
|
feed('j7|a <esc>4k13|<C-v>4j<')
|
||||||
execute('$-5,$yank A')
|
execute('$-5,$yank A')
|
||||||
execute([[$-4,$s/\s\+//g]])
|
execute([[$-4,$s/\s\+//g]])
|
||||||
feed('<C-v>4kI <esc>j<lt><lt>')
|
feed('<C-v>4kI <esc>j<<')
|
||||||
feed('j7|a <esc>')
|
feed('j7|a <esc>')
|
||||||
feed('j7|a <esc>')
|
feed('j7|a <esc>')
|
||||||
feed('j7|a <esc>4k13|<C-v>4j3<lt>')
|
feed('j7|a <esc>4k13|<C-v>4j3<')
|
||||||
execute('$-4,$yank A')
|
execute('$-4,$yank A')
|
||||||
|
|
||||||
-- Put @a and clean empty lines
|
-- Put @a and clean empty lines
|
||||||
|
@ -142,6 +142,7 @@ describe('Default highlight groups', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('end of file markers', function()
|
it('end of file markers', function()
|
||||||
|
nvim('command', 'hi Normal guibg=black')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
^ |
|
^ |
|
||||||
{1:~ }|
|
{1:~ }|
|
||||||
|
@ -99,6 +99,7 @@ function Screen.new(width, height)
|
|||||||
_mouse_enabled = true,
|
_mouse_enabled = true,
|
||||||
_bell = false,
|
_bell = false,
|
||||||
_visual_bell = false,
|
_visual_bell = false,
|
||||||
|
_suspended = true,
|
||||||
_attrs = {},
|
_attrs = {},
|
||||||
_cursor = {
|
_cursor = {
|
||||||
enabled = true, row = 1, col = 1
|
enabled = true, row = 1, col = 1
|
||||||
@ -114,11 +115,13 @@ function Screen:set_default_attr_ids(attr_ids)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Screen:attach()
|
function Screen:attach()
|
||||||
request('ui_attach', self._width, self._height, true)
|
request('attach_ui', self._width, self._height)
|
||||||
|
self._suspended = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen:detach()
|
function Screen:detach()
|
||||||
request('ui_detach')
|
request('detach_ui')
|
||||||
|
self._suspended = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen:expect(expected, attr_ids)
|
function Screen:expect(expected, attr_ids)
|
||||||
@ -187,7 +190,7 @@ end
|
|||||||
|
|
||||||
function Screen:_handle_eol_clear()
|
function Screen:_handle_eol_clear()
|
||||||
local row, col = self._cursor.row, self._cursor.col
|
local row, col = self._cursor.row, self._cursor.col
|
||||||
self:_clear_block(row, 1, col, self._scroll_region.right - col)
|
self:_clear_block(row, 1, col, self._width - col)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen:_handle_cursor_goto(row, col)
|
function Screen:_handle_cursor_goto(row, col)
|
||||||
@ -275,12 +278,8 @@ function Screen:_handle_visual_bell()
|
|||||||
self._visual_bell = true
|
self._visual_bell = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen:_handle_update_fg(fg)
|
function Screen:_handle_suspend()
|
||||||
self._fg = fg
|
self._suspended = true
|
||||||
end
|
|
||||||
|
|
||||||
function Screen:_handle_update_bg(bg)
|
|
||||||
self._bg = bg
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen:_clear_block(top, lines, left, columns)
|
function Screen:_clear_block(top, lines, left, columns)
|
||||||
|
Loading…
Reference in New Issue
Block a user