aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/charset.c6
-rw-r--r--src/nvim/digraph.c4
-rw-r--r--src/nvim/eval.c17
-rw-r--r--src/nvim/ex_cmds.c15
-rw-r--r--src/nvim/ex_cmds2.c1
-rw-r--r--src/nvim/ex_docmd.c8
-rw-r--r--src/nvim/ex_eval.c10
-rw-r--r--src/nvim/ex_getln.c5
-rw-r--r--src/nvim/file_search.c8
-rw-r--r--src/nvim/fileio.c4
-rw-r--r--src/nvim/macros.h5
-rw-r--r--src/nvim/main.c110
-rw-r--r--src/nvim/mbyte.c2
-rw-r--r--src/nvim/memory.c3
-rw-r--r--src/nvim/misc1.c3
-rw-r--r--src/nvim/mouse.c67
-rw-r--r--src/nvim/normal.c9
-rw-r--r--src/nvim/option.c3
-rw-r--r--src/nvim/os/env.c2
-rw-r--r--src/nvim/os/shell.c10
-rw-r--r--src/nvim/os/time.c30
-rw-r--r--src/nvim/os_unix.c64
-rw-r--r--src/nvim/os_unix_defs.h10
-rw-r--r--src/nvim/screen.c98
-rw-r--r--src/nvim/search.c1
-rw-r--r--src/nvim/strings.c140
-rw-r--r--src/nvim/term.c252
-rw-r--r--src/nvim/term.h4
-rw-r--r--src/nvim/ui.c2
-rw-r--r--src/nvim/window.c1
31 files changed, 441 insertions, 454 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 3b05c7329c..184bcc0548 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -77,7 +77,6 @@ set(CONV_SOURCES
search.c
sha256.c
spell.c
- strings.c
syntax.c
tag.c
term.c
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index bbe80a519c..9e5194a5df 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1855,7 +1855,7 @@ int hexhex2nr(char_u *p)
#endif // if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK)
// || defined(PROTO)
-/// Return TRUE if "str" starts with a backslash that should be removed.
+/// Return true if "str" starts with a backslash that should be removed.
/// For WIN32 this is only done when the character after the
/// backslash is not a normal file name character.
/// '$' is a valid file name character, we don't remove the backslash before
@@ -1869,8 +1869,8 @@ int hexhex2nr(char_u *p)
///
/// @param str
///
-/// @return TRUE if `str` starts with a backslash that should be removed.
-int rem_backslash(char_u *str)
+/// @return true if `str` starts with a backslash that should be removed.
+bool rem_backslash(const char_u *str)
{
#ifdef BACKSLASH_IN_FILENAME
return str[0] == '\\'
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index 6587a43452..2b5fdea2fe 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.c
@@ -1813,10 +1813,10 @@ void ex_loadkeymap(exarg_T *eap)
if ((*p != '"') && (*p != NUL)) {
kmap_T *kp = GA_APPEND_VIA_PTR(kmap_T, &curbuf->b_kmap_ga);
s = skiptowhite(p);
- kp->from = vim_strnsave(p, (int)(s - p));
+ kp->from = vim_strnsave(p, (size_t)(s - p));
p = skipwhite(s);
s = skiptowhite(p);
- kp->to = vim_strnsave(p, (int)(s - p));
+ kp->to = vim_strnsave(p, (size_t)(s - p));
if ((STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN)
|| (*kp->from == NUL)
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 8be25bc34e..be69bdbe61 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6593,7 +6593,7 @@ static struct fst {
{"synconcealed", 2, 2, f_synconcealed},
{"synstack", 2, 2, f_synstack},
{"system", 1, 2, f_system},
- {"systemlist", 1, 2, f_systemlist},
+ {"systemlist", 1, 3, f_systemlist},
{"tabpagebuflist", 0, 1, f_tabpagebuflist},
{"tabpagenr", 0, 1, f_tabpagenr},
{"tabpagewinnr", 1, 2, f_tabpagewinnr},
@@ -14523,7 +14523,7 @@ static void f_synstack(typval_T *argvars, typval_T *rettv)
}
}
-static list_T* string_to_list(char_u *str, size_t len)
+static list_T* string_to_list(char_u *str, size_t len, bool keepempty)
{
list_T *list = list_alloc();
@@ -14543,6 +14543,11 @@ static list_T* string_to_list(char_u *str, size_t len)
list_append(list, li);
}
+ // Optionally retain final newline, if present
+ if (keepempty && str[len-1] == NL) {
+ list_append_string(list, (char_u*)"", 0);
+ }
+
return list;
}
@@ -14585,7 +14590,11 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
}
if (retlist) {
- rettv->vval.v_list = string_to_list((char_u *) res, nread);
+ int keepempty = 0;
+ if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
+ keepempty = get_tv_number(&argvars[2]);
+ }
+ rettv->vval.v_list = string_to_list((char_u *) res, nread, keepempty != 0);
rettv->vval.v_list->lv_refcount++;
rettv->v_type = VAR_LIST;
@@ -19723,7 +19732,7 @@ static void apply_job_autocmds(int id, char *name, char *type,
str_slot->li_tv.v_type = VAR_LIST;
str_slot->li_tv.v_lock = 0;
str_slot->li_tv.vval.v_list =
- string_to_list((char_u *) received, received_len);
+ string_to_list((char_u *) received, received_len, false);
str_slot->li_tv.vval.v_list->lv_refcount++;
list_append(list, str_slot);
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 556e0c01e3..44caa67847 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -47,6 +47,7 @@
#include "nvim/garray.h"
#include "nvim/memory.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
@@ -3602,10 +3603,16 @@ void do_sub(exarg_T *eap)
eap->flags = EXFLAG_PRINT;
}
- do_join(eap->line2 - eap->line1 + 1, FALSE, TRUE, FALSE, true);
- sub_nlines = sub_nsubs = eap->line2 - eap->line1 + 1;
- do_sub_msg(false);
- ex_may_print(eap);
+ linenr_T joined_lines_count = eap->line2 < curbuf->b_ml.ml_line_count
+ ? eap->line2 - eap->line1 + 2
+ : eap->line2 - eap->line1 + 1;
+ if (joined_lines_count > 1) {
+ do_join(joined_lines_count, FALSE, TRUE, FALSE, true);
+ sub_nsubs = joined_lines_count - 1;
+ sub_nlines = 1;
+ do_sub_msg(false);
+ ex_may_print(eap);
+ }
return;
}
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 24a1ccf85d..794e9930b9 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -157,7 +157,6 @@ void do_debug(char_u *cmd)
/* Make sure we are in raw mode and start termcap mode. Might have side
* effects... */
- settmode(TMODE_RAW);
starttermcap();
++RedrawingDisabled; /* don't redisplay the window */
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 3967c916bb..e180be4421 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5107,7 +5107,6 @@ static void ex_highlight(exarg_T *eap)
void not_exiting(void)
{
exiting = FALSE;
- settmode(TMODE_RAW);
}
/*
@@ -5994,7 +5993,6 @@ do_exedit (
{
int n;
int need_hide;
- int exmode_was = exmode_active;
/*
* ":vi" command ends Ex mode.
@@ -6014,8 +6012,6 @@ do_exedit (
eap->nextcmd = NULL;
}
- if (exmode_was != EXMODE_VIM)
- settmode(TMODE_RAW);
RedrawingDisabled = 0;
no_wait_return = 0;
need_wait_return = FALSE;
@@ -6446,7 +6442,7 @@ static void ex_winsize(exarg_T *eap)
p = arg;
h = getdigits(&arg);
if (*p != NUL && *arg == NUL)
- set_shellsize(w, h, TRUE);
+ screen_resize(w, h, TRUE);
else
EMSG(_("E465: :winsize requires two number arguments"));
}
@@ -7482,7 +7478,7 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name)
* If found return one of the SPEC_ values and set "*usedlen" to the length of
* the variable. Otherwise return -1 and "*usedlen" is unchanged.
*/
-int find_cmdline_var(char_u *src, int *usedlen)
+int find_cmdline_var(const char_u *src, int *usedlen) FUNC_ATTR_NONNULL_ALL
{
int len;
int i;
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index ef3facb18b..196f8e6136 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -386,21 +386,19 @@ int do_intthrow(struct condstack *cstack)
char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should_free)
{
char_u *ret, *mesg;
- int cmdlen;
char_u *p, *val;
if (type == ET_ERROR) {
*should_free = FALSE;
mesg = ((struct msglist *)value)->throw_msg;
if (cmdname != NULL && *cmdname != NUL) {
- cmdlen = (int)STRLEN(cmdname);
- ret = vim_strnsave((char_u *)"Vim(",
- 4 + cmdlen + 2 + (int)STRLEN(mesg));
+ size_t cmdlen = STRLEN(cmdname);
+ ret = vim_strnsave((char_u *)"Vim(", 4 + cmdlen + 2 + STRLEN(mesg));
STRCPY(&ret[4], cmdname);
STRCPY(&ret[4 + cmdlen], "):");
val = ret + 4 + cmdlen + 2;
} else {
- ret = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg));
+ ret = vim_strnsave((char_u *)"Vim:", 4 + STRLEN(mesg));
val = ret + 4;
}
@@ -708,7 +706,7 @@ static void report_pending(int action, int pending, void *value)
if (pending & CSTP_THROW) {
vim_snprintf((char *)IObuff, IOSIZE,
(char *)mesg, _("Exception"));
- mesg = vim_strnsave(IObuff, (int)STRLEN(IObuff) + 4);
+ mesg = vim_strnsave(IObuff, STRLEN(IObuff) + 4);
STRCAT(mesg, ": %s");
s = (char *)((except_T *)value)->value;
} else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT))
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 70db2dc479..e56592923d 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -48,6 +48,7 @@
#include "nvim/keymap.h"
#include "nvim/garray.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/ops.h"
#include "nvim/option.h"
#include "nvim/os_unix.h"
@@ -270,10 +271,6 @@ getcmdline (
setmouse();
ui_cursor_shape(); /* may show different cursor shape */
- /* When inside an autocommand for writing "exiting" may be set and
- * terminal mode set to cooked. Need to set raw mode here then. */
- settmode(TMODE_RAW);
-
init_history();
hiscnt = hislen; /* set hiscnt to impossible history value */
histype = hist_char2type(firstc);
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index a51f088586..9267e7991c 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -308,7 +308,7 @@ vim_findfile_init (
&& (vim_ispathsep(path[1]) || path[1] == NUL)
&& (!tagfile || vim_strchr(p_cpo, CPO_DOTTAG) == NULL)
&& rel_fname != NULL) {
- int len = (int)(path_tail(rel_fname) - rel_fname);
+ size_t len = (size_t)(path_tail(rel_fname) - rel_fname);
if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL) {
/* Make the start dir an absolute path name. */
@@ -375,8 +375,9 @@ vim_findfile_init (
search_ctx->ffsc_stopdirs_v = ptr;
walker = vim_strchr(walker, ';');
if (walker) {
+ assert(walker - helper >= 0);
search_ctx->ffsc_stopdirs_v[dircount-1] =
- vim_strnsave(helper, (int)(walker - helper));
+ vim_strnsave(helper, (size_t)(walker - helper));
walker++;
} else
/* this might be "", which means ascent till top
@@ -404,7 +405,8 @@ vim_findfile_init (
char *errpt;
/* save the fix part of the path */
- search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
+ assert(wc_part - path >= 0);
+ search_ctx->ffsc_fix_path = vim_strnsave(path, (size_t)(wc_part - path));
/*
* copy wc_path and add restricts to the '**' wildcard.
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 3be9d89d87..021b12208e 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1812,7 +1812,6 @@ failed:
* Switch on raw mode now and clear the screen.
*/
if (read_stdin) {
- settmode(TMODE_RAW); /* set to raw mode */
starttermcap();
screenclear();
}
@@ -2387,9 +2386,6 @@ buf_write (
else
overwriting = FALSE;
- if (exiting)
- settmode(TMODE_COOK); /* when exiting allow typeahead now */
-
++no_wait_return; /* don't wait for return yet */
/*
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index f8fd6ac6a2..215ad3a1f7 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -143,8 +143,9 @@
/* get length of multi-byte char, not including composing chars */
# define mb_cptr2len(p) (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
-# define MB_COPY_CHAR(f, \
- t) if (has_mbyte) mb_copy_char(&f, &t); else *t++ = *f++
+# define MB_COPY_CHAR(f, t) \
+ if (has_mbyte) mb_copy_char((const char_u **)(&f), &t); \
+ else *t++ = *f++
# define MB_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
# define MB_CHAR2LEN(c) (has_mbyte ? mb_char2len(c) : 1)
# define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 68ae000c35..8e19cf3686 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -43,6 +43,7 @@
#include "nvim/log.h"
#include "nvim/memory.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
@@ -60,10 +61,13 @@
#include "nvim/os/time.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/os/time.h"
+#include "nvim/os/event.h"
#include "nvim/os/signal.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/private/handle.h"
/* Maximum number of commands from + or -c arguments. */
#define MAX_ARG_CMDS 10
@@ -142,13 +146,60 @@ static char *(main_errors[]) =
#define ME_INVALID_ARG 5
};
+/// Performs early initialization.
+///
+/// Needed for unit tests. Must be called after `time_init()`.
+void early_init(void)
+{
+ handle_init();
+
+ (void)mb_init(); // init mb_bytelen_tab[] to ones
+ eval_init(); // init global variables
+
+#ifdef __QNXNTO__
+ qnx_init(); // PhAttach() for clipboard, (and gui)
+#endif
+
+ // Init the table of Normal mode commands.
+ init_normal_cmds();
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+ // Setup to use the current locale (for ctype() and many other things).
+ // NOTE: Translated messages with encodings other than latin1 will not
+ // work until set_init_1() has been called!
+ init_locale();
+#endif
+
+ // Allocate the first window and buffer.
+ // Can't do anything without it, exit when it fails.
+ if (!win_alloc_first()) {
+ mch_exit(0);
+ }
+
+ init_yank(); // init yank buffers
+
+ alist_init(&global_alist); // Init the argument list to empty.
+ global_alist.id = 0;
+
+ // Set the default values for the options.
+ // NOTE: Non-latin1 translated messages are working only after this,
+ // because this is where "has_mbyte" will be set, which is used by
+ // msg_outtrans_len_attr().
+ // First find out the home directory, needed to expand "~" in options.
+ init_homedir(); // find real value of $HOME
+ set_init_1();
+ TIME_MSG("inits 1");
+
+ set_lang_var(); // set v:lang and v:ctype
+}
+
#ifndef NO_VIM_MAIN /* skip this for unittests */
int main(int argc, char **argv)
{
char_u *fname = NULL; /* file name from command line */
mparm_T params; /* various parameters passed between
* main() and other functions. */
- mch_early_init();
+ time_init();
/* Many variables are in "params" so that we can pass them to invoked
* functions without a lot of arguments. "argc" and "argv" are also
@@ -157,24 +208,7 @@ int main(int argc, char **argv)
init_startuptime(&params);
- (void)mb_init(); /* init mb_bytelen_tab[] to ones */
- eval_init(); /* init global variables */
-
-#ifdef __QNXNTO__
- qnx_init(); /* PhAttach() for clipboard, (and gui) */
-#endif
-
- /* Init the table of Normal mode commands. */
- init_normal_cmds();
-
-#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
- /*
- * Setup to use the current locale (for ctype() and many other things).
- * NOTE: Translated messages with encodings other than latin1 will not
- * work until set_init_1() has been called!
- */
- init_locale();
-#endif
+ early_init();
/*
* Check if we have an interactive window.
@@ -185,32 +219,6 @@ int main(int argc, char **argv)
check_and_set_isatty(&params);
/*
- * Allocate the first window and buffer.
- * Can't do anything without it, exit when it fails.
- */
- if (win_alloc_first() == FAIL)
- mch_exit(0);
-
- init_yank(); /* init yank buffers */
-
- alist_init(&global_alist); /* Init the argument list to empty. */
- global_alist.id = 0;
-
- /*
- * Set the default values for the options.
- * NOTE: Non-latin1 translated messages are working only after this,
- * because this is where "has_mbyte" will be set, which is used by
- * msg_outtrans_len_attr().
- * First find out the home directory, needed to expand "~" in options.
- */
- init_homedir(); /* find real value of $HOME */
- set_init_1();
- TIME_MSG("inits 1");
-
- set_lang_var(); /* set v:lang and v:ctype */
-
-
- /*
* Figure out the way to work from the command name argv[0].
* "vimdiff" starts diff mode, "rvim" sets "restricted", etc.
*/
@@ -252,14 +260,12 @@ int main(int argc, char **argv)
*/
- /*
- * mch_init() sets up the terminal (window) for use. This must be
- * done after resetting full_screen, otherwise it may move the cursor
- * Note that we may use mch_exit() before mch_init()!
- */
- mch_init();
+ // term_init() sets up the terminal (window) for use. This must be
+ // done after resetting full_screen, otherwise it may move the cursor
+ term_init();
TIME_MSG("shell init");
+ event_init();
if (!embedded_mode) {
// Print a warning if stdout is not a terminal.
@@ -276,7 +282,7 @@ int main(int argc, char **argv)
// In embedded mode don't do terminal-related initializations, assume an
// initial screen size of 80x20
full_screen = true;
- set_shellsize(80, 20, false);
+ screen_resize(80, 20, false);
} else {
// set terminal name and get terminal capabilities (will set full_screen)
// Do some initialization of the screen
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index d79a46ceaa..9b4513e979 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -3002,7 +3002,7 @@ int utf_head_off(const char_u *base, const char_u *p)
/*
* Copy a character from "*fp" to "*tp" and advance the pointers.
*/
-void mb_copy_char(char_u **fp, char_u **tp)
+void mb_copy_char(const char_u **fp, char_u **tp)
{
int l = (*mb_ptr2len)(*fp);
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 4c5a45b8b6..f959ea55e4 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -305,6 +305,7 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
/// @param size Size of destination buffer
/// @return Length of the source string (i.e.: strlen(src))
size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size)
+ FUNC_ATTR_NONNULL_ALL
{
size_t ret = strlen(src);
@@ -348,7 +349,7 @@ char *xstrdup(const char *str)
/// @param c The byte to search for.
/// @param len The length of the memory object.
/// @returns a pointer to the found byte in src[len], or NULL.
-void *xmemrchr(void *src, uint8_t c, size_t len)
+void *xmemrchr(const void *src, uint8_t c, size_t len)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
while (len--) {
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 230e198121..fc848466c6 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -42,6 +42,7 @@
#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/option.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
@@ -2286,8 +2287,6 @@ int ask_yesno(char_u *str, int direct)
int r = ' ';
int save_State = State;
- if (exiting) /* put terminal in raw mode for this question */
- settmode(TMODE_RAW);
++no_wait_return;
#ifdef USE_ON_FLY_SCROLL
dont_scroll = TRUE; /* disallow scrolling here */
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 7fc581a7c0..439cdbd5c8 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -2,8 +2,12 @@
#include "nvim/mouse.h"
#include "nvim/vim.h"
-#include "nvim/screen.h"
+#include "nvim/ascii.h"
#include "nvim/window.h"
+#include "nvim/strings.h"
+#include "nvim/screen.h"
+#include "nvim/ui.h"
+#include "nvim/os_unix.h"
#include "nvim/term.h"
#include "nvim/fold.h"
#include "nvim/diff.h"
@@ -165,11 +169,9 @@ retnomove:
// (MOUSE_FOCUS was set above if we dragged first).
if (dragwin == NULL || (flags & MOUSE_RELEASED))
win_enter(wp, true); // can make wp invalid!
-# ifdef CHECK_DOUBLE_CLICK
// set topline, to be able to check for double click ourselves
if (curwin != old_curwin)
set_mouse_topline(curwin);
-# endif
if (on_status_line) { // In (or below) status line
// Don't use start_arrow() if we're in the same window
if (curwin == old_curwin)
@@ -436,3 +438,62 @@ win_T *mouse_find_win(int *rowp, int *colp)
}
return fp->fr_win;
}
+
+/*
+ * setmouse() - switch mouse on/off depending on current mode and 'mouse'
+ */
+void setmouse(void)
+{
+ int checkfor;
+
+
+ /* be quick when mouse is off */
+ if (*p_mouse == NUL)
+ return;
+
+ /* don't switch mouse on when not in raw mode (Ex mode) */
+ if (cur_tmode != TMODE_RAW) {
+ mch_setmouse(false);
+ return;
+ }
+
+ if (VIsual_active)
+ checkfor = MOUSE_VISUAL;
+ else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
+ checkfor = MOUSE_RETURN;
+ else if (State & INSERT)
+ checkfor = MOUSE_INSERT;
+ else if (State & CMDLINE)
+ checkfor = MOUSE_COMMAND;
+ else if (State == CONFIRM || State == EXTERNCMD)
+ checkfor = ' '; /* don't use mouse for ":confirm" or ":!cmd" */
+ else
+ checkfor = MOUSE_NORMAL; /* assume normal mode */
+
+ if (mouse_has(checkfor))
+ mch_setmouse(true);
+ else
+ mch_setmouse(false);
+}
+
+/*
+ * Return true if
+ * - "c" is in 'mouse', or
+ * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
+ * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
+ * normal editing mode (not at hit-return message).
+ */
+int mouse_has(int c)
+{
+ for (char_u *p = p_mouse; *p; ++p)
+ switch (*p) {
+ case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
+ return true;
+ break;
+ case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
+ return true;
+ break;
+ default: if (c == *p) return true; break;
+ }
+ return false;
+}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 0a43d59607..1b21100933 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -46,6 +46,7 @@
#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/ops.h"
#include "nvim/option.h"
#include "nvim/quickfix.h"
@@ -7374,3 +7375,11 @@ static void nv_cursorhold(cmdarg_T *cap)
did_cursorhold = true;
cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
}
+
+/*
+ * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
+ */
+static int mouse_model_popup(void)
+{
+ return p_mousem[0] == 'p';
+}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index ee70b5bf8a..2882d7a511 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -66,6 +66,7 @@
#include "nvim/garray.h"
#include "nvim/cursor_shape.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/normal.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
@@ -5540,7 +5541,7 @@ set_num_option (
*pp = old_value;
else if (full_screen
)
- set_shellsize((int)Columns, (int)Rows, TRUE);
+ screen_resize((int)Columns, (int)Rows, TRUE);
else {
/* Postpone the resizing; check the size and cmdline position for
* messages. */
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 3aefbc39d1..b2e62453c5 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -43,7 +43,7 @@ char *os_getenvname_at_index(size_t index)
if (str == NULL) {
return NULL;
}
- int namesize = 0;
+ size_t namesize = 0;
while (str[namesize] != '=' && str[namesize] != NUL) {
namesize++;
}
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 1b279f18f5..cdd85e4e96 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -104,14 +104,10 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_arg)
{
DynamicBuffer input = DYNAMIC_BUFFER_INIT;
char *output = NULL, **output_ptr = NULL;
- int current_state = State, old_mode = cur_tmode;
+ int current_state = State;
bool forward_output = true;
out_flush();
- if (opts & kShellOptCooked) {
- settmode(TMODE_COOK);
- }
-
// While the child is running, ignore terminating signals
signal_reject_deadly();
@@ -155,10 +151,6 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_arg)
msg_putchar('\n');
}
- if (old_mode == TMODE_RAW) {
- // restore mode
- settmode(TMODE_RAW);
- }
State = current_state;
signal_accept_deadly();
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index a4871ef499..3794e813d2 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -6,6 +6,7 @@
#include <uv.h>
#include "nvim/os/time.h"
+#include "nvim/os/event.h"
#include "nvim/vim.h"
#include "nvim/term.h"
@@ -38,31 +39,22 @@ uint64_t os_hrtime(void)
/// @param ignoreinput If true, allow a SIGINT to interrupt us
void os_delay(uint64_t milliseconds, bool ignoreinput)
{
- os_microdelay(milliseconds * 1000, ignoreinput);
+ if (ignoreinput) {
+ if (milliseconds > INT_MAX) {
+ milliseconds = INT_MAX;
+ }
+ event_poll_until((int)milliseconds, got_int);
+ } else {
+ os_microdelay(milliseconds * 1000);
+ }
}
/// Sleeps for a certain amount of microseconds
///
/// @param microseconds Number of microseconds to sleep
-/// @param ignoreinput If true, allow a SIGINT to interrupt us
-void os_microdelay(uint64_t microseconds, bool ignoreinput)
+void os_microdelay(uint64_t microseconds)
{
- int old_tmode;
-
- if (ignoreinput) {
- // Go to cooked mode without echo, to allow SIGINT interrupting us
- // here
- old_tmode = curr_tmode;
-
- if (curr_tmode == TMODE_RAW)
- settmode(TMODE_SLEEP);
-
- microdelay(microseconds);
-
- settmode(old_tmode);
- } else {
- microdelay(microseconds);
- }
+ microdelay(microseconds);
}
/// Portable version of POSIX localtime_r()
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 3bf1198b46..677976e3e1 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -1,6 +1,5 @@
/*
* VIM - Vi IMproved by Bram Moolenaar
- * OS/2 port by Paul Slootman
* VMS merge by Zoltan Arpadffy
*
* Do ":help uganda" in Vim to read copying and usage conditions.
@@ -10,7 +9,7 @@
/*
* os_unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
- * Also for BeOS and Atari MiNT.
+ * Also for BeOS
*
* A lot of this file was originally written by Juergen Weigert and later
* changed beyond recognition.
@@ -38,6 +37,7 @@
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/misc2.h"
+#include "nvim/mouse.h"
#include "nvim/garray.h"
#include "nvim/path.h"
#include "nvim/screen.h"
@@ -82,47 +82,22 @@ static int did_set_title = FALSE;
static char_u *oldicon = NULL;
static int did_set_icon = FALSE;
-
-
-/*
- * Write s[len] to the screen.
- */
-void mch_write(char_u *s, int len)
-{
- if (embedded_mode) {
- // TODO(tarruda): This is a temporary hack to stop Neovim from writing
- // messages to stdout in embedded mode. In the future, embedded mode will
- // be the only possibility(GUIs will always start neovim with a msgpack-rpc
- // over stdio) and this function won't exist.
- //
- // The reason for this is because before Neovim fully migrates to a
- // msgpack-rpc-driven architecture, we must have a fully functional
- // UI working
- return;
- }
-
- ignored = (int)write(1, (char *)s, len);
- if (p_wd) /* Unix is too fast, slow down a bit more */
- os_microdelay(p_wd, false);
-}
-
/*
* If the machine has job control, use it to suspend the program,
* otherwise fake it by starting a new shell.
*/
void mch_suspend(void)
{
- /* BeOS does have SIGTSTP, but it doesn't work. */
-#if defined(SIGTSTP) && !defined(__BEOS__)
+#if defined(SIGTSTP)
out_flush(); /* needed to make cursor visible on some systems */
settmode(TMODE_COOK);
out_flush(); /* needed to disable mouse on some systems */
-
+ // Note: compiler defines _REENTRANT when given -pthread flag.
# if defined(_REENTRANT) && defined(SIGCONT)
sigcont_received = FALSE;
# endif
- kill(0, SIGTSTP); /* send ourselves a STOP signal */
+ uv_kill(0, SIGTSTP); // send ourselves a STOP signal
# if defined(_REENTRANT) && defined(SIGCONT)
/*
* Wait for the SIGCONT signal to be handled. It generally happens
@@ -154,20 +129,6 @@ void mch_suspend(void)
#endif
}
-void mch_init(void)
-{
- Columns = 80;
- Rows = 24;
-
- out_flush();
-
-#ifdef MACOS_CONVERT
- mac_conv_init();
-#endif
-
- event_init();
-}
-
static int get_x11_title(int test_only)
{
return FALSE;
@@ -478,12 +439,6 @@ int mch_nodetype(char_u *name)
return NODE_WRITABLE;
}
-void mch_early_init(void)
-{
- handle_init();
- time_init();
-}
-
#if defined(EXITFREE) || defined(PROTO)
void mch_free_mem(void)
{
@@ -569,9 +524,8 @@ void mch_settmode(int tmode)
{
static int first = TRUE;
- /* Why is NeXT excluded here (and not in os_unixx.h)? */
#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
- defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
+ defined(HAVE_TERMIOS_H))
/*
* for "new" tty systems
*/
@@ -599,9 +553,8 @@ void mch_settmode(int tmode)
*/
tnew.c_iflag &= ~ICRNL;
tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
-# if defined(IEXTEN) && !defined(__MINT__)
+# if defined(IEXTEN)
| IEXTEN /* IEXTEN enables typing ^V on SOLARIS */
- /* but it breaks function keys on MINT */
# endif
);
# ifdef ONLCR /* don't map NL -> CR NL, we do it ourselves */
@@ -667,9 +620,8 @@ void get_stty(void)
char_u buf[2];
char_u *p;
- /* Why is NeXT excluded here (and not in os_unixx.h)? */
#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
- defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
+ defined(HAVE_TERMIOS_H))
/* for "new" tty systems */
# ifdef HAVE_TERMIOS_H
struct termios keys;
diff --git a/src/nvim/os_unix_defs.h b/src/nvim/os_unix_defs.h
index 2a44ec3412..ebea86ebcf 100644
--- a/src/nvim/os_unix_defs.h
+++ b/src/nvim/os_unix_defs.h
@@ -8,17 +8,13 @@
* Do ":help credits" in Vim to see a list of people who contributed.
*/
-/*
- * NextStep has a problem with configure, undefine a few things:
- */
-
#include <stdio.h>
#include <ctype.h>
-# include <sys/types.h>
-# include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
-# include <stdlib.h>
+#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 2dbf3f8888..0225eb72c1 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -103,6 +103,7 @@
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
+#include "nvim/edit.h"
#include "nvim/farsi.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
@@ -120,6 +121,7 @@
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/popupmnu.h"
#include "nvim/quickfix.h"
@@ -129,6 +131,7 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/term.h"
+#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/window.h"
@@ -8117,3 +8120,98 @@ int screen_screenrow(void)
return screen_cur_row;
}
+/*
+ * Set size of the Vim shell.
+ * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
+ * window size (this is used for the :win command).
+ * If 'mustset' is FALSE, we may try to get the real window size and if
+ * it fails use 'width' and 'height'.
+ */
+void screen_resize(int width, int height, int mustset)
+{
+ static int busy = FALSE;
+
+ /*
+ * Avoid recursiveness, can happen when setting the window size causes
+ * another window-changed signal.
+ */
+ if (busy)
+ return;
+
+ if (width < 0 || height < 0) /* just checking... */
+ return;
+
+ if (State == HITRETURN || State == SETWSIZE) {
+ /* postpone the resizing */
+ State = SETWSIZE;
+ return;
+ }
+
+ /* curwin->w_buffer can be NULL when we are closing a window and the
+ * buffer has already been closed and removing a scrollbar causes a resize
+ * event. Don't resize then, it will happen after entering another buffer.
+ */
+ if (curwin->w_buffer == NULL)
+ return;
+
+ ++busy;
+
+
+ if (mustset || (ui_get_shellsize() == FAIL && height != 0)) {
+ Rows = height;
+ Columns = width;
+ check_shellsize();
+ mch_set_shellsize();
+ } else
+ check_shellsize();
+
+ /* The window layout used to be adjusted here, but it now happens in
+ * screenalloc() (also invoked from screenclear()). That is because the
+ * "busy" check above may skip this, but not screenalloc(). */
+
+ if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
+ screenclear();
+ else
+ screen_start(); /* don't know where cursor is now */
+
+ if (starting != NO_SCREEN) {
+ maketitle();
+ changed_line_abv_curs();
+ invalidate_botline();
+
+ /*
+ * We only redraw when it's needed:
+ * - While at the more prompt or executing an external command, don't
+ * redraw, but position the cursor.
+ * - While editing the command line, only redraw that.
+ * - in Ex mode, don't redraw anything.
+ * - Otherwise, redraw right now, and position the cursor.
+ * Always need to call update_screen() or screenalloc(), to make
+ * sure Rows/Columns and the size of ScreenLines[] is correct!
+ */
+ if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
+ || exmode_active) {
+ screenalloc(false);
+ repeat_message();
+ } else {
+ if (curwin->w_p_scb)
+ do_check_scrollbind(TRUE);
+ if (State & CMDLINE) {
+ update_screen(NOT_VALID);
+ redrawcmdline();
+ } else {
+ update_topline();
+ if (pum_visible()) {
+ redraw_later(NOT_VALID);
+ ins_compl_show_pum(); /* This includes the redraw. */
+ } else
+ update_screen(NOT_VALID);
+ if (redrawing())
+ setcursor();
+ }
+ }
+ cursor_on(); /* redrawing may have switched it off */
+ }
+ out_flush();
+ --busy;
+}
diff --git a/src/nvim/search.c b/src/nvim/search.c
index e9184d84cd..3055729bf8 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -39,6 +39,7 @@
#include "nvim/misc1.h"
#include "nvim/misc2.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/path.h"
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 6c69b3b34a..20008bca16 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -49,7 +49,8 @@
/*
* Copy "string" into newly allocated memory.
*/
-char_u *vim_strsave(char_u *string) FUNC_ATTR_NONNULL_RET
+char_u *vim_strsave(const char_u *string)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
return (char_u *)xstrdup((char *)string);
}
@@ -60,7 +61,8 @@ char_u *vim_strsave(char_u *string) FUNC_ATTR_NONNULL_RET
* The allocated memory always has size "len + 1", also when "string" is
* shorter.
*/
-char_u *vim_strnsave(char_u *string, int len) FUNC_ATTR_NONNULL_RET
+char_u *vim_strnsave(const char_u *string, size_t len)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
return (char_u *)strncpy(xmallocz(len), (char *)string, len);
}
@@ -69,31 +71,30 @@ char_u *vim_strnsave(char_u *string, int len) FUNC_ATTR_NONNULL_RET
* Same as vim_strsave(), but any characters found in esc_chars are preceded
* by a backslash.
*/
-char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars)
- FUNC_ATTR_NONNULL_RET
+char_u *vim_strsave_escaped(const char_u *string, const char_u *esc_chars)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE);
+ return vim_strsave_escaped_ext(string, esc_chars, '\\', false);
}
/*
- * Same as vim_strsave_escaped(), but when "bsl" is TRUE also escape
+ * Same as vim_strsave_escaped(), but when "bsl" is true also escape
* characters where rem_backslash() would remove the backslash.
* Escape the characters with "cc".
*/
-char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int bsl)
- FUNC_ATTR_NONNULL_RET
+char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars,
+ char_u cc, bool bsl)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- unsigned length;
- int l;
-
/*
* First count the number of backslashes required.
* Then allocate the memory and insert them.
*/
- length = 1; /* count the trailing NUL */
- for (char_u *p = string; *p; p++) {
- if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
- length += l; /* count a multibyte char */
+ size_t length = 1; // count the trailing NUL
+ for (const char_u *p = string; *p; p++) {
+ size_t l;
+ if (has_mbyte && (l = (size_t)(*mb_ptr2len)(p)) > 1) {
+ length += l; // count a multibyte char
p += l - 1;
continue;
}
@@ -104,9 +105,10 @@ char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int b
char_u *escaped_string = xmalloc(length);
char_u *p2 = escaped_string;
- for (char_u *p = string; *p; p++) {
- if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
- memmove(p2, p, (size_t)l);
+ for (const char_u *p = string; *p; p++) {
+ size_t l;
+ if (has_mbyte && (l = (size_t)(*mb_ptr2len)(p)) > 1) {
+ memcpy(p2, p, l);
p2 += l;
p += l - 1; /* skip multibyte char */
continue;
@@ -130,10 +132,10 @@ char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int b
* When "do_newline" is false do not escape newline unless it is csh shell.
* Returns the result in allocated memory.
*/
-char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline)
+char_u *vim_strsave_shellescape(const char_u *string,
+ bool do_special, bool do_newline)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- unsigned length;
- char_u *p;
char_u *d;
char_u *escaped_string;
int l;
@@ -146,8 +148,8 @@ char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline
csh_like = csh_like_shell();
/* First count the number of extra bytes required. */
- length = (unsigned)STRLEN(string) + 3; /* two quotes and a trailing NUL */
- for (p = string; *p != NUL; mb_ptr_adv(p)) {
+ size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL
+ for (const char_u *p = string; *p != NUL; mb_ptr_adv(p)) {
if (*p == '\'')
length += 3; /* ' => '\'' */
if ((*p == '\n' && (csh_like || do_newline))
@@ -169,7 +171,7 @@ char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline
/* add opening quote */
*d++ = '\'';
- for (p = string; *p != NUL; ) {
+ for (const char_u *p = string; *p != NUL; ) {
if (*p == '\'') {
*d++ = '\'';
*d++ = '\\';
@@ -207,7 +209,8 @@ char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline
* Like vim_strsave(), but make all characters uppercase.
* This uses ASCII lower-to-upper case translation, language independent.
*/
-char_u *vim_strsave_up(char_u *string)
+char_u *vim_strsave_up(const char_u *string)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
char_u *p1;
@@ -220,7 +223,8 @@ char_u *vim_strsave_up(char_u *string)
* Like vim_strnsave(), but make all characters uppercase.
* This uses ASCII lower-to-upper case translation, language independent.
*/
-char_u *vim_strnsave_up(char_u *string, int len) FUNC_ATTR_NONNULL_RET
+char_u *vim_strnsave_up(const char_u *string, size_t len)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
char_u *p1 = vim_strnsave(string, len);
vim_strup(p1);
@@ -231,14 +235,15 @@ char_u *vim_strnsave_up(char_u *string, int len) FUNC_ATTR_NONNULL_RET
* ASCII lower-to-upper case translation, language independent.
*/
void vim_strup(char_u *p)
+ FUNC_ATTR_NONNULL_ALL
{
char_u *p2;
- int c;
+ char_u c;
if (p != NULL) {
p2 = p;
while ((c = *p2) != NUL)
- *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
+ *p2++ = (char_u)((c < 'a' || c > 'z') ? c : c - 0x20);
}
}
@@ -246,7 +251,8 @@ void vim_strup(char_u *p)
* Make string "s" all upper-case and return it in allocated memory.
* Handles multi-byte characters as well as possible.
*/
-char_u *strup_save(char_u *orig)
+char_u *strup_save(const char_u *orig)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
char_u *res = vim_strsave(orig);
@@ -264,8 +270,8 @@ char_u *strup_save(char_u *orig)
int newl = utf_char2len(uc);
if (newl != l) {
// TODO(philix): use xrealloc() in strup_save()
- char_u *s = xmalloc(STRLEN(res) + 1 + newl - l);
- memmove(s, res, p - res);
+ char_u *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
+ memcpy(s, res, (size_t)(p - res));
STRCPY(s + (p - res) + newl, p + l);
p = s + (p - res);
free(res);
@@ -277,7 +283,7 @@ char_u *strup_save(char_u *orig)
} else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
p += l; /* skip multi-byte character */
else {
- *p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */
+ *p = (char_u) TOUPPER_LOC(*p); // note that toupper() can be a macro
p++;
}
}
@@ -289,6 +295,7 @@ char_u *strup_save(char_u *orig)
* copy a space a number of times
*/
void copy_spaces(char_u *ptr, size_t count)
+ FUNC_ATTR_NONNULL_ALL
{
size_t i = count;
char_u *p = ptr;
@@ -301,7 +308,8 @@ void copy_spaces(char_u *ptr, size_t count)
* Copy a character a number of times.
* Does not work for multi-byte characters!
*/
-void copy_chars(char_u *ptr, size_t count, int c)
+void copy_chars(char_u *ptr, size_t count, char_u c)
+ FUNC_ATTR_NONNULL_ALL
{
size_t i = count;
char_u *p = ptr;
@@ -314,6 +322,7 @@ void copy_chars(char_u *ptr, size_t count, int c)
* delete spaces at the end of a string
*/
void del_trailing_spaces(char_u *ptr)
+ FUNC_ATTR_NONNULL_ALL
{
char_u *q;
@@ -326,7 +335,8 @@ void del_trailing_spaces(char_u *ptr)
* Like strncpy(), but always terminate the result with one NUL.
* "to" must be "len + 1" long!
*/
-void vim_strncpy(char_u *to, char_u *from, size_t len)
+void vim_strncpy(char_u *restrict to, const char_u *restrict from, size_t len)
+ FUNC_ATTR_NONNULL_ALL
{
STRNCPY(to, from, len);
to[len] = NUL;
@@ -336,13 +346,15 @@ void vim_strncpy(char_u *to, char_u *from, size_t len)
* Like strcat(), but make sure the result fits in "tosize" bytes and is
* always NUL terminated.
*/
-void vim_strcat(char_u *to, char_u *from, size_t tosize)
+void vim_strcat(char_u *restrict to, const char_u *restrict from,
+ size_t tosize)
+ FUNC_ATTR_NONNULL_ALL
{
size_t tolen = STRLEN(to);
size_t fromlen = STRLEN(from);
if (tolen + fromlen + 1 > tosize) {
- memmove(to + tolen, from, tosize - tolen - 1);
+ memcpy(to + tolen, from, tosize - tolen - 1);
to[tosize - 1] = NUL;
} else
STRCPY(to + tolen, from);
@@ -354,7 +366,8 @@ void vim_strcat(char_u *to, char_u *from, size_t tosize)
* Doesn't work for multi-byte characters.
* return 0 for match, < 0 for smaller, > 0 for bigger
*/
-int vim_stricmp(char *s1, char *s2)
+int vim_stricmp(const char *s1, const char *s2)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
int i;
@@ -377,7 +390,8 @@ int vim_stricmp(char *s1, char *s2)
* Doesn't work for multi-byte characters.
* return 0 for match, < 0 for smaller, > 0 for bigger
*/
-int vim_strnicmp(char *s1, char *s2, size_t len)
+int vim_strnicmp(const char *s1, const char *s2, size_t len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
int i;
@@ -400,16 +414,16 @@ int vim_strnicmp(char *s1, char *s2, size_t len)
* with characters from 128 to 255 correctly. It also doesn't return a
* pointer to the NUL at the end of the string.
*/
-char_u *vim_strchr(char_u *string, int c)
+char_u *vim_strchr(const char_u *string, int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
- char_u *p;
int b;
- p = string;
+ const char_u *p = string;
if (enc_utf8 && c >= 0x80) {
while (*p != NUL) {
if (utf_ptr2char(p) == c)
- return p;
+ return (char_u *) p;
p += (*mb_ptr2len)(p);
}
return NULL;
@@ -420,7 +434,7 @@ char_u *vim_strchr(char_u *string, int c)
c = ((unsigned)c >> 8) & 0xff;
while ((b = *p) != NUL) {
if (b == c && p[1] == n2)
- return p;
+ return (char_u *) p;
p += (*mb_ptr2len)(p);
}
return NULL;
@@ -428,14 +442,14 @@ char_u *vim_strchr(char_u *string, int c)
if (has_mbyte) {
while ((b = *p) != NUL) {
if (b == c)
- return p;
+ return (char_u *) p;
p += (*mb_ptr2len)(p);
}
return NULL;
}
while ((b = *p) != NUL) {
if (b == c)
- return p;
+ return (char_u *) p;
++p;
}
return NULL;
@@ -446,13 +460,14 @@ char_u *vim_strchr(char_u *string, int c)
* strings with characters above 128 correctly. It also doesn't return a
* pointer to the NUL at the end of the string.
*/
-char_u *vim_strbyte(char_u *string, int c)
+char_u *vim_strbyte(const char_u *string, int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
- char_u *p = string;
+ const char_u *p = string;
while (*p != NUL) {
if (*p == c)
- return p;
+ return (char_u *) p;
++p;
}
return NULL;
@@ -463,24 +478,26 @@ char_u *vim_strbyte(char_u *string, int c)
* Return NULL if not found.
* Does not handle multi-byte char for "c"!
*/
-char_u *vim_strrchr(char_u *string, int c)
+char_u *vim_strrchr(const char_u *string, int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
- char_u *retval = NULL;
- char_u *p = string;
+ const char_u *retval = NULL;
+ const char_u *p = string;
while (*p) {
if (*p == c)
retval = p;
mb_ptr_adv(p);
}
- return retval;
+ return (char_u *) retval;
}
/*
* Vim has its own isspace() function, because on some machines isspace()
* can't handle characters above 128.
*/
-int vim_isspace(int x)
+bool vim_isspace(int x)
+ FUNC_ATTR_CONST
{
return (x >= 9 && x <= 13) || x == ' ';
}
@@ -493,6 +510,7 @@ int vim_isspace(int x)
# include "strings.c.generated.h"
#endif
static int sort_compare(const void *s1, const void *s2)
+ FUNC_ATTR_NONNULL_ALL
{
return STRCMP(*(char **)s1, *(char **)s2);
}
@@ -503,24 +521,26 @@ void sort_strings(char_u **files, int count)
}
/*
- * Return TRUE if string "s" contains a non-ASCII character (128 or higher).
- * When "s" is NULL FALSE is returned.
+ * Return true if string "s" contains a non-ASCII character (128 or higher).
+ * When "s" is NULL false is returned.
*/
-int has_non_ascii(char_u *s)
+bool has_non_ascii(const char_u *s)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
{
- char_u *p;
+ const char_u *p;
if (s != NULL)
for (p = s; *p != NUL; ++p)
if (*p >= 128)
- return TRUE;
- return FALSE;
+ return true;
+ return false;
}
/*
* Concatenate two strings and return the result in allocated memory.
*/
-char_u *concat_str(char_u *str1, char_u *str2) FUNC_ATTR_NONNULL_RET
+char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
size_t l = STRLEN(str1);
char_u *dest = xmalloc(l + STRLEN(str2) + 1);
diff --git a/src/nvim/term.c b/src/nvim/term.c
index 3d1053bd2f..54508b1daa 100644
--- a/src/nvim/term.c
+++ b/src/nvim/term.c
@@ -43,6 +43,7 @@
#include "nvim/keymap.h"
#include "nvim/memory.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/os_unix.h"
@@ -639,7 +640,7 @@ static struct builtin_term builtin_termcaps[] =
{K_BS, "\x7f"}, /* for some reason 0177 doesn't work */
# endif
-# if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__)
+# if defined(ALL_BUILTIN_TCAPS)
/*
* Ordinary vt52
*/
@@ -998,7 +999,7 @@ static struct builtin_term builtin_termcaps[] =
-#if defined(UNIX) && !defined(__MINT__)
+#if defined(UNIX)
# define DEFAULT_TERM (char_u *)"ansi"
#endif
@@ -1010,6 +1011,30 @@ static struct builtin_term builtin_termcaps[] =
# define DEFAULT_TERM (char_u *)"dumb"
#endif
+/// Sets up the terminal window for use.
+///
+/// This must be done after resetting full_screen, otherwise it may move the
+/// cursor.
+///
+/// @remark We may call mch_exit() before calling this.
+void term_init(void)
+{
+ Columns = 80;
+ Rows = 24;
+
+ // Prevent buffering output.
+ // Output gets explicitly buffered and flushed by out_flush() at times like,
+ // for example, when the user presses a key. Without this line, vim will not
+ // render the screen correctly.
+ setbuf(stdout, NULL);
+
+ out_flush();
+
+#ifdef MACOS_CONVERT
+ mac_conv_init();
+#endif
+}
+
/*
* Term_strings contains currently used terminal output strings.
* It is initialized with the default values by parse_builtin_tcap().
@@ -1448,7 +1473,7 @@ int set_termname(char_u *term)
width = 80;
height = 24; /* most terminals are 24 lines */
}
- set_shellsize(width, height, FALSE); /* may change Rows */
+ screen_resize(width, height, FALSE); /* may change Rows */
if (starting != NO_SCREEN) {
if (scroll_region)
scroll_region_reset(); /* In case Rows changed */
@@ -1482,7 +1507,6 @@ int set_termname(char_u *term)
# define HMT_PTERM 8
# define HMT_URXVT 16
# define HMT_SGR 32
-static int has_mouse_termcode = 0;
void
set_mouse_termcode (
@@ -1493,16 +1517,6 @@ set_mouse_termcode (
char_u name[2] = { n, KE_FILLER };
add_termcode(name, s, FALSE);
- if (n == KS_NETTERM_MOUSE)
- has_mouse_termcode |= HMT_NETTERM;
- else if (n == KS_DEC_MOUSE)
- has_mouse_termcode |= HMT_DEC;
- else if (n == KS_URXVT_MOUSE)
- has_mouse_termcode |= HMT_URXVT;
- else if (n == KS_SGR_MOUSE)
- has_mouse_termcode |= HMT_SGR;
- else
- has_mouse_termcode |= HMT_NORMAL;
}
# if (defined(UNIX) && defined(FEAT_MOUSE_TTY)) || defined(PROTO)
@@ -1514,16 +1528,6 @@ del_mouse_termcode (
char_u name[2] = { n, KE_FILLER };
del_termcode(name);
- if (n == KS_NETTERM_MOUSE)
- has_mouse_termcode &= ~HMT_NETTERM;
- else if (n == KS_DEC_MOUSE)
- has_mouse_termcode &= ~HMT_DEC;
- else if (n == KS_URXVT_MOUSE)
- has_mouse_termcode &= ~HMT_URXVT;
- else if (n == KS_SGR_MOUSE)
- has_mouse_termcode &= ~HMT_SGR;
- else
- has_mouse_termcode &= ~HMT_NORMAL;
}
# endif
@@ -1822,11 +1826,35 @@ void termcapinit(char_u *name)
set_termname(T_NAME != NULL ? T_NAME : term);
}
+/// Write s[len] to the screen.
+void term_write(char_u *s, size_t len)
+{
+ if (embedded_mode) {
+ // TODO(tarruda): This is a temporary hack to stop Neovim from writing
+ // messages to stdout in embedded mode. In the future, embedded mode will
+ // be the only possibility(GUIs will always start neovim with a msgpack-rpc
+ // over stdio) and this function won't exist.
+ //
+ // The reason for this is because before Neovim fully migrates to a
+ // msgpack-rpc-driven architecture, we must have a fully functional
+ // UI working
+ return;
+ }
+
+ (void) fwrite(s, len, 1, stdout);
+
+#ifdef UNIX
+ if (p_wd) { // Unix is too fast, slow down a bit more
+ os_microdelay(p_wd);
+ }
+#endif
+}
+
/*
* the number of calls to ui_write is reduced by using the buffer "out_buf"
*/
# define OUT_SIZE 2047
-/* Add one to allow mch_write() in os_win32.c to append a NUL */
+// Add one to allow term_write() in os_win32.c to append a NUL
static char_u out_buf[OUT_SIZE + 1];
static int out_pos = 0; /* number of chars in out_buf */
@@ -2241,7 +2269,7 @@ void win_new_shellsize(void)
*/
void shell_resized(void)
{
- set_shellsize(0, 0, FALSE);
+ screen_resize(0, 0, FALSE);
}
/*
@@ -2263,102 +2291,6 @@ void shell_resized_check(void)
}
/*
- * Set size of the Vim shell.
- * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
- * window size (this is used for the :win command).
- * If 'mustset' is FALSE, we may try to get the real window size and if
- * it fails use 'width' and 'height'.
- */
-void set_shellsize(int width, int height, int mustset)
-{
- static int busy = FALSE;
-
- /*
- * Avoid recursiveness, can happen when setting the window size causes
- * another window-changed signal.
- */
- if (busy)
- return;
-
- if (width < 0 || height < 0) /* just checking... */
- return;
-
- if (State == HITRETURN || State == SETWSIZE) {
- /* postpone the resizing */
- State = SETWSIZE;
- return;
- }
-
- /* curwin->w_buffer can be NULL when we are closing a window and the
- * buffer has already been closed and removing a scrollbar causes a resize
- * event. Don't resize then, it will happen after entering another buffer.
- */
- if (curwin->w_buffer == NULL)
- return;
-
- ++busy;
-
-
- if (mustset || (ui_get_shellsize() == FAIL && height != 0)) {
- Rows = height;
- Columns = width;
- check_shellsize();
- mch_set_shellsize();
- } else
- check_shellsize();
-
- /* The window layout used to be adjusted here, but it now happens in
- * screenalloc() (also invoked from screenclear()). That is because the
- * "busy" check above may skip this, but not screenalloc(). */
-
- if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
- screenclear();
- else
- screen_start(); /* don't know where cursor is now */
-
- if (starting != NO_SCREEN) {
- maketitle();
- changed_line_abv_curs();
- invalidate_botline();
-
- /*
- * We only redraw when it's needed:
- * - While at the more prompt or executing an external command, don't
- * redraw, but position the cursor.
- * - While editing the command line, only redraw that.
- * - in Ex mode, don't redraw anything.
- * - Otherwise, redraw right now, and position the cursor.
- * Always need to call update_screen() or screenalloc(), to make
- * sure Rows/Columns and the size of ScreenLines[] is correct!
- */
- if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
- || exmode_active) {
- screenalloc(false);
- repeat_message();
- } else {
- if (curwin->w_p_scb)
- do_check_scrollbind(TRUE);
- if (State & CMDLINE) {
- update_screen(NOT_VALID);
- redrawcmdline();
- } else {
- update_topline();
- if (pum_visible()) {
- redraw_later(NOT_VALID);
- ins_compl_show_pum(); /* This includes the redraw. */
- } else
- update_screen(NOT_VALID);
- if (redrawing())
- setcursor();
- }
- }
- cursor_on(); /* redrawing may have switched it off */
- }
- out_flush();
- --busy;
-}
-
-/*
* Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
* commands and Ex mode).
*/
@@ -2593,73 +2525,6 @@ int swapping_screen(void)
}
/*
- * setmouse() - switch mouse on/off depending on current mode and 'mouse'
- */
-void setmouse(void)
-{
- int checkfor;
-
-
- /* be quick when mouse is off */
- if (*p_mouse == NUL || has_mouse_termcode == 0)
- return;
-
- /* don't switch mouse on when not in raw mode (Ex mode) */
- if (cur_tmode != TMODE_RAW) {
- mch_setmouse(FALSE);
- return;
- }
-
- if (VIsual_active)
- checkfor = MOUSE_VISUAL;
- else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
- checkfor = MOUSE_RETURN;
- else if (State & INSERT)
- checkfor = MOUSE_INSERT;
- else if (State & CMDLINE)
- checkfor = MOUSE_COMMAND;
- else if (State == CONFIRM || State == EXTERNCMD)
- checkfor = ' '; /* don't use mouse for ":confirm" or ":!cmd" */
- else
- checkfor = MOUSE_NORMAL; /* assume normal mode */
-
- if (mouse_has(checkfor))
- mch_setmouse(TRUE);
- else
- mch_setmouse(FALSE);
-}
-
-/*
- * Return TRUE if
- * - "c" is in 'mouse', or
- * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
- * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
- * normal editing mode (not at hit-return message).
- */
-int mouse_has(int c)
-{
- for (char_u *p = p_mouse; *p; ++p)
- switch (*p) {
- case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
- return TRUE;
- break;
- case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
- return TRUE;
- break;
- default: if (c == *p) return TRUE; break;
- }
- return FALSE;
-}
-
-/*
- * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
- */
-int mouse_model_popup(void)
-{
- return p_mousem[0] == 'p';
-}
-
-/*
* By outputting the 'cursor very visible' termcap code, for some windowed
* terminals this makes the screen scrolled to the correct position.
* Used when starting Vim or returning from a shell.
@@ -2954,11 +2819,9 @@ static void switch_to_8bit(void)
LOG_TR("Switching to 8 bit");
}
-#ifdef CHECK_DOUBLE_CLICK
static linenr_T orig_topline = 0;
static int orig_topfill = 0;
-#endif
-#if defined(CHECK_DOUBLE_CLICK) || defined(PROTO)
+
/*
* Checking for double clicks ourselves.
* "orig_topline" is used to avoid detecting a double-click when the window
@@ -2973,7 +2836,6 @@ void set_mouse_topline(win_T *wp)
orig_topline = wp->w_topline;
orig_topfill = wp->w_topfill;
}
-#endif
/*
* Check if typebuf.tb_buf[] contains a terminal key code.
@@ -3664,7 +3526,6 @@ int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen)
is_drag = TRUE;
current_button = held_button;
} else if (wheel_code == 0) {
-# ifdef CHECK_DOUBLE_CLICK
{
static int orig_mouse_col = 0;
static int orig_mouse_row = 0;
@@ -3698,9 +3559,6 @@ int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen)
orig_topline = curwin->w_topline;
orig_topfill = curwin->w_topfill;
}
-# else
- orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
-# endif
is_click = TRUE;
orig_mouse_code = mouse_code;
}
diff --git a/src/nvim/term.h b/src/nvim/term.h
index 17154b8c26..3f70f484a7 100644
--- a/src/nvim/term.h
+++ b/src/nvim/term.h
@@ -52,10 +52,6 @@
* 128 = 16384 columns, now it's reduced to 10000. */
#define MOUSE_COLOFF 10000
-#if defined(UNIX)
-# define CHECK_DOUBLE_CLICK 1 /* Checking for double clicks ourselves. */
-#endif
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "term.h.generated.h"
#endif
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 526cc3e47e..eab6251288 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -55,7 +55,7 @@ void ui_write(char_u *s, int len)
s = tofree;
}
- mch_write(s, len);
+ term_write(s, len);
if (output_conv.vc_type != CONV_NONE)
free(tofree);
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 315d5f07de..bd461a873f 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -41,6 +41,7 @@
#include "nvim/file_search.h"
#include "nvim/garray.h"
#include "nvim/move.h"
+#include "nvim/mouse.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/os_unix.h"