aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/edit.c83
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/fileio.c48
-rw-r--r--src/nvim/keymap.c32
-rw-r--r--src/nvim/normal.c6
-rw-r--r--src/nvim/os/fs.c4
-rw-r--r--src/nvim/os/os_defs.h19
-rw-r--r--src/nvim/os/shell.c25
-rw-r--r--src/nvim/os/unix_defs.h12
-rw-r--r--src/nvim/os/win_defs.h5
-rw-r--r--src/nvim/os_unix.c4
-rw-r--r--src/nvim/strings.c48
-rw-r--r--src/nvim/terminal.c26
13 files changed, 149 insertions, 165 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index b3222b0781..ccfc9b4803 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1352,24 +1352,21 @@ ins_redraw (
if (char_avail())
return;
- /* Trigger CursorMoved if the cursor moved. Not when the popup menu is
- * visible, the command might delete it. */
- if (ready && (
- has_cursormovedI()
- ||
- curwin->w_p_cole > 0
- )
+ // Trigger CursorMoved if the cursor moved. Not when the popup menu is
+ // visible, the command might delete it.
+ if (ready && (has_event(EVENT_CURSORMOVEDI) || curwin->w_p_cole > 0)
&& !equalpos(last_cursormoved, curwin->w_cursor)
- && !pum_visible()
- ) {
- /* Need to update the screen first, to make sure syntax
- * highlighting is correct after making a change (e.g., inserting
- * a "(". The autocommand may also require a redraw, so it's done
- * again below, unfortunately. */
- if (syntax_present(curwin) && must_redraw)
+ && !pum_visible()) {
+ // Need to update the screen first, to make sure syntax
+ // highlighting is correct after making a change (e.g., inserting
+ // a "(". The autocommand may also require a redraw, so it's done
+ // again below, unfortunately.
+ if (syntax_present(curwin) && must_redraw) {
update_screen(0);
- if (has_cursormovedI())
- apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf);
+ }
+ if (has_event(EVENT_CURSORMOVEDI)) {
+ apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, false, curbuf);
+ }
if (curwin->w_p_cole > 0) {
conceal_old_cursor_line = last_cursormoved.lnum;
conceal_new_cursor_line = curwin->w_cursor.lnum;
@@ -1378,13 +1375,13 @@ ins_redraw (
last_cursormoved = curwin->w_cursor;
}
- /* Trigger TextChangedI if b_changedtick differs. */
- if (ready && has_textchangedI()
+ // Trigger TextChangedI if b_changedtick differs.
+ if (ready && has_event(EVENT_TEXTCHANGEDI)
&& last_changedtick != curbuf->b_changedtick
- && !pum_visible()
- ) {
- if (last_changedtick_buf == curbuf)
- apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
+ && !pum_visible()) {
+ if (last_changedtick_buf == curbuf) {
+ apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf);
+ }
last_changedtick_buf = curbuf;
last_changedtick = curbuf->b_changedtick;
}
@@ -5124,24 +5121,20 @@ insertchar (
can_si = FALSE;
can_si_back = FALSE;
- /*
- * If there's any pending input, grab up to INPUT_BUFLEN at once.
- * This speeds up normal text input considerably.
- * Don't do this when 'cindent' or 'indentexpr' is set, because we might
- * need to re-indent at a ':', or any other character (but not what
- * 'paste' is set)..
- * Don't do this when there an InsertCharPre autocommand is defined,
- * because we need to fire the event for every character.
- */
-
- if ( !ISSPECIAL(c)
- && (!has_mbyte || (*mb_char2len)(c) == 1)
- && vpeekc() != NUL
- && !(State & REPLACE_FLAG)
- && !cindent_on()
- && !p_ri
- && !has_insertcharpre()
- ) {
+ // If there's any pending input, grab up to INPUT_BUFLEN at once.
+ // This speeds up normal text input considerably.
+ // Don't do this when 'cindent' or 'indentexpr' is set, because we might
+ // need to re-indent at a ':', or any other character (but not what
+ // 'paste' is set)..
+ // Don't do this when there an InsertCharPre autocommand is defined,
+ // because we need to fire the event for every character.
+ if (!ISSPECIAL(c)
+ && (!has_mbyte || (*mb_char2len)(c) == 1)
+ && vpeekc() != NUL
+ && !(State & REPLACE_FLAG)
+ && !cindent_on()
+ && !p_ri
+ && !has_event(EVENT_INSERTCHARPRE)) {
#define INPUT_BUFLEN 100
char_u buf[INPUT_BUFLEN + 1];
int i;
@@ -8486,13 +8479,13 @@ static char_u *do_insert_char_pre(int c)
{
char_u buf[MB_MAXBYTES + 1];
- /* Return quickly when there is nothing to do. */
- if (!has_insertcharpre())
+ // Return quickly when there is nothing to do.
+ if (!has_event(EVENT_INSERTCHARPRE)) {
return NULL;
-
- if (has_mbyte)
+ }
+ if (has_mbyte) {
buf[(*mb_char2bytes)(c, buf)] = NUL;
- else {
+ } else {
buf[0] = c;
buf[1] = NUL;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index fad497928c..84bd31d9ad 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1694,7 +1694,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
// autocommands defined, trigger the matching autocommands.
if (p != NULL && ea.cmdidx == CMD_SIZE && !ea.skip
&& ASCII_ISUPPER(*ea.cmd)
- && has_cmdundefined()) {
+ && has_event(EVENT_CMDUNDEFINED)) {
p = ea.cmd;
while (ASCII_ISALNUM(*p)) {
++p;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 05cb8f8f8c..bd0f0fc80a 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -6266,50 +6266,12 @@ int trigger_cursorhold(void)
return FALSE;
}
-/*
- * Return TRUE when there is a CursorMoved autocommand defined.
- */
-int has_cursormoved(void)
-{
- return first_autopat[(int)EVENT_CURSORMOVED] != NULL;
-}
-
-/*
- * Return TRUE when there is a CursorMovedI autocommand defined.
- */
-int has_cursormovedI(void)
-{
- return first_autopat[(int)EVENT_CURSORMOVEDI] != NULL;
-}
-
-/*
- * Return TRUE when there is a TextChanged autocommand defined.
- */
-int has_textchanged(void)
-{
- return first_autopat[(int)EVENT_TEXTCHANGED] != NULL;
-}
-
-/*
- * Return TRUE when there is a TextChangedI autocommand defined.
- */
-int has_textchangedI(void)
-{
- return first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL;
-}
-
-/*
- * Return TRUE when there is an InsertCharPre autocommand defined.
- */
-int has_insertcharpre(void)
-{
- return first_autopat[(int)EVENT_INSERTCHARPRE] != NULL;
-}
-
-/// @returns true when there is an CmdUndefined autocommand defined.
-int has_cmdundefined(void)
+/// Return true if "event" autocommand is defined.
+///
+/// @param event the autocommand to check
+bool has_event(int event) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return first_autopat[(int)EVENT_CMDUNDEFINED] != NULL;
+ return first_autopat[event] != NULL;
}
static int
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 04d6cbf5e3..b2fd929714 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -18,6 +18,9 @@
#include "nvim/strings.h"
#include "nvim/mouse.h"
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "keymap.c.generated.h"
+#endif
/*
* Some useful tables.
@@ -637,11 +640,11 @@ find_special_key (
key = DEL;
}
- /*
- * Normal Key with modifier: Try to make a single byte code.
- */
- if (!IS_SPECIAL(key))
+ // Normal Key with modifier:
+ // Try to make a single byte code (except for Alt/Meta modifiers).
+ if (!IS_SPECIAL(key)) {
key = extract_modifiers(key, &modifiers);
+ }
*modp = modifiers;
*srcp = end_of_name;
@@ -652,11 +655,9 @@ find_special_key (
return 0;
}
-/*
- * Try to include modifiers in the key.
- * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
- */
-int extract_modifiers(int key, int *modp)
+/// Try to include modifiers (except alt/meta) in the key.
+/// Changes "Shift-a" to 'A', "Ctrl-@" to <Nul>, etc.
+static int extract_modifiers(int key, int *modp)
{
int modifiers = *modp;
@@ -665,19 +666,12 @@ int extract_modifiers(int key, int *modp)
modifiers &= ~MOD_MASK_SHIFT;
}
if ((modifiers & MOD_MASK_CTRL)
- && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
- ) {
+ && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))) {
key = Ctrl_chr(key);
modifiers &= ~MOD_MASK_CTRL;
- /* <C-@> is <Nul> */
- if (key == 0)
+ if (key == 0) { // <C-@> is <Nul>
key = K_ZERO;
- }
- if ((modifiers & MOD_MASK_ALT) && key < 0x80
- && !enc_dbcs /* avoid creating a lead byte */
- ) {
- key |= 0x80;
- modifiers &= ~MOD_MASK_ALT; /* remove the META modifier */
+ }
}
*modp = modifiers;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index d4bf1c2e90..2f57d8c610 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1205,9 +1205,9 @@ static void normal_check_interrupt(NormalState *s)
static void normal_check_cursor_moved(NormalState *s)
{
// Trigger CursorMoved if the cursor moved.
- if (!finish_op && (has_cursormoved() || curwin->w_p_cole > 0)
+ if (!finish_op && (has_event(EVENT_CURSORMOVED) || curwin->w_p_cole > 0)
&& !equalpos(last_cursormoved, curwin->w_cursor)) {
- if (has_cursormoved()) {
+ if (has_event(EVENT_CURSORMOVED)) {
apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf);
}
@@ -1224,7 +1224,7 @@ static void normal_check_cursor_moved(NormalState *s)
static void normal_check_text_changed(NormalState *s)
{
// Trigger TextChanged if b_changedtick differs.
- if (!finish_op && has_textchanged()
+ if (!finish_op && has_event(EVENT_TEXTCHANGED)
&& last_changedtick != curbuf->b_changedtick) {
if (last_changedtick_buf == curbuf) {
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL, false, curbuf);
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 1a4c3495f2..21f0fc6f41 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -151,7 +151,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
// Walk through all entries in $PATH to check if "name" exists there and
// is an executable file.
for (;; ) {
- const char *e = xstrchrnul(path, ':');
+ const char *e = xstrchrnul(path, ENV_SEPCHAR);
// Glue together the given directory from $PATH with name and save into
// buf.
@@ -169,7 +169,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
return true;
}
- if (*e != ':') {
+ if (*e != ENV_SEPCHAR) {
// End of $PATH without finding any executable called name.
xfree(buf);
return false;
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index 79d14920eb..8afbd29292 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -13,24 +13,7 @@
# include "nvim/os/unix_defs.h"
#endif
-#if defined(DIRSIZ) && !defined(MAXNAMLEN)
-# define MAXNAMLEN DIRSIZ
-#endif
-
-#if defined(UFS_MAXNAMLEN) && !defined(MAXNAMLEN)
-# define MAXNAMLEN UFS_MAXNAMLEN /* for dynix/ptx */
-#endif
-
-#if defined(NAME_MAX) && !defined(MAXNAMLEN)
-# define MAXNAMLEN NAME_MAX /* for Linux before .99p3 */
-#endif
-
-// Default value.
-#ifndef MAXNAMLEN
-# define MAXNAMLEN 512
-#endif
-
-#define BASENAMELEN (MAXNAMLEN - 5)
+#define BASENAMELEN (NAME_MAX - 5)
// Use the system path length if it makes sense.
#if defined(PATH_MAX) && (PATH_MAX > 1000)
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 3813c45726..f5a1637c94 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -36,7 +36,6 @@ typedef struct {
# include "os/shell.c.generated.h"
#endif
-
/// Builds the argument vector for running the user-configured 'shell' (p_sh)
/// with an optional command prefixed by 'shellcmdflag' (p_shcf).
///
@@ -45,9 +44,10 @@ typedef struct {
/// @return A newly allocated argument vector. It must be freed with
/// `shell_free_argv` when no longer needed.
char **shell_build_argv(const char *cmd, const char *extra_args)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
{
- size_t argc = tokenize(p_sh, NULL) + tokenize(p_shcf, NULL);
- char **rv = xmalloc((unsigned)((argc + 4) * sizeof(char *)));
+ size_t argc = tokenize(p_sh, NULL) + (cmd ? tokenize(p_shcf, NULL) : 0);
+ char **rv = xmalloc((argc + 4) * sizeof(*rv));
// Split 'shell'
size_t i = tokenize(p_sh, rv);
@@ -338,24 +338,22 @@ static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data,
/// @param argv The vector that will be filled with copies of the parsed
/// words. It can be NULL if the caller only needs to count words.
/// @return The number of words parsed.
-static size_t tokenize(const char_u *str, char **argv)
+static size_t tokenize(const char_u *const str, char **const argv)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- size_t argc = 0, len;
- char_u *p = (char_u *) str;
+ size_t argc = 0;
+ const char *p = (const char *) str;
while (*p != NUL) {
- len = word_length(p);
+ const size_t len = word_length((const char_u *) p);
if (argv != NULL) {
// Fill the slot
- argv[argc] = xmalloc(len + 1);
- memcpy(argv[argc], p, len);
- argv[argc][len] = NUL;
+ argv[argc] = vim_strnsave_unquoted(p, len);
}
argc++;
- p += len;
- p = skipwhite(p);
+ p = (const char *) skipwhite((char_u *) (p + len));
}
return argc;
@@ -377,6 +375,9 @@ static size_t word_length(const char_u *str)
if (*p == '"') {
// Found a quote character, switch the `inquote` flag
inquote = !inquote;
+ } else if (*p == '\\' && inquote) {
+ p++;
+ length++;
}
p++;
diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h
index e3ba3262f4..78fc9331d1 100644
--- a/src/nvim/os/unix_defs.h
+++ b/src/nvim/os/unix_defs.h
@@ -1,13 +1,12 @@
#ifndef NVIM_OS_UNIX_DEFS_H
#define NVIM_OS_UNIX_DEFS_H
+// Windows doesn't have unistd.h, so we include it here to avoid numerous
+// instances of `#ifdef HAVE_UNISTD_H'.
#include <unistd.h>
-#include <signal.h>
-// Defines BSD, if it's a BSD system.
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
+// POSIX.1-2008 says that NAME_MAX should be in here
+#include <limits.h>
#define TEMP_DIR_NAMES {"$TMPDIR", "/tmp", ".", "~"}
#define TEMP_FILE_PATH_MAXLEN 256
@@ -17,4 +16,7 @@
// Special wildcards that need to be handled by the shell.
#define SPECIAL_WILDCHAR "`'{"
+// Separator character for environment variables.
+#define ENV_SEPCHAR ':'
+
#endif // NVIM_OS_UNIX_DEFS_H
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index 9f9e5e277c..e6a714601f 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -5,11 +5,16 @@
#include <sys/stat.h>
#include <stdio.h>
+#define NAME_MAX _MAX_PATH
+
#define TEMP_DIR_NAMES {"$TMP", "$TEMP", "$USERPROFILE", ""}
#define TEMP_FILE_PATH_MAXLEN _MAX_PATH
#define FNAME_ILLEGAL "\"*?><|"
+// Separator character for environment variables.
+#define ENV_SEPCHAR ';'
+
#define USE_CRNL
#ifdef _MSC_VER
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 62b264046c..6c7cb3bba7 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -44,10 +44,6 @@
#include "nvim/os/signal.h"
#include "nvim/msgpack_rpc/helpers.h"
-#ifdef HAVE_STROPTS_H
-# include <stropts.h>
-#endif
-
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
static int selinux_enabled = -1;
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 00dcf3cf46..fe91141375 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -119,6 +119,54 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars,
return escaped_string;
}
+/// Save a copy of an unquoted string
+///
+/// Turns string like `a\bc"def\"ghi\\\n"jkl` into `a\bcdef"ghi\\njkl`, for use
+/// in shell_build_argv: the only purpose of backslash is making next character
+/// be treated literally inside the double quotes, if this character is
+/// backslash or quote.
+///
+/// @param[in] string String to copy.
+/// @param[in] length Length of the string to copy.
+///
+/// @return [allocated] Copy of the string.
+char *vim_strnsave_unquoted(const char *const string, const size_t length)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
+{
+#define ESCAPE_COND(p, inquote, string_end) \
+ (*p == '\\' && inquote && p + 1 < string_end && (p[1] == '\\' || p[1] == '"'))
+ size_t ret_length = 0;
+ bool inquote = false;
+ const char *const string_end = string + length;
+ for (const char *p = string; p < string_end; p++) {
+ if (*p == '"') {
+ inquote = !inquote;
+ } else if (ESCAPE_COND(p, inquote, string_end)) {
+ ret_length++;
+ p++;
+ } else {
+ ret_length++;
+ }
+ }
+
+ char *const ret = xmallocz(ret_length);
+ char *rp = ret;
+ inquote = false;
+ for (const char *p = string; p < string_end; p++) {
+ if (*p == '"') {
+ inquote = !inquote;
+ } else if (ESCAPE_COND(p, inquote, string_end)) {
+ *rp++ = *(++p);
+ } else {
+ *rp++ = *p;
+ }
+ }
+#undef ESCAPE_COND
+
+ return ret;
+}
+
/*
* Escape "string" for use as a shell argument with system().
* This uses single quotes, except when we know we need to use double quotes
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index adf3f725a2..6045acd1cb 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1,5 +1,5 @@
-// VT220/xterm-like terminal emulator implementation for Neovim. Powered by
-// libvterm(http://www.leonerd.org.uk/code/libvterm/).
+// VT220/xterm-like terminal emulator implementation for nvim. Powered by
+// libvterm (http://www.leonerd.org.uk/code/libvterm/).
//
// libvterm is a pure C99 terminal emulation library with abstract input and
// display. This means that the library needs to read data from the master fd
@@ -10,31 +10,31 @@
// vterm_keyboard_key/vterm_keyboard_unichar, which generates byte streams that
// must be fed back to the master fd.
//
-// This implementation uses Neovim buffers as the display mechanism for both
+// This implementation uses nvim buffers as the display mechanism for both
// the visible screen and the scrollback buffer. When focused, the window
// "pins" to the bottom of the buffer and mirrors libvterm screen state.
//
// When a line becomes invisible due to a decrease in screen height or because
// a line was pushed up during normal terminal output, we store the line
-// information in the scrollback buffer, which is mirrored in the Neovim buffer
+// information in the scrollback buffer, which is mirrored in the nvim buffer
// by appending lines just above the visible part of the buffer.
//
// When the screen height increases, libvterm will ask for a row in the
-// scrollback buffer, which is mirrored in the Neovim buffer displaying lines
+// scrollback buffer, which is mirrored in the nvim buffer displaying lines
// that were previously invisible.
//
-// The vterm->Neovim synchronization is performed in intervals of 10
+// The vterm->nvim synchronization is performed in intervals of 10
// milliseconds. This is done to minimize screen updates when receiving large
// bursts of data.
//
// This module is decoupled from the processes that normally feed it data, so
-// it's possible to use it as a general purpose console buffer(possibly as a
-// log/display mechanism for Neovim in the future)
+// it's possible to use it as a general purpose console buffer (possibly as a
+// log/display mechanism for nvim in the future)
//
-// Inspired by vimshell(http://www.wana.at/vimshell/) and
-// Conque(https://code.google.com/p/conque/). Libvterm usage instructions (plus
+// Inspired by vimshell (http://www.wana.at/vimshell/) and
+// Conque (https://code.google.com/p/conque/). Libvterm usage instructions (plus
// some extra code) were taken from
-// pangoterm(http://www.leonerd.org.uk/code/pangoterm/)
+// pangoterm (http://www.leonerd.org.uk/code/pangoterm/)
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
@@ -402,11 +402,11 @@ static int terminal_execute(VimState *state, int key)
TerminalState *s = (TerminalState *)state;
switch (key) {
- case K_FOCUSGAINED: // Neovim has been given focus
+ case K_FOCUSGAINED: // nvim has been given focus
apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
break;
- case K_FOCUSLOST: // Neovim has lost focus
+ case K_FOCUSLOST: // nvim has lost focus
apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
break;