diff options
Diffstat (limited to 'src')
39 files changed, 322 insertions, 244 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 58310a22a4..3a378ea360 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -602,7 +602,6 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count) { (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO, start, dir, count, eap->forceit); -#ifdef HAS_SWAP_EXISTS_ACTION buf_T *old_curbuf = curbuf; swap_exists_action = SEA_DIALOG; @@ -624,10 +623,8 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count) } else { handle_swap_exists(old_curbuf); } -#endif } -#if defined(HAS_SWAP_EXISTS_ACTION) || defined(PROTO) /* * Handle the situation of swap_exists_action being set. * It is allowed for "old_curbuf" to be NULL or invalid. @@ -678,7 +675,6 @@ void handle_swap_exists(buf_T *old_curbuf) } swap_exists_action = SEA_NONE; } -#endif /* * do_bufdel() - delete or unload buffer(s) @@ -2351,7 +2347,7 @@ int buflist_add(char_u *fname, int flags) return 0; } -#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) +#if defined(BACKSLASH_IN_FILENAME) /* * Adjust slashes in file names. Called after 'shellslash' was set. */ @@ -2752,7 +2748,7 @@ void resettitle(void) mch_settitle(lasttitle, lasticon); } -# if defined(EXITFREE) || defined(PROTO) +# if defined(EXITFREE) void free_titles(void) { free(lasttitle); @@ -3934,17 +3930,12 @@ void ex_buffer_all(exarg_T *eap) continue; /* Open the buffer in this window. */ -#if defined(HAS_SWAP_EXISTS_ACTION) swap_exists_action = SEA_DIALOG; -#endif set_curbuf(buf, DOBUF_GOTO); if (!buf_valid(buf)) { /* autocommands deleted the buffer!!! */ -#if defined(HAS_SWAP_EXISTS_ACTION) swap_exists_action = SEA_NONE; -# endif break; } -#if defined(HAS_SWAP_EXISTS_ACTION) if (swap_exists_action == SEA_QUIT) { cleanup_T cs; @@ -3964,7 +3955,6 @@ void ex_buffer_all(exarg_T *eap) leave_cleanup(&cs); } else handle_swap_exists(NULL); -#endif } os_breakcheck(); diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 7356d91ac2..b86c66c3fe 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1853,7 +1853,7 @@ int hex2nr(int c) return c - '0'; } -#if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) || defined(PROTO) +#if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) /// Convert two hex characters to a byte. /// Return -1 if one of the characters is not hex. @@ -1870,8 +1870,7 @@ int hexhex2nr(char_u *p) return (hex2nr(p[0]) << 4) + hex2nr(p[1]); } -#endif // if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) - // || defined(PROTO) +#endif // if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) /// Return true if "str" starts with a backslash that should be removed. /// For WIN32 this is only done when the character after the diff --git a/src/nvim/edit.c b/src/nvim/edit.c index e1a1fb18fa..4c00547daa 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -5800,7 +5800,7 @@ void set_last_insert(int c) last_insert_skip = 0; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_last_insert(void) { free(last_insert); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d60ce2de73..1833461fa9 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -76,6 +76,7 @@ #include "nvim/tag.h" #include "nvim/tempfile.h" #include "nvim/term.h" +#include "nvim/ui.h" #include "nvim/mouse.h" #include "nvim/undo.h" #include "nvim/version.h" @@ -499,7 +500,7 @@ void eval_init(void) job_event_pool = kmp_init(JobEventPool); } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void eval_clear(void) { struct vimvar *p; @@ -4847,7 +4848,6 @@ list_equal ( return item1 == NULL && item2 == NULL; } -#if defined(PROTO) /* * Return the dictitem that an entry in a hashtable points to. */ @@ -4855,12 +4855,6 @@ dictitem_T *dict_lookup(hashitem_T *hi) { return HI2DI(hi); } -#endif - -dictitem_T * dict_lookup(hashitem_T *hi) -{ - return HI2DI(hi); -} /* * Return TRUE when two dictionaries have exactly the same key/values. @@ -10023,6 +10017,8 @@ static void f_has(typval_T *argvars, typval_T *rettv) #endif } else if (STRICMP(name, "syntax_items") == 0) { n = syntax_present(curwin); + } else if (STRICMP(name, "gui_running") == 0) { + n = ui_rgb_attached(); } } @@ -14440,7 +14436,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv) if (modec != 't' && modec != 'c' && modec != 'g') modec = 0; /* replace invalid with current */ } else { - if (t_colors > 1) + if (abstract_ui || t_colors > 1) modec = 'c'; else modec = 't'; @@ -18047,7 +18043,7 @@ static ufunc_T *find_func(char_u *name) return NULL; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_all_functions(void) { hashitem_T *hi; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 03b45f9d49..763a2d6212 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -825,7 +825,7 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n) static char_u *prevcmd = NULL; /* the previous command */ -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_prev_shellcmd(void) { free(prevcmd); @@ -2978,9 +2978,7 @@ do_ecmd ( lnum = curwin->w_cursor.lnum; topline = curwin->w_topline; if (!oldbuf) { /* need to read the file */ -#if defined(HAS_SWAP_EXISTS_ACTION) swap_exists_action = SEA_DIALOG; -#endif curbuf->b_flags |= BF_CHECK_RO; /* set/reset 'ro' flag */ /* @@ -2989,11 +2987,9 @@ do_ecmd ( if (should_abort(open_buffer(FALSE, eap, readfile_flags))) retval = FAIL; -#if defined(HAS_SWAP_EXISTS_ACTION) if (swap_exists_action == SEA_QUIT) retval = FAIL; handle_swap_exists(old_curbuf); -#endif } else { /* Read the modelines, but only to set window-local options. Any * buffer-local options have already been set and may have been @@ -4609,7 +4605,7 @@ void write_viminfo_sub_string(FILE *fp) } } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_old_sub(void) { free(old_sub); @@ -6184,7 +6180,7 @@ char_u * sign_typenr2name(int typenr) return (char_u *)_("[Deleted]"); } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) /* * Undefine/free all signs. */ diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index c796cf6ac7..7de47cb296 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2546,7 +2546,7 @@ void ex_scriptnames(exarg_T *eap) } } -# if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) +# if defined(BACKSLASH_IN_FILENAME) /* * Fix slashes in the list of script names for 'shellslash'. */ @@ -2579,7 +2579,7 @@ char_u *get_scriptname(scid_T id) return SCRIPT_ITEM(id).sn_name; } -# if defined(EXITFREE) || defined(PROTO) +# if defined(EXITFREE) void free_scriptnames() { # define FREE_SCRIPTNAME(item) free((item)->sn_name) @@ -3204,7 +3204,7 @@ static char_u **find_locales(void) return (char_u **)locales_ga.ga_data; } -# if defined(EXITFREE) || defined(PROTO) +# if defined(EXITFREE) void free_locales(void) { int i; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3661a65b11..b4dfe99aed 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5530,7 +5530,7 @@ void alist_new(void) alist_init(curwin->w_alist); } -#if !defined(UNIX) || defined(PROTO) +#if !defined(UNIX) /* * Expand the file names in the global argument list. * If "fnum_list" is not NULL, use "fnum_list[fnum_len]" as a list of buffer @@ -5623,7 +5623,7 @@ alist_add ( ++al->al_ga.ga_len; } -#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) +#if defined(BACKSLASH_IN_FILENAME) /* * Adjust slashes in file names. Called after 'shellslash' was set. */ @@ -6256,7 +6256,7 @@ static void ex_read(exarg_T *eap) static char_u *prev_dir = NULL; -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_cd_dir(void) { free(prev_dir); diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 3ce8263457..b942f69f61 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1972,7 +1972,7 @@ static void realloc_cmdbuff(int len) static char_u *arshape_buf = NULL; -# if defined(EXITFREE) || defined(PROTO) +# if defined(EXITFREE) void free_cmdline_buf(void) { free(arshape_buf); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 58e67fa58c..370584b095 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -636,14 +636,12 @@ readfile ( #endif } -#if defined(HAS_SWAP_EXISTS_ACTION) /* If "Quit" selected at ATTENTION dialog, don't load the file */ if (swap_exists_action == SEA_QUIT) { if (!read_buffer && !read_stdin) close(fd); return FAIL; } -#endif ++no_wait_return; /* don't wait for return yet */ @@ -5149,7 +5147,7 @@ void write_lnum_adjust(linenr_T offset) curbuf->b_no_eol_lnum += offset; } -#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) +#if defined(BACKSLASH_IN_FILENAME) /* * Convert all backslashes in fname to forward slashes in-place. */ @@ -5547,7 +5545,7 @@ void do_augroup(char_u *arg, int del_group) } } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_all_autocmds(void) { for (current_augroup = -1; current_augroup < augroups.ga_len; @@ -7454,7 +7452,7 @@ file_pat_to_reg_pat ( return reg_pat; } -#if defined(EINTR) || defined(PROTO) +#if defined(EINTR) /* * Version of read() that retries when interrupted by EINTR (possibly * by a SIGWINCH). diff --git a/src/nvim/garray.c b/src/nvim/garray.c index c4f8f66bfe..c3a3426e87 100644 --- a/src/nvim/garray.c +++ b/src/nvim/garray.c @@ -199,7 +199,7 @@ void ga_append(garray_T *gap, char c) GA_APPEND(char, gap, c); } -#if defined(UNIX) || defined(WIN3264) || defined(PROTO) +#if defined(UNIX) || defined(WIN3264) /// Append the text in "gap" below the cursor line and clear "gap". /// diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index e12601e4c9..d97c983133 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1307,7 +1307,7 @@ static void closescript(void) --curscript; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void close_all_scripts(void) { while (scriptin[0] != NULL) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 11a7e9ecac..73bcdea226 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -859,7 +859,6 @@ EXTERN int cmd_silent INIT(= FALSE); /* don't echo the command line */ #define SEA_QUIT 2 /* quit editing the file */ #define SEA_RECOVER 3 /* recover the file */ -#define HAS_SWAP_EXISTS_ACTION EXTERN int swap_exists_action INIT(= SEA_NONE); /* For dialog when swap file already * exists. */ diff --git a/src/nvim/main.c b/src/nvim/main.c index f063cc1238..05b9778102 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -261,10 +261,7 @@ int main(int argc, char **argv) if (params.want_full_screen && !silent_mode) { if (embedded_mode) { - // In embedded mode don't do terminal-related initializations, assume an - // initial screen size of 80x20 - full_screen = true; - screen_resize(80, 20, false); + // embedded mode implies abstract_ui termcapinit((uint8_t *)"abstract_ui"); } else { // set terminal name and get terminal capabilities (will set full_screen) @@ -278,7 +275,9 @@ int main(int argc, char **argv) event_init(); if (abstract_ui) { + full_screen = true; t_colors = 256; + T_CCO = (uint8_t *)"256"; } else { // Print a warning if stdout is not a terminal TODO(tarruda): Remove this // check once the new terminal UI is implemented @@ -1560,19 +1559,15 @@ static void handle_quickfix(mparm_T *paramp) static void handle_tag(char_u *tagname) { if (tagname != NULL) { -#if defined(HAS_SWAP_EXISTS_ACTION) swap_exists_did_quit = FALSE; -#endif vim_snprintf((char *)IObuff, IOSIZE, "ta %s", tagname); do_cmdline_cmd(IObuff); TIME_MSG("jumping to tag"); -#if defined(HAS_SWAP_EXISTS_ACTION) /* If the user doesn't want to edit the file then we quit here. */ if (swap_exists_did_quit) getout(1); -#endif } } @@ -1607,10 +1602,8 @@ static void read_stdin(void) { int i; -#if defined(HAS_SWAP_EXISTS_ACTION) /* When getting the ATTENTION prompt here, use a dialog */ swap_exists_action = SEA_DIALOG; -#endif no_wait_return = TRUE; i = msg_didany; set_buflisted(TRUE); @@ -1618,9 +1611,7 @@ static void read_stdin(void) no_wait_return = FALSE; msg_didany = i; TIME_MSG("reading stdin"); -#if defined(HAS_SWAP_EXISTS_ACTION) check_swap_exists_action(); -#endif /* * Close stdin and dup it from stderr. Required for GPM to work * properly, and for running external commands. @@ -1702,16 +1693,13 @@ static void create_windows(mparm_T *parmp) /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */ if (p_fdls >= 0) curwin->w_p_fdl = p_fdls; -#if defined(HAS_SWAP_EXISTS_ACTION) /* When getting the ATTENTION prompt here, use a dialog */ swap_exists_action = SEA_DIALOG; -#endif set_buflisted(TRUE); /* create memfile, read file */ (void)open_buffer(FALSE, NULL, 0); -#if defined(HAS_SWAP_EXISTS_ACTION) if (swap_exists_action == SEA_QUIT) { if (got_int || only_one_window()) { /* abort selected or quit and only one window */ @@ -1726,7 +1714,6 @@ static void create_windows(mparm_T *parmp) swap_exists_action = SEA_NONE; } else handle_swap_exists(NULL); -#endif dorewind = TRUE; /* start again */ } os_breakcheck(); @@ -1797,13 +1784,10 @@ static void edit_buffers(mparm_T *parmp) curwin->w_arg_idx = arg_idx; /* Edit file from arg list, if there is one. When "Quit" selected * at the ATTENTION prompt close the window. */ -# ifdef HAS_SWAP_EXISTS_ACTION swap_exists_did_quit = FALSE; -# endif (void)do_ecmd(0, arg_idx < GARGCOUNT ? alist_name(&GARGLIST[arg_idx]) : NULL, NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin); -# ifdef HAS_SWAP_EXISTS_ACTION if (swap_exists_did_quit) { /* abort or quit selected */ if (got_int || only_one_window()) { @@ -1814,7 +1798,6 @@ static void edit_buffers(mparm_T *parmp) win_close(curwin, TRUE); advance = FALSE; } -# endif if (arg_idx == GARGCOUNT - 1) arg_had_last = TRUE; ++arg_idx; @@ -2215,7 +2198,6 @@ static void usage(void) mch_exit(0); } -#if defined(HAS_SWAP_EXISTS_ACTION) /* * Check the result of the ATTENTION dialog: * When "Quit" selected, exit Vim. @@ -2228,5 +2210,4 @@ static void check_swap_exists_action(void) handle_swap_exists(NULL); } -#endif diff --git a/src/nvim/mark.c b/src/nvim/mark.c index cf11be665a..cfc702f189 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1180,7 +1180,7 @@ void set_last_cursor(win_T *win) win->w_buffer->b_last_cursor = win->w_cursor; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_all_marks(void) { int i; diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 3274c8d8ec..bc8f768724 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -106,8 +106,6 @@ #include "nvim/os/os.h" #include "nvim/arabic.h" -#define WINBYTE BYTE - typedef struct { int rangeStart; int rangeEnd; @@ -365,10 +363,6 @@ enc_alias_table[] = {NULL, 0} }; -#ifndef CP_UTF8 -# define CP_UTF8 65001 /* magic number from winnls.h */ -#endif - /* * Find encoding "name" in the list of canonical encoding names. * Returns -1 if not found. @@ -3452,7 +3446,7 @@ char_u * enc_locale(void) return enc_canonize((char_u *)buf); } -# if defined(USE_ICONV) || defined(PROTO) +# if defined(USE_ICONV) /* @@ -3591,7 +3585,7 @@ static char_u * iconv_string(vimconv_T *vcp, char_u *str, int slen, int *unconvl return result; } -# if defined(DYNAMIC_ICONV) || defined(PROTO) +# if defined(DYNAMIC_ICONV) /* * Dynamically load the "iconv.dll" on Win32. */ diff --git a/src/nvim/memline.c b/src/nvim/memline.c index f6246c8b57..1fa6d6acc6 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -3000,7 +3000,7 @@ static void ml_lineadd(buf_T *buf, int count) } } -#if defined(HAVE_READLINK) || defined(PROTO) +#if defined(HAVE_READLINK) /* * Resolve a symlink in the last component of a file name. * Note that f_resolve() does it for every part of the path, we don't do that @@ -3367,9 +3367,7 @@ findswapname ( * for the current file, and the buffer was not recovered. */ if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED) && vim_strchr(p_shm, SHM_ATTENTION) == NULL) { -#if defined(HAS_SWAP_EXISTS_ACTION) int choice = 0; -#endif #ifdef UNIX process_still_running = FALSE; @@ -3427,7 +3425,6 @@ findswapname ( redraw_all_later(NOT_VALID); } -#if defined(HAS_SWAP_EXISTS_ACTION) if (choice > 0) { switch (choice) { case 1: @@ -3454,7 +3451,6 @@ findswapname ( if (!os_file_exists(fname)) break; } else -#endif { MSG_PUTS("\n"); if (msg_silent == 0) diff --git a/src/nvim/memory.c b/src/nvim/memory.c index f38dfd56ac..a2274a25fe 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -440,7 +440,7 @@ void do_outofmem_msg(size_t size) } } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) #include "nvim/file_search.h" #include "nvim/buffer.h" diff --git a/src/nvim/menu.c b/src/nvim/menu.c index ea15fd68e3..9c1ca71477 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -1359,7 +1359,7 @@ void ex_emenu(exarg_T *eap) #if defined(FEAT_GUI_MSWIN) \ || defined(FEAT_GUI_GTK) \ - || defined(FEAT_BEVAL_TIP) || defined(PROTO) + || defined(FEAT_BEVAL_TIP) /* * Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy. */ diff --git a/src/nvim/message.c b/src/nvim/message.c index 46e0a1a0df..9cd3814826 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -10,8 +10,6 @@ * message.c: functions for displaying messages on the command line */ -#define MESSAGE_FILE /* don't include prototype for smsg() */ - #include <assert.h> #include <errno.h> #include <inttypes.h> diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index c0d2e254ac..f756201efb 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2662,7 +2662,7 @@ void init_homedir(void) } } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_homedir(void) { free(homedir); diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 4c35cce09a..c8f8252e6d 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -45,6 +45,7 @@ typedef struct { typedef struct { uint64_t id; + size_t pending_requests; PMap(cstr_t) *subscribed_events; bool is_job, closed; msgpack_unpacker *unpacker; @@ -83,7 +84,6 @@ static uint64_t next_id = 1; static PMap(uint64_t) *channels = NULL; static PMap(cstr_t) *event_strings = NULL; static msgpack_sbuffer out_buffer; -static size_t pending_requests = 0; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "msgpack_rpc/channel.c.generated.h" @@ -103,14 +103,7 @@ void channel_init(void) } if (abstract_ui) { - // Add handler for "attach_ui" 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); } } @@ -200,20 +193,21 @@ bool channel_send_event(uint64_t id, char *name, Array args) return false; } - if (pending_requests) { - DelayedNotification p = { - .channel = channel, - .method = cstr_to_string(name), - .args = args - }; - // Pending request, queue the notification for sending later - *kl_pushp(DelayedNotification, delayed_notifications) = p; - } else { - if (channel) { - send_event(channel, name, args); + if (channel) { + if (channel->pending_requests) { + DelayedNotification p = { + .channel = channel, + .method = cstr_to_string(name), + .args = args + }; + // Pending request, queue the notification for sending later + *kl_pushp(DelayedNotification, delayed_notifications) = p; } else { - broadcast_event(name, args); + send_event(channel, name, args); } + } else { + // TODO(tarruda): Implement event broadcasting in vimscript + broadcast_event(name, args); } return true; @@ -246,10 +240,10 @@ Object channel_send_call(uint64_t id, // Push the frame ChannelCallFrame frame = {request_id, false, false, NIL}; kv_push(ChannelCallFrame *, channel->call_stack, &frame); - pending_requests++; + channel->pending_requests++; event_poll_until(-1, frame.returned); (void)kv_pop(channel->call_stack); - pending_requests--; + channel->pending_requests--; if (frame.errored) { api_set_error(err, Exception, "%s", frame.result.data.string.data); @@ -261,7 +255,7 @@ Object channel_send_call(uint64_t id, free_channel(channel); } - if (!pending_requests) { + if (!channel->pending_requests) { send_delayed_notifications(); } @@ -644,6 +638,7 @@ static void close_channel(Channel *channel) uv_handle_t *handle = (uv_handle_t *)channel->data.streams.uv; if (handle) { uv_close(handle, close_cb); + free_channel(channel); } else { event_push((Event) { .handler = on_stdio_close }, false); } @@ -687,6 +682,7 @@ static Channel *register_channel(void) rv->closed = false; rv->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE); rv->id = next_id++; + rv->pending_requests = 0; rv->subscribed_events = pmap_new(cstr_t)(); rv->next_request_id = 1; kv_init(rv->call_stack); diff --git a/src/nvim/msgpack_rpc/remote_ui.c b/src/nvim/msgpack_rpc/remote_ui.c index f980a77b4c..361e93a6da 100644 --- a/src/nvim/msgpack_rpc/remote_ui.c +++ b/src/nvim/msgpack_rpc/remote_ui.c @@ -26,18 +26,44 @@ static PMap(uint64_t) *connected_uis = NULL; void remote_ui_init(void) { 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); } -Object remote_ui_attach(uint64_t channel_id, uint64_t request_id, Array args, - Error *error) +void remote_ui_disconnect(uint64_t channel_id) +{ + 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)) { api_set_error(error, Exception, _("UI already attached for channel")); return NIL; } - if (args.size != 2 || args.items[0].type != kObjectTypeInteger + if (args.size != 3 || args.items[0].type != kObjectTypeInteger || args.items[1].type != kObjectTypeInteger + || args.items[2].type != kObjectTypeBoolean || 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 " @@ -50,6 +76,7 @@ Object remote_ui_attach(uint64_t channel_id, uint64_t request_id, Array args, UI *ui = xcalloc(1, sizeof(UI)); ui->width = (int)args.items[0].data.integer; ui->height = (int)args.items[1].data.integer; + ui->rgb = args.items[2].data.boolean; ui->data = data; ui->resize = remote_ui_resize; ui->clear = remote_ui_clear; @@ -67,16 +94,19 @@ Object remote_ui_attach(uint64_t channel_id, uint64_t request_id, Array args, ui->put = remote_ui_put; ui->bell = remote_ui_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->suspend = remote_ui_suspend; + ui->set_title = remote_ui_set_title; + ui->set_icon = remote_ui_set_icon; pmap_put(uint64_t)(connected_uis, channel_id, ui); ui_attach(ui); - return NIL; } -Object remote_ui_detach(uint64_t channel_id, uint64_t request_id, Array args, - Error *error) +static Object remote_ui_detach(uint64_t channel_id, uint64_t request_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")); @@ -86,21 +116,30 @@ Object remote_ui_detach(uint64_t channel_id, uint64_t request_id, Array args, return NIL; } -void remote_ui_disconnect(uint64_t channel_id) +static Object remote_ui_try_resize(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; + if (!pmap_has(uint64_t)(connected_uis, channel_id)) { + api_set_error(error, Exception, _("UI is not attached for channel")); } - 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); + + 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->width = (int)args.items[0].data.integer; + ui->height = (int)args.items[1].data.integer; + ui_refresh(); + return NIL; } + static void push_call(UI *ui, char *name, Array args) { Array call = ARRAY_DICT_INIT; @@ -214,10 +253,6 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) PUT(hl, "bold", BOOLEAN_OBJ(true)); } - if (attrs.standout) { - PUT(hl, "standout", BOOLEAN_OBJ(true)); - } - if (attrs.underline) { PUT(hl, "underline", BOOLEAN_OBJ(true)); } @@ -266,6 +301,20 @@ static void remote_ui_visual_bell(UI *ui) 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) { UIData *data = ui->data; @@ -275,6 +324,20 @@ static void remote_ui_flush(UI *ui) static void remote_ui_suspend(UI *ui) { - UIData *data = ui->data; - remote_ui_disconnect(data->channel_id); + Array args = ARRAY_DICT_INIT; + push_call(ui, "suspend", args); +} + +static void remote_ui_set_title(UI *ui, char *title) +{ + Array args = ARRAY_DICT_INIT; + ADD(args, STRING_OBJ(cstr_to_string(title))); + push_call(ui, "set_title", args); +} + +static void remote_ui_set_icon(UI *ui, char *icon) +{ + Array args = ARRAY_DICT_INIT; + ADD(args, STRING_OBJ(cstr_to_string(icon))); + push_call(ui, "set_icon", args); } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 87a2c2ca05..8fb3ba7f08 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2293,7 +2293,7 @@ void init_yank(void) y_regs[i].y_array = NULL; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void clear_registers(void) { int i; diff --git a/src/nvim/option.c b/src/nvim/option.c index 6c774937cd..88108b14a2 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2237,7 +2237,7 @@ void set_number_default(char *name, long val) options[opt_idx].def_val[VI_DEFAULT] = (char_u *)val; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) /* * Free all options. */ diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index c0d588f4ef..2ae4558f3d 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -187,14 +187,20 @@ size_t input_enqueue(String keys) unsigned int new_size = trans_special((uint8_t **)&ptr, buf, false); 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 *buf = (uint8_t)*ptr++; new_size = 1; } 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); } @@ -217,7 +223,8 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, mouse_code = buf[5]; } - if (mouse_code < KE_LEFTMOUSE || mouse_code > KE_RIGHTRELEASE) { + if (!((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE) + || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { return bufsize; } @@ -226,7 +233,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, // find mouse coordinates, and it would be too expensive to refactor this // now. int col, row, advance; - if (sscanf(*ptr, "<%d,%d>%n", &col, &row, &advance)) { + if (sscanf(*ptr, "<%d,%d>%n", &col, &row, &advance) != EOF && advance) { if (col >= 0 && row >= 0) { mouse_row = row; mouse_col = col; diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index d0f8442768..d481d6af56 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -24,7 +24,6 @@ #include "nvim/option_defs.h" #include "nvim/charset.h" #include "nvim/strings.h" -#include "nvim/ui.h" #define DYNAMIC_BUFFER_INIT {NULL, 0, 0} @@ -414,6 +413,7 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer, char *start = output; size_t off = 0; + int lastrow = (int)Rows - 1; while (off < remaining) { if (output[off] == NL) { // Insert the line @@ -421,10 +421,8 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer, if (to_buffer) { ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false); } else { - // pending data from the output buffer has been flushed to the screen, - // safe to call ui_write directly - ui_write((char_u *)output, (int)off); - ui_write((char_u *)"\r\n", 2); + screen_del_lines(0, 0, 1, (int)Rows, true, NULL); + screen_puts_len((char_u *)output, (int)off, lastrow, 0, 0); } size_t skip = off + 1; output += skip; @@ -448,8 +446,8 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer, // remember that the NL was missing curbuf->b_no_eol_lnum = curwin->w_cursor.lnum; } else { - ui_write((char_u *)output, (int)remaining); - ui_write((char_u *)"\r\n", 2); + screen_del_lines(0, 0, 1, (int)Rows, true, NULL); + screen_puts_len((char_u *)output, (int)remaining, lastrow, 0, 0); } output += remaining; } else if (to_buffer) { diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 7ec4059bce..f7b47f9569 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -43,6 +43,7 @@ #include "nvim/syntax.h" #include "nvim/tempfile.h" #include "nvim/term.h" +#include "nvim/ui.h" #include "nvim/types.h" #include "nvim/os/os.h" #include "nvim/os/time.h" @@ -181,22 +182,26 @@ void mch_settitle(char_u *title, char_u *icon) * Note: if "t_ts" is set, title is set with escape sequence rather * than x11 calls, because the x11 calls don't always work */ - if ((type || *T_TS != NUL) && title != NULL) { + if ((type || *T_TS != NUL || abstract_ui) && title != NULL) { if (oldtitle == NULL ) /* first call but not in GUI, save title */ (void)get_x11_title(FALSE); - if (*T_TS != NUL) /* it's OK if t_fs is empty */ + if (abstract_ui) { + ui_set_title((char *)title); + } else if (*T_TS != NUL) /* it's OK if t_fs is empty */ term_settitle(title); did_set_title = TRUE; } - if ((type || *T_CIS != NUL) && icon != NULL) { + if ((type || *T_CIS != NUL || abstract_ui) && icon != NULL) { if (oldicon == NULL ) /* first call, save icon */ get_x11_icon(FALSE); - if (*T_CIS != NUL) { + if (abstract_ui) { + ui_set_icon((char *)icon); + } else if (*T_CIS != NUL) { out_str(T_CIS); /* set icon start */ out_str_nf(icon); out_str(T_CIE); /* set icon end */ @@ -270,7 +275,7 @@ int use_xterm_mouse(void) return 0; } -#if defined(USE_FNAME_CASE) || defined(PROTO) +#if defined(USE_FNAME_CASE) /* * Set the case of the file name, if it already exists. This will cause the * file name to remain exactly the same. @@ -326,7 +331,7 @@ int len /* buffer size, only used when name gets longer */ } #endif -#if defined(HAVE_ACL) || defined(PROTO) +#if defined(HAVE_ACL) # ifdef HAVE_SYS_ACL_H # include <sys/acl.h> # endif @@ -335,7 +340,7 @@ int len /* buffer size, only used when name gets longer */ # endif -#if defined(HAVE_SELINUX) || defined(PROTO) +#if defined(HAVE_SELINUX) /* * Copy security info from "from_file" to "to_file". */ @@ -437,7 +442,7 @@ int mch_nodetype(char_u *name) return NODE_WRITABLE; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void mch_free_mem(void) { free(oldtitle); diff --git a/src/nvim/path.c b/src/nvim/path.c index 8af4015611..219dac12de 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -403,9 +403,9 @@ char_u *save_absolute_path(const char_u *name) } -#if !defined(NO_EXPANDPATH) || defined(PROTO) +#if !defined(NO_EXPANDPATH) -#if defined(UNIX) || defined(USE_UNIXFILENAME) || defined(PROTO) +#if defined(UNIX) || defined(USE_UNIXFILENAME) /* * Unix style wildcard expansion code. * It's here because it's used both for Unix and Mac. @@ -1622,7 +1622,7 @@ int same_directory(char_u *f1, char_u *f2) && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0; } -#if !defined(NO_EXPANDPATH) || defined(PROTO) +#if !defined(NO_EXPANDPATH) /* * Compare path "p[]" to "q[]". * If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]" diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 62c01e3798..fafd99c046 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -3228,7 +3228,7 @@ static garray_T backpos = GA_EMPTY_INIT_VALUE; #define REGSTACK_INITIAL 2048 #define BACKPOS_INITIAL 64 -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_regexp_stuff(void) { ga_clear(®stack); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 52ded0aa49..8f4f894128 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -5971,7 +5971,7 @@ void screen_stop_highlight(void) */ void reset_cterm_colors(void) { - if (t_colors > 1) { + if (!abstract_ui && t_colors > 1) { /* set Normal cterm colors */ if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0) { out_str(T_OP); @@ -6150,8 +6150,7 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, return; /* it's a "normal" terminal when not in a GUI or cterm */ - norm_term = ( - t_colors <= 1); + norm_term = (!abstract_ui && t_colors <= 1); for (row = start_row; row < end_row; ++row) { if (has_mbyte ) { @@ -6675,8 +6674,8 @@ static void linecopy(int to, int from, win_T *wp) */ int can_clear(char_u *p) { - return *p != NUL && (t_colors <= 1 - || cterm_normal_bg_color == 0 || *T_UT != NUL); + return abstract_ui || (*p != NUL && (t_colors <= 1 + || cterm_normal_bg_color == 0 || *T_UT != NUL)); } /* @@ -8186,8 +8185,13 @@ void screen_resize(int width, int height, int mustset) Columns = width; } check_shellsize(); + height = Rows; + width = Columns; 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); } else { mch_set_shellsize(); diff --git a/src/nvim/search.c b/src/nvim/search.c index 25b8277933..e2781f17d5 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -294,7 +294,7 @@ void restore_search_patterns(void) } } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_search_patterns(void) { free(spats[0].pat); diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 25e4a6c93b..20fa35ed1c 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -329,7 +329,7 @@ void vim_strcat(char_u *restrict to, const char_u *restrict from, STRCPY(to + tolen, from); } -#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO) +#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) /* * Compare two strings, ignoring case, using current locale. * Doesn't work for multi-byte characters. @@ -353,7 +353,7 @@ int vim_stricmp(const char *s1, const char *s2) } #endif -#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) || defined(PROTO) +#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) /* * Compare two strings, for length "len", ignoring case, using current locale. * Doesn't work for multi-byte characters. diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index e9a814bc97..3980a4d8e6 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -45,6 +45,7 @@ #include "nvim/strings.h" #include "nvim/syntax_defs.h" #include "nvim/term.h" +#include "nvim/ui.h" #include "nvim/os/os.h" #include "nvim/os/time.h" @@ -223,8 +224,6 @@ struct name_list { #define ATTR_OFF (HL_ALL + 1) -#define SYN_NAMELEN 50 /* maximum length of a syntax name */ - static char *(spo_name_tab[SPO_COUNT]) = {"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="}; @@ -6036,6 +6035,7 @@ int load_colors(char_u *name) apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); recursive = FALSE; + ui_refresh(); return retval; } @@ -6070,8 +6070,6 @@ do_highlight ( int error = FALSE; int color; int is_normal_group = FALSE; /* "Normal" group */ -# define is_menu_group 0 -# define is_tooltip_group 0 /* * If no argument, list current highlighting. @@ -6438,8 +6436,7 @@ do_highlight ( HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; } 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 * probably an xterm-like terminal. Use the changed @@ -6449,7 +6446,7 @@ do_highlight ( p = T_CAF; else p = T_CSF; - if (*p != NUL && *(p + STRLEN(p) - 1) == 'm') + if (abstract_ui || (*p != NUL && *(p + STRLEN(p) - 1) == 'm')) switch (t_colors) { case 16: color = color_numbers_8[i]; @@ -6632,6 +6629,10 @@ do_highlight ( if (is_normal_group) { HL_TABLE()[idx].sg_term_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 set_hl_attr(idx); HL_TABLE()[idx].sg_scriptID = current_SID; @@ -6644,7 +6645,7 @@ do_highlight ( need_highlight_changed = TRUE; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_highlight(void) { for (int i = 0; i < highlight_ga.ga_len; ++i) { @@ -6860,7 +6861,7 @@ int hl_combine_attr(int char_attr, int prim_attr) if (char_attr <= HL_ALL && prim_attr <= HL_ALL) return char_attr | prim_attr; - if (t_colors > 1) { + if (abstract_ui || t_colors > 1) { if (char_attr > HL_ALL) char_aep = syn_cterm_attr2entry(char_attr); if (char_aep != NULL) @@ -6924,7 +6925,7 @@ int syn_attr2attr(int attr) { attrentry_T *aep; - if (t_colors > 1) + if (abstract_ui || t_colors > 1) aep = syn_cterm_attr2entry(attr); else aep = syn_term_attr2entry(attr); @@ -7194,9 +7195,10 @@ set_hl_attr ( * For the color term mode: If there are other than "normal" * 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; - else { + } else { 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.bg_color = sgp->sg_cterm_bg; @@ -7351,7 +7353,7 @@ int syn_id2attr(int hl_id) hl_id = syn_get_final_id(hl_id); sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */ - if (t_colors > 1) + if (abstract_ui || t_colors > 1) attr = sgp->sg_cterm_attr; else attr = sgp->sg_term_attr; diff --git a/src/nvim/tag.c b/src/nvim/tag.c index fb39e069f0..bab594a27d 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1981,7 +1981,7 @@ static void found_tagfile_cb(char_u *fname, void *cookie) GA_APPEND(char_u *, &tag_fnames, vim_strsave(fname)); } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void free_tag_stuff(void) { ga_clear_strings(&tag_fnames); diff --git a/src/nvim/term.c b/src/nvim/term.c index b78b01b68a..78fd3c6a67 100644 --- a/src/nvim/term.c +++ b/src/nvim/term.c @@ -170,6 +170,7 @@ static struct builtin_term builtin_termcaps[] = {(int)KS_DL, "\033|d"}, {(int)KS_CDL, "\033|%p1%dD"}, {(int)KS_CS, "\033|%p1%d;%p2%dR"}, + {(int)KS_CSV, "\033|%p1%d;%p2%dV"}, {(int)KS_CL, "\033|C"}, // attributes switched on with 'h', off with * 'H' {(int)KS_ME, "\033|31H"}, // HL_ALL @@ -1487,7 +1488,7 @@ set_mouse_termcode ( add_termcode(name, s, FALSE); } -# if (defined(UNIX) && defined(FEAT_MOUSE_TTY)) || defined(PROTO) +# if (defined(UNIX) && defined(FEAT_MOUSE_TTY)) void del_mouse_termcode ( char_u n /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */ @@ -1704,7 +1705,7 @@ static char_u term_7to8bit(char_u *p) } -#if !defined(HAVE_TGETENT) || defined(PROTO) +#if !defined(HAVE_TGETENT) char_u *tltoa(unsigned long i) { @@ -1816,17 +1817,20 @@ void term_write(char_u *s, size_t len) static char_u out_buf[OUT_SIZE + 1]; 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 */ void out_flush(void) { - if (out_pos != 0) { - /* set out_pos to 0 before ui_write, to avoid recursiveness */ - int len = out_pos; - out_pos = 0; - ui_write(out_buf, len); - } + int len = out_pos; + out_pos = 0; + ui_write(out_buf, len); } /* @@ -1945,7 +1949,7 @@ void term_delete_lines(int line_count) OUT_STR(tgoto((char *)T_CDL, 0, line_count)); } -#if defined(HAVE_TGETENT) || defined(PROTO) +#if defined(HAVE_TGETENT) void term_set_winpos(int x, int y) { /* Can't handle a negative value here */ @@ -2010,7 +2014,7 @@ static void term_color(char_u *s, int n) OUT_STR(tgoto((char *)s, 0, n)); } -#if defined(UNIX) || defined(MACOS_X) || defined(PROTO) +#if defined(UNIX) || defined(MACOS_X) /* * Generic function to set window title, using t_ts and t_fs. */ @@ -2202,7 +2206,11 @@ void win_new_shellsize(void) */ void shell_resized(void) { - screen_resize(0, 0, FALSE); + if (abstract_ui) { + ui_refresh(); + } else { + screen_resize(0, 0, FALSE); + } } /* diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 25d6a81960..a8ca58d633 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -60,11 +60,8 @@ static struct { int top, bot, left, right; } sr; static int current_highlight_mask = 0; -static HlAttrs current_attrs = { - false, false, false, false, false, false, -1, -1 -}; static bool cursor_enabled = true; -static int height = INT_MAX, width = INT_MAX; +static int height, width; // 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 @@ -98,6 +95,10 @@ void ui_write(uint8_t *s, int len) return; } + if (!len) { + return; + } + char_u *tofree = NULL; if (output_conv.vc_type != CONV_NONE) { @@ -113,6 +114,16 @@ void ui_write(uint8_t *s, int len) free(tofree); } +bool ui_rgb_attached(void) +{ + for (size_t i = 0; i < ui_count; i++) { + if (uis[i]->rgb) { + return true; + } + } + return false; +} + /* * If the machine has job control, use it to suspend the program, * otherwise fake it by starting a new shell. @@ -122,11 +133,24 @@ void ui_suspend(void) { if (abstract_ui) { UI_CALL(suspend); + UI_CALL(flush); } else { mch_suspend(); } } +void ui_set_title(char *title) +{ + UI_CALL(set_title, title); + UI_CALL(flush); +} + +void ui_set_icon(char *icon) +{ + UI_CALL(set_icon, icon); + UI_CALL(flush); +} + /* * Try to get the current Vim shell size. Put the result in Rows and Columns. * Use the new sizes as defaults for 'columns' and 'lines'. @@ -165,8 +189,31 @@ void ui_cursor_shape(void) } } -void ui_resize(int width, int height) +void ui_refresh(void) { + 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.bot = height - 1; sr.left = 0; @@ -240,7 +287,7 @@ void ui_attach(UI *ui) } uis[ui_count++] = ui; - resized(ui); + ui_refresh(); } void ui_detach(UI *ui) @@ -267,17 +314,8 @@ void ui_detach(UI *ui) 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) { - screen_resize(width, height, true); + ui_refresh(); } } @@ -295,8 +333,7 @@ static void highlight_start(int mask) return; } - set_highlight_args(current_highlight_mask, ¤t_attrs); - UI_CALL(highlight_set, current_attrs); + set_highlight_args(current_highlight_mask); } static void highlight_stop(int mask) @@ -309,12 +346,12 @@ static void highlight_stop(int mask) current_highlight_mask &= ~mask; } - set_highlight_args(current_highlight_mask, ¤t_attrs); - UI_CALL(highlight_set, current_attrs); + set_highlight_args(current_highlight_mask); } -static void set_highlight_args(int mask, HlAttrs *attrs) +static void set_highlight_args(int mask) { + HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1 }; attrentry_T *aep = NULL; if (mask > HL_ALL) { @@ -322,18 +359,40 @@ static void set_highlight_args(int mask, HlAttrs *attrs) mask = aep ? aep->ae_attr : 0; } - attrs->bold = mask & HL_BOLD; - attrs->standout = mask & HL_STANDOUT; - attrs->underline = mask & HL_UNDERLINE; - attrs->undercurl = mask & HL_UNDERCURL; - attrs->italic = mask & HL_ITALIC; - attrs->reverse = mask & HL_INVERSE; - attrs->foreground = aep && aep->fg_color >= 0 ? aep->fg_color : normal_fg; - attrs->background = aep && aep->bg_color >= 0 ? aep->bg_color : normal_bg; + rgb_attrs.bold = mask & HL_BOLD; + rgb_attrs.underline = mask & HL_UNDERLINE; + rgb_attrs.undercurl = mask & HL_UNDERCURL; + rgb_attrs.italic = mask & HL_ITALIC; + rgb_attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT); + HlAttrs cterm_attrs = rgb_attrs; + + if (aep) { + 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) { + if (!ui_count) { + return; + } + int arg1 = 0, arg2 = 0; uint8_t *end = ptr + len, *p, c; bool update_cursor = false; @@ -444,6 +503,9 @@ static void parse_abstract_ui_codes(uint8_t *ptr, int len) UI_CALL(put, NULL, 0); col++; } + if (col >= width) { + ui_linefeed(); + } p += clen; } ptr = p; @@ -457,25 +519,6 @@ static void parse_abstract_ui_codes(uint8_t *ptr, int len) 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) { int new_col = 0; diff --git a/src/nvim/ui.h b/src/nvim/ui.h index d0933055cc..099f2643d5 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -6,13 +6,14 @@ #include <stdint.h> typedef struct { - bool bold, standout, underline, undercurl, italic, reverse; + bool bold, underline, undercurl, italic, reverse; int foreground, background; } HlAttrs; typedef struct ui_t UI; struct ui_t { + bool rgb; int width, height; void *data; void (*resize)(UI *ui, int rows, int columns); @@ -32,7 +33,11 @@ struct ui_t { void (*bell)(UI *ui); void (*visual_bell)(UI *ui); void (*flush)(UI *ui); + void (*update_fg)(UI *ui, int fg); + void (*update_bg)(UI *ui, int bg); void (*suspend)(UI *ui); + void (*set_title)(UI *ui, char *title); + void (*set_icon)(UI *ui, char *icon); }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 59920cfbe1..4d84c69158 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -128,7 +128,7 @@ static int undo_undoes = FALSE; static int lastmark = 0; -#if defined(U_DEBUG) || defined(PROTO) +#if defined(U_DEBUG) /* * Check the undo structures for being valid. Print a warning when something * looks wrong. diff --git a/src/nvim/window.c b/src/nvim/window.c index f9190e6915..cf0977e280 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2060,7 +2060,7 @@ win_free_mem ( return wp; } -#if defined(EXITFREE) || defined(PROTO) +#if defined(EXITFREE) void win_free_all(void) { int dummy; |