aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt75
-rw-r--r--cmake/FindIconv.cmake18
-rw-r--r--cmake/GetCompileFlags.cmake58
-rw-r--r--cmake/InstallHelpers.cmake4
-rw-r--r--config/CMakeLists.txt7
-rw-r--r--config/config.h.in3
-rw-r--r--neovim.rb45
-rw-r--r--runtime/doc/nvim_clipboard.txt10
-rwxr-xr-xscripts/legacy2luatest.pl180
-rw-r--r--src/nvim/CMakeLists.txt8
-rw-r--r--src/nvim/cursor_shape.c2
-rw-r--r--src/nvim/edit.c22
-rw-r--r--src/nvim/eval.c5
-rw-r--r--src/nvim/ex_cmds.c21
-rw-r--r--src/nvim/ex_cmds2.c16
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/ex_eval.c3
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/fileio.c7
-rw-r--r--src/nvim/fold.c8
-rw-r--r--src/nvim/hardcopy.c4
-rw-r--r--src/nvim/memory.c35
-rw-r--r--src/nvim/message.c9
-rw-r--r--src/nvim/msgpack_rpc/channel.c2
-rw-r--r--src/nvim/ops.c17
-rw-r--r--src/nvim/os/job.c4
-rw-r--r--src/nvim/os/shell.c9
-rw-r--r--src/nvim/os/wstream.c6
-rw-r--r--src/nvim/po/CMakeLists.txt8
-rw-r--r--src/nvim/regexp.c30
-rw-r--r--src/nvim/screen.c34
-rw-r--r--src/nvim/version.c8
-rw-r--r--src/nvim/version_defs.h12
-rw-r--r--test/functional/helpers.lua10
-rw-r--r--test/functional/shell/viml_system_spec.lua32
35 files changed, 442 insertions, 278 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d67aebee64..9482e6d8a4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.8.7)
project (NEOVIM)
# Point CMake at any custom modules we may ship
-set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
+list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
# Prefer our bundled versions of dependencies.
set(DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.deps")
@@ -12,6 +12,37 @@ set(DEPS_BIN_DIR "${DEPS_INSTALL_DIR}/bin")
list(APPEND CMAKE_PREFIX_PATH ${DEPS_INSTALL_DIR})
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ # CMake tries to treat /sw and /opt/local as extension of the system path, but
+ # that doesn't really work out very well. Once you have a dependency that
+ # resides there and have to add it as an include directory, then any other
+ # dependency that could be satisfied from there must be--otherwise you can end
+ # up with conflicting versions. So, let's make them more of a priority having
+ # them be included as one of the first places to look for dependencies.
+ list(APPEND CMAKE_PREFIX_PATH /sw /opt/local)
+
+ # Work around some old, broken detection by CMake for knowing when to use the
+ # isystem flag. Apple's compilers have supported this for quite some time
+ # now.
+ if(CMAKE_COMPILER_IS_GNUCC)
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
+ endif()
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
+ endif()
+endif()
+
+# Set available build types for CMake GUIs.
+# A different build type can still be set by -DCMAKE_BUILD_TYPE=...
+set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
+ STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
+
+# Set default build type.
+if(NOT CMAKE_BUILD_TYPE)
+ message(STATUS "CMAKE_BUILD_TYPE not given; setting to 'RelWithDebInfo'.")
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build." FORCE)
+endif()
+
# Version tokens
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC NVIM_VERSION_COMMIT)
@@ -28,20 +59,11 @@ git_timestamp(GIT_TIMESTAMP)
if(GIT_TIMESTAMP)
set(NVIM_VERSION_BUILD "+${GIT_TIMESTAMP}")
endif()
+set(NVIM_VERSION_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
+# NVIM_VERSION_CFLAGS set further below.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-# Work around some old, broken detection by CMake for knowing when to use the
-# isystem flag. Apple's compilers have supported this for quite some time now.
-if(APPLE)
- if(CMAKE_COMPILER_IS_GNUCC)
- set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
- endif()
- if(CMAKE_COMPILER_IS_GNUCXX)
- set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
- endif()
-endif()
-
# Default to -O2 on release builds.
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
@@ -67,9 +89,16 @@ if(TRAVIS_CI_BUILD)
add_definitions(-Werror)
endif()
+if(CMAKE_COMPILER_IS_GNUCC)
+ include(CheckCCompilerFlag)
+ check_c_compiler_flag(-Og HAS_OG_FLAG)
+else()
+ set(HAS_OG_FLAG 0)
+endif()
+
# Set custom build flags for RelWithDebInfo.
# -DNDEBUG purposely omitted because we want assertions.
-if(CMAKE_COMPILER_IS_GNUCC)
+if(HAS_OG_FLAG)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Og -g"
CACHE STRING "Flags used by the compiler during release builds with debug info." FORCE)
else()
@@ -128,7 +157,12 @@ include_directories(SYSTEM ${LUAJIT_INCLUDE_DIRS})
find_package(LibIntl)
if(LibIntl_FOUND)
- include_directories(SYSTEM ${LibIntl_INCLUDE_DIR})
+ include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS})
+endif()
+
+find_package(Iconv)
+if(Iconv_FOUND)
+ include_directories(SYSTEM ${Iconv_INCLUDE_DIRS})
endif()
# Determine platform's threading library. Set CMAKE_THREAD_PREFER_PTHREAD
@@ -215,7 +249,7 @@ foreach(PROG ${RUNTIME_PROGRAMS})
install_helper(PROGRAMS ${PROG} DESTINATION share/nvim/${BASEDIR})
endforeach()
-install(SCRIPT ${CMAKE_MODULE_PATH}/GenerateHelptags.cmake)
+install(SCRIPT ${PROJECT_SOURCE_DIR}/cmake/GenerateHelptags.cmake)
# Unfortunately, the below does not work under Ninja. Ninja doesn't use a
# pseudo-tty when launching processes, because it can put many jobs in parallel
@@ -228,9 +262,14 @@ install(SCRIPT ${CMAKE_MODULE_PATH}/GenerateHelptags.cmake)
# Go down the tree.
-add_subdirectory(config)
add_subdirectory(src/nvim)
+# Read compilation flags from src/nvim,
+# used in config subdirectory below.
+include(GetCompileFlags)
+get_compile_flags(NVIM_VERSION_CFLAGS)
+
add_subdirectory(test/includes)
+add_subdirectory(config)
# Setup some test-related bits. We do this after going down the tree because we
# need some of the targets.
@@ -258,7 +297,7 @@ if(BUSTED_PRG)
-DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
-DBUILD_DIR=${CMAKE_BINARY_DIR}
-DTEST_TYPE=unit
- -P ${CMAKE_MODULE_PATH}/RunTests.cmake
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
DEPENDS nvim-test unittest-headers)
add_custom_target(functionaltest
@@ -270,6 +309,6 @@ if(BUSTED_PRG)
-DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
-DBUILD_DIR=${CMAKE_BINARY_DIR}
-DTEST_TYPE=functional
- -P ${CMAKE_MODULE_PATH}/RunTests.cmake
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
DEPENDS nvim)
endif()
diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake
new file mode 100644
index 0000000000..f3a54e9d6f
--- /dev/null
+++ b/cmake/FindIconv.cmake
@@ -0,0 +1,18 @@
+# - Try to find iconv
+# Once done, this will define
+#
+# Iconv_FOUND - system has iconv
+# Iconv_INCLUDE_DIRS - the iconv include directories
+# Iconv_LIBRARIES - link these to use iconv
+
+include(LibFindMacros)
+
+find_path(ICONV_INCLUDE_DIR NAMES iconv.h)
+find_library(ICONV_LIBRARY NAMES iconv)
+
+set(Iconv_PROCESS_INCLUDES ICONV_INCLUDE_DIR)
+if(ICONV_LIBRARY)
+ set(Iconv_PROCESS_LIBS ICONV_LIBRARY)
+endif()
+
+libfind_process(Iconv)
diff --git a/cmake/GetCompileFlags.cmake b/cmake/GetCompileFlags.cmake
new file mode 100644
index 0000000000..e0994b67bc
--- /dev/null
+++ b/cmake/GetCompileFlags.cmake
@@ -0,0 +1,58 @@
+function(get_compile_flags _compile_flags)
+ # Create template akin to CMAKE_C_COMPILE_OBJECT.
+ set(compile_flags "<CMAKE_C_COMPILER> <CFLAGS> <BUILD_TYPE_CFLAGS> <DEFINITIONS> <INCLUDES>")
+
+ # Get C compiler.
+ string(REPLACE
+ "<CMAKE_C_COMPILER>"
+ "${CMAKE_C_COMPILER}"
+ compile_flags
+ "${compile_flags}")
+
+ # Get flags set by add_definition().
+ get_directory_property(definitions
+ DIRECTORY "src/nvim"
+ DEFINITIONS)
+ string(REPLACE
+ "<DEFINITIONS>"
+ "${definitions}"
+ compile_flags
+ "${compile_flags}")
+
+ # Get general C flags.
+ string(REPLACE
+ "<CFLAGS>"
+ "${CMAKE_C_FLAGS}"
+ compile_flags
+ "${compile_flags}")
+
+ # Get C flags specific to build type.
+ string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
+ string(REPLACE
+ "<BUILD_TYPE_CFLAGS>"
+ "${CMAKE_C_FLAGS_${build_type}}"
+ compile_flags
+ "${compile_flags}")
+
+ # Get include directories.
+ get_directory_property(include_directories_list
+ DIRECTORY "src/nvim"
+ INCLUDE_DIRECTORIES)
+ foreach(include_directory ${include_directories_list})
+ set(include_directories "${include_directories} -I${include_directory}")
+ endforeach()
+ string(REPLACE
+ "<INCLUDES>"
+ "${include_directories}"
+ compile_flags
+ "${compile_flags}")
+
+ # Clean duplicate whitespace.
+ string(REPLACE
+ " "
+ " "
+ compile_flags
+ "${compile_flags}")
+
+ set(${_compile_flags} "${compile_flags}" PARENT_SCOPE)
+endfunction()
diff --git a/cmake/InstallHelpers.cmake b/cmake/InstallHelpers.cmake
index 763b2a092c..bd03ae3875 100644
--- a/cmake/InstallHelpers.cmake
+++ b/cmake/InstallHelpers.cmake
@@ -22,10 +22,6 @@ function(create_install_dir_with_perms)
install(CODE
"
- if(DEFINED ENV{DESTDIR} AND NOT IS_ABSOLUTE \${CMAKE_INSTALL_PREFIX})
- message(FATAL_ERROR \"Install prefix must be absolute when using DESTDIR\")
- endif()
-
set(_current_dir \"\${CMAKE_INSTALL_PREFIX}/${_install_dir_DESTINATION}\")
set(_dir_permissions \"${_install_dir_DIRECTORY_PERMISSIONS}\")
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt
index c48887548d..0f5dd7d984 100644
--- a/config/CMakeLists.txt
+++ b/config/CMakeLists.txt
@@ -44,12 +44,9 @@ check_function_exists(getpwent HAVE_GETPWENT)
check_function_exists(getpwnam HAVE_GETPWNAM)
check_function_exists(getpwuid HAVE_GETPWUID)
-check_include_files(iconv.h HAVE_ICONV_H)
-check_library_exists(iconv iconv "" HAVE_ICONV_LIB)
-if(HAVE_ICONV_LIB)
- set(CMAKE_REQUIRED_LIBRARIES iconv)
+if(Iconv_FOUND)
+ set(HAVE_ICONV 1)
endif()
-check_function_exists(iconv HAVE_ICONV)
check_function_exists(lstat HAVE_LSTAT)
if(NOT HAVE_LSTAT)
diff --git a/config/config.h.in b/config/config.h.in
index 7a04837c92..79dabc61e4 100644
--- a/config/config.h.in
+++ b/config/config.h.in
@@ -4,6 +4,8 @@
#define NVIM_VERSION_PRERELEASE "@NVIM_VERSION_PRERELEASE@"
#define NVIM_VERSION_BUILD "@NVIM_VERSION_BUILD@"
#define NVIM_VERSION_COMMIT "@NVIM_VERSION_COMMIT@"
+#define NVIM_VERSION_CFLAGS "@NVIM_VERSION_CFLAGS@"
+#define NVIM_VERSION_BUILD_TYPE "@NVIM_VERSION_BUILD_TYPE@"
#cmakedefine DEBUG
@@ -29,7 +31,6 @@
#cmakedefine HAVE_GETPWNAM
#cmakedefine HAVE_GETPWUID
#cmakedefine HAVE_ICONV
-#cmakedefine USE_ICONV
#cmakedefine HAVE_ICONV_H
#cmakedefine HAVE_LANGINFO_H
#cmakedefine HAVE_LIBGEN_H
diff --git a/neovim.rb b/neovim.rb
index 876a69f952..859ebdf39d 100644
--- a/neovim.rb
+++ b/neovim.rb
@@ -1,42 +1,9 @@
-require "formula"
+odie <<-EOS.undent
-class Neovim < Formula
- homepage "http://neovim.org"
- head "https://github.com/neovim/neovim.git"
+ Whoops, the neovim Homebrew Formula has moved! Please instead run:
- depends_on "cmake" => :build
- depends_on "libtool" => :build
- depends_on "automake" => :build
- depends_on "autoconf" => :build
+ brew tap neovim/homebrew-neovim
+ brew install --HEAD neovim
- resource "libuv" do
- url "https://github.com/joyent/libuv/archive/v0.11.28.tar.gz"
- sha1 "3b70b65467ee693228b8b8385665a52690d74092"
- end
-
- resource "msgpack" do
- url "https://github.com/msgpack/msgpack-c/archive/ecf4b09acd29746829b6a02939db91dfdec635b4.tar.gz"
- sha1 "c160ff99f20d9d0a25bea0a57f4452f1c9bde370"
- end
-
- resource "luajit" do
- url "http://luajit.org/download/LuaJIT-2.0.3.tar.gz"
- sha1 "2db39e7d1264918c2266b0436c313fbd12da4ceb"
- end
-
- resource "luarocks" do
- url "https://github.com/keplerproject/luarocks/archive/0587afbb5fe8ceb2f2eea16f486bd6183bf02f29.tar.gz"
- sha1 "61a894fd5d61987bf7e7f9c3e0c5de16ba4b68c4"
- end
-
- def install
- ENV["GIT_DIR"] = cached_download/".git" if build.head?
- ENV.deparallelize
-
- resources.each do |r|
- r.stage(target=buildpath/".deps/build/src/#{r.name}")
- end
-
- system "make", "CMAKE_BUILD_TYPE=RelWithDebInfo", "CMAKE_EXTRA_FLAGS=\"-DCMAKE_INSTALL_PREFIX:PATH=#{prefix}\"", "install"
- end
-end
+ Thanks!
+EOS
diff --git a/runtime/doc/nvim_clipboard.txt b/runtime/doc/nvim_clipboard.txt
index 3dd5fb5fcb..74c9254c70 100644
--- a/runtime/doc/nvim_clipboard.txt
+++ b/runtime/doc/nvim_clipboard.txt
@@ -12,24 +12,24 @@ will be implemented by UI programs, which connect to Nvim via |msgpack-rpc|.
Even though externalized UIs are not available yet, there's a workaround that
enables clipboard usage through the python interface(which also uses
|msgpack-rpc| and consequently can implement the clipboard methods required
-by Nvim):
+by Nvim):
- Make sure you follow the setup instructions in |nvim-python-quickstart|.
- Install the `xerox` python module:
>
$ pip install xerox
<
-- Create a ~/.vim/pythonx/nvim_clipboard.py file with the following contents:
+- Create a ~/.nvim/pythonx/nvim_clipboard.py file with the following contents:
>
import xerox
-
+
class NvimClipboard(object):
def __init__(self, vim):
self.provides = ['clipboard']
-
+
def clipboard_get(self):
return xerox.paste().split('\n')
-
+
def clipboard_set(self, lines):
xerox.copy(u'\n'.join([line.decode('utf-8') for line in lines]))
<
diff --git a/scripts/legacy2luatest.pl b/scripts/legacy2luatest.pl
index 0628ac0a1d..5979afa788 100755
--- a/scripts/legacy2luatest.pl
+++ b/scripts/legacy2luatest.pl
@@ -33,7 +33,52 @@ sub read_in_file {
use constant EMIT_DESCRIPTION => 0;
use constant EMIT_COMMAND => 1;
use constant EMIT_INPUT => 2;
- use constant END_INPUT => 3;
+
+ # Push lines from current input and
+ # command blocks into @test_body_lines
+ # in the correct order.
+ sub end_input {
+ my $input_lines = $_[0];
+ my $command_lines = $_[1];
+ my $test_body_lines = $_[2];
+
+ # Only keep first input line if it is not empty.
+ my $first_input_line = shift @{$input_lines};
+ if ($first_input_line =~ /^$/) {
+ unshift @{$input_lines}, $first_input_line;
+ }
+
+ # If there are input lines left, wrap them with
+ # `insert` command and add before the previous command
+ # block.
+ if (@{$input_lines}) {
+ my $last_input_line = pop @{$input_lines};
+ unshift @{$command_lines}, '';
+ unshift @{$command_lines}, $last_input_line . ']])';
+ unshift @{$command_lines}, @{$input_lines};
+ unshift @{$command_lines}, "insert([[";
+
+ push @{$test_body_lines}, @{$command_lines};
+
+ @{$command_lines} = ();
+ @{$input_lines} = ();
+ }
+ }
+
+ sub format_comment {
+ # Handle empty comments.
+ if (/^$/) {
+ return '';
+ }
+
+ # Capitalize first character and emit as Lua comment.
+ my $comment = '-- ' . ucfirst $_;
+
+ # Add trailing dot if not already there.
+ $comment .= '.' unless $comment =~ /\.$/;
+
+ return $comment;
+ }
my %states = (
# Add test description to @description_lines.
@@ -57,56 +102,52 @@ sub read_in_file {
# If line starts with ':"', emit a comment.
if (/^:"/) {
- # If it's an empty comment, just add an empty line
- # to improve readability.
- push @command_lines, (/^$/ ? '' : '-- ' . $_);
- } else {
- # Extract possible inline comment.
- if (/^[^"]*"[^"]*$/) {
- # Remove command part and prepended whitespace.
- s/^(.*?)\s*"\s*//;
-
- # Capitalize first character and emit as Lua comment.
- my $comment = '-- ' . ucfirst $_;
-
- # Add trailing dot if not already there.
- $comment .= '.' unless $comment =~ /\.$/;
-
- push @command_lines, '';
- push @command_lines, $comment;
-
- # Set implicit variable to command without comment.
- $_ = $1;
+ # Remove Vim comment prefix.
+ s/^:"\s*//;
+
+ push @command_lines, format_comment $_;
+
+ return EMIT_COMMAND;
+ }
+
+ # Extract possible inline comment.
+ if (/^[^"]*"[^"]*$/) {
+ # Remove command part and prepended whitespace.
+ s/^(.*?)\s*"\s*//;
+
+ push @command_lines, format_comment $_;
+
+ # Set implicit variable to command without comment.
+ $_ = $1;
+ }
+
+ # Only continue if remaining command is not empty.
+ if (!/^:?\s*$/) {
+ # Replace terminal escape characters with <esc>.
+ s/\e/<esc>/g;
+
+ my $startstr = "'";
+ my $endstr = "'";
+
+ # If line contains single quotes or backslashes, use double
+ # square brackets to wrap string.
+ if (/'/ || /\\/) {
+ $startstr = '[[';
+ $endstr = ']]';
}
- # Only continue if remaining command is not empty.
- if (!/^:?\s*$/) {
- # Replace terminal escape characters with <esc>.
- s/\e/<esc>/g;
-
- my $startstr = "'";
- my $endstr = "'";
-
- # If line contains single quotes or backslashes, use double
- # square brackets to wrap string.
- if (/'/ || /\\/) {
- $startstr = '[[';
- $endstr = ']]';
- }
-
- # Emit 'feed' if not a search ('/') or ex (':') command.
- if (!/^\// && !/^:/) {
- # If command does not end with <esc>, insert trailing <cr>.
- my $command = 'feed(' . $startstr . $_;
- $command .= '<cr>' unless /<esc>$/;
- $command .= $endstr . ')';
-
- push @command_lines, $command;
- } else {
- # Remove prepending ':'.
- s/^://;
- push @command_lines, 'execute(' . $startstr . $_ . $endstr . ')';
- }
+ # Emit 'feed' if not a search ('/') or ex (':') command.
+ if (!/^\// && !/^:/) {
+ # If command does not end with <esc>, insert trailing <cr>.
+ my $command = 'feed(' . $startstr . $_;
+ $command .= '<cr>' unless /<esc>$/;
+ $command .= $endstr . ')';
+
+ push @command_lines, $command;
+ } else {
+ # Remove prepending ':'.
+ s/^://;
+ push @command_lines, 'execute(' . $startstr . $_ . $endstr . ')';
}
}
@@ -115,40 +156,13 @@ sub read_in_file {
# Add input to @input_lines.
EMIT_INPUT() => sub {
if (/^STARTTEST/) {
- return END_INPUT;
+ end_input \@input_lines, \@command_lines, \@test_body_lines;
+ return EMIT_COMMAND;
}
push @input_lines, ' ' . $_;
return EMIT_INPUT;
},
- # The END_INPUT state is used to push lines from current
- # input and command blocks into @test_body_lines
- # in the correct order.
- END_INPUT() => sub {
- # Only keep first input line if it is not empty.
- my $first_input_line = shift @input_lines;
- if ($first_input_line =~ /^$/) {
- unshift @input_lines, $first_input_line;
- }
-
- # If there are input lines left, wrap them with
- # `insert` command and add before the previous command
- # block.
- if (@input_lines) {
- my $last_input_line = pop @input_lines;
- unshift @command_lines, '';
- unshift @command_lines, $last_input_line . ']])';
- unshift @command_lines, @input_lines;
- unshift @command_lines, "insert([[";
-
- push @test_body_lines, @command_lines;
-
- @command_lines = ();
- @input_lines = ();
- }
-
- return EMIT_COMMAND;
- }
);
my $state = EMIT_DESCRIPTION;
@@ -162,7 +176,7 @@ sub read_in_file {
# If not all input lines have been processed,
# do it now.
if (@input_lines) {
- $states{END_INPUT()}->();
+ end_input \@input_lines, \@command_lines, \@test_body_lines;
}
close $in_file_handle;
@@ -216,7 +230,13 @@ my ($test_name, $base_path, $suffix) = fileparse($legacy_testfile, @legacy_suffi
my $in_file = catfile($base_path, $test_name . '.in');
my $ok_file = catfile($base_path, $test_name . '.ok');
-my $spec_file = catfile($out_dir, $test_name . '_spec.lua');
+my $spec_file = do {
+ if ($test_name =~ /^test([0-9]+)/) {
+ catfile($out_dir, sprintf('%03d', $1) . '_' . $test_name . '_spec.lua')
+ } else {
+ catfile($out_dir, $test_name . '_spec.lua')
+ }
+};
if (! -f $in_file) {
say "Test input file $in_file not found.";
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 5b97cf5f40..b06b4fa547 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -89,8 +89,8 @@ get_directory_property(gen_includes INCLUDE_DIRECTORIES)
foreach(gen_include ${gen_includes})
set(gen_cflags "${gen_cflags} -I${gen_include}")
endforeach()
-string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
-set(gen_cflags "${gen_cflags} ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}")
+string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
+set(gen_cflags "${gen_cflags} ${CMAKE_C_FLAGS_${build_type}} ${CMAKE_C_FLAGS}")
foreach(sfile ${NEOVIM_SOURCES}
"${PROJECT_SOURCE_DIR}/src/nvim/regexp_nfa.c")
@@ -158,8 +158,8 @@ else()
endif()
endif()
-if(HAVE_ICONV_LIB)
- list(APPEND NVIM_LINK_LIBRARIES iconv)
+if(Iconv_LIBRARIES)
+ list(APPEND NVIM_LINK_LIBRARIES ${Iconv_LIBRARIES})
endif()
# Put these last on the link line, since multiple things may depend on them.
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index 9992fbdfcf..328b751693 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/cursor_shape.h"
@@ -76,6 +77,7 @@ char_u *parse_shape_opt(int what)
* For the 'a' mode, we loop to handle all the modes.
*/
all_idx = -1;
+ assert(modep < colonp);
while (modep < colonp || all_idx >= 0) {
if (all_idx < 0) {
/* Find the mode. */
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 1d5e1a51cf..384ca9abd8 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -3231,6 +3231,7 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
if (flag == 'w') { /* just windows */
if (buf == curbuf) /* first call for this flag/expansion */
wp = curwin;
+ assert(wp);
while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin
&& wp->w_buffer->b_scanned)
;
@@ -3612,6 +3613,7 @@ static int ins_compl_get_exp(pos_T *ini)
* If 'infercase' is set, don't use 'smartcase' here
*/
save_p_scs = p_scs;
+ assert(ins_buf);
if (ins_buf->b_p_inf)
p_scs = FALSE;
@@ -3760,8 +3762,10 @@ static int ins_compl_get_exp(pos_T *ini)
compl_started = TRUE;
} else {
/* Mark a buffer scanned when it has been scanned completely */
- if (type == 0 || type == CTRL_X_PATH_PATTERNS)
+ if (type == 0 || type == CTRL_X_PATH_PATTERNS) {
+ assert(ins_buf);
ins_buf->b_scanned = TRUE;
+ }
compl_started = FALSE;
}
@@ -6286,6 +6290,7 @@ static void mb_replace_pop_ins(int cc)
break;
} else {
buf[0] = c;
+ assert(n > 1);
for (i = 1; i < n; ++i)
buf[i] = replace_pop();
if (utf_iscomposing(utf_ptr2char(buf)))
@@ -6331,10 +6336,11 @@ static void replace_do_bs(int limit_col)
char_u *p;
int i;
int vcol;
+ const int l_State = State;
cc = replace_pop();
if (cc > 0) {
- if (State & VREPLACE_FLAG) {
+ if (l_State & VREPLACE_FLAG) {
/* Get the number of screen cells used by the character we are
* going to delete. */
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
@@ -6342,17 +6348,17 @@ static void replace_do_bs(int limit_col)
}
if (has_mbyte) {
(void)del_char_after_col(limit_col);
- if (State & VREPLACE_FLAG)
+ if (l_State & VREPLACE_FLAG)
orig_len = (int)STRLEN(get_cursor_pos_ptr());
replace_push(cc);
} else {
pchar_cursor(cc);
- if (State & VREPLACE_FLAG)
+ if (l_State & VREPLACE_FLAG)
orig_len = (int)STRLEN(get_cursor_pos_ptr()) - 1;
}
replace_pop_ins();
- if (State & VREPLACE_FLAG) {
+ if (l_State & VREPLACE_FLAG) {
/* Get the number of screen cells used by the inserted characters */
p = get_cursor_pos_ptr();
ins_len = (int)STRLEN(p) - orig_len;
@@ -7449,7 +7455,9 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
if (State & REPLACE_FLAG)
replace_do_bs(-1);
else {
- if (enc_utf8 && p_deco)
+ const bool l_enc_utf8 = enc_utf8;
+ const int l_p_deco = p_deco;
+ if (l_enc_utf8 && l_p_deco)
(void)utfc_ptr2char(get_cursor_pos_ptr(), cpc);
(void)del_char(FALSE);
/*
@@ -7457,7 +7465,7 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
* move the cursor back. Don't back up before the base
* character.
*/
- if (enc_utf8 && p_deco && cpc[0] != NUL)
+ if (l_enc_utf8 && l_p_deco && cpc[0] != NUL)
inc_cursor();
if (revins_chars) {
revins_chars--;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 59363a3608..fc61fed529 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -14492,6 +14492,11 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
set_vim_var_nr(VV_SHELL_ERROR, (long) status);
if (res == NULL) {
+ if (retlist) {
+ // return an empty list when there's no output
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = list_alloc();
+ }
return;
}
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index f5fa16a139..ef9affcdf6 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -10,6 +10,7 @@
* ex_cmds.c: some functions for command line commands
*/
+#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
@@ -90,8 +91,9 @@ void do_ascii(exarg_T *eap)
int cc[MAX_MCO];
int ci = 0;
int len;
+ const bool l_enc_utf8 = enc_utf8;
- if (enc_utf8)
+ if (l_enc_utf8)
c = utfc_ptr2char(get_cursor_pos_ptr(), cc);
else
c = gchar_cursor();
@@ -123,20 +125,20 @@ void do_ascii(exarg_T *eap)
vim_snprintf((char *)IObuff, IOSIZE,
_("<%s>%s%s %d, Hex %02x, Octal %03o"),
transchar(c), buf1, buf2, cval, cval, cval);
- if (enc_utf8)
+ if (l_enc_utf8)
c = cc[ci++];
else
c = 0;
}
/* Repeat for combining characters. */
- while (has_mbyte && (c >= 0x100 || (enc_utf8 && c >= 0x80))) {
+ while (has_mbyte && (c >= 0x100 || (l_enc_utf8 && c >= 0x80))) {
len = (int)STRLEN(IObuff);
/* This assumes every multi-byte char is printable... */
if (len > 0)
IObuff[len++] = ' ';
IObuff[len++] = '<';
- if (enc_utf8 && utf_iscomposing(c)
+ if (l_enc_utf8 && utf_iscomposing(c)
# ifdef USE_GUI
&& !gui.in_use
# endif
@@ -148,7 +150,7 @@ void do_ascii(exarg_T *eap)
: _("> %d, Hex %08x, Octal %o"), c, c, c);
if (ci == MAX_MCO)
break;
- if (enc_utf8)
+ if (l_enc_utf8)
c = cc[ci++];
else
c = 0;
@@ -2764,9 +2766,12 @@ do_ecmd (
/* Autocommands may open a new window and leave oldwin open
* which leads to crashes since the above call sets
* oldwin->w_buffer to NULL. */
- if (curwin != oldwin && oldwin != aucmd_win
- && win_valid(oldwin) && oldwin->w_buffer == NULL)
- win_close(oldwin, FALSE);
+ if (curwin != oldwin && oldwin != aucmd_win && win_valid(oldwin)) {
+ assert(oldwin);
+ if (oldwin->w_buffer == NULL) {
+ win_close(oldwin, FALSE);
+ }
+ }
if (aborting()) { /* autocmds may abort script processing */
free(new_name);
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 6e31142137..1636d62c74 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -10,6 +10,7 @@
* ex_cmds2.c: some more functions for command line commands
*/
+#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -2404,11 +2405,13 @@ do_source (
// time_fd was successfully opened afterwards.
proftime_T rel_time;
proftime_T start_time;
- if (time_fd != NULL) {
+ FILE * const l_time_fd = time_fd;
+ if (l_time_fd != NULL) {
time_push(&rel_time, &start_time);
}
- if (do_profiling == PROF_YES)
+ const int l_do_profiling = do_profiling;
+ if (l_do_profiling == PROF_YES)
prof_child_enter(&wait_start); /* entering a child now */
/* Don't use local function variables, if called from a function.
@@ -2422,6 +2425,7 @@ do_source (
save_current_SID = current_SID;
FileID file_id;
bool file_id_ok = os_fileid((char *)fname_exp, &file_id);
+ assert(script_items.ga_len >= 0);
for (current_SID = script_items.ga_len; current_SID > 0; --current_SID) {
si = &SCRIPT_ITEM(current_SID);
// Compare dev/ino when possible, it catches symbolic links.
@@ -2455,7 +2459,7 @@ do_source (
new_script_vars(current_SID);
}
- if (do_profiling == PROF_YES) {
+ if (l_do_profiling == PROF_YES) {
int forceit;
/* Check if we do profiling for this script. */
@@ -2477,7 +2481,7 @@ do_source (
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
retval = OK;
- if (do_profiling == PROF_YES) {
+ if (l_do_profiling == PROF_YES) {
/* Get "si" again, "script_items" may have been reallocated. */
si = &SCRIPT_ITEM(current_SID);
if (si->sn_prof_on) {
@@ -2501,7 +2505,7 @@ do_source (
verbose_leave();
}
- if (time_fd != NULL) {
+ if (l_time_fd != NULL) {
vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
time_msg((char *)IObuff, &start_time);
time_pop(rel_time);
@@ -2517,7 +2521,7 @@ do_source (
current_SID = save_current_SID;
restore_funccal(save_funccalp);
- if (do_profiling == PROF_YES)
+ if (l_do_profiling == PROF_YES)
prof_child_exit(&wait_start); /* leaving a child now */
fclose(cookie.fp);
free(cookie.nextline);
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 21c877e2b9..67c346237c 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7699,6 +7699,10 @@ eval_vars (
sprintf((char *)strbuf, "%" PRId64, (int64_t)sourcing_lnum);
result = strbuf;
break;
+ default:
+ // should not happen
+ *errormsg = (char_u *)"";
+ return NULL;
}
resultlen = (int)STRLEN(result); /* length of new string */
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 3e1672c2e7..fba0b93253 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -9,8 +9,8 @@
/*
* ex_eval.c: functions for Ex command line for the +eval feature.
*/
+#include <assert.h>
#include <stdbool.h>
-
#include <inttypes.h>
#include "nvim/vim.h"
@@ -670,6 +670,7 @@ static void report_pending(int action, int pending, void *value)
char *s;
int save_msg_silent;
+ assert(value || !(pending & CSTP_THROW));
switch (action) {
case RP_MAKE:
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index b8d8837092..5feff4d456 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4245,8 +4245,10 @@ void init_history(void)
for (i = newlen - 1;; --i) {
if (i >= 0) /* copy newest entries */
temp[i] = history[type][j];
- else /* remove older entries */
+ else { /* remove older entries */
free(history[type][j].hisstr);
+ history[type][j].hisstr = NULL;
+ }
if (--j < 0)
j = hislen - 1;
if (j == hisidx[type])
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index ecc05a9faa..05a0a59874 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1751,7 +1751,9 @@ failed:
# ifdef USE_ICONV
if (iconv_fd != (iconv_t)-1) {
iconv_close(iconv_fd);
+# ifndef __clang_analyzer__
iconv_fd = (iconv_t)-1;
+# endif
}
# endif
@@ -6189,12 +6191,9 @@ aucmd_prepbuf (
}
}
- /* Allocate "aucmd_win" when needed. If this fails (out of memory) fall
- * back to using the current window. */
+ /* Allocate "aucmd_win" when needed. */
if (win == NULL && aucmd_win == NULL) {
win_alloc_aucmd_win();
- if (aucmd_win == NULL)
- win = curwin;
}
if (win == NULL && aucmd_win_used)
/* Strange recursive autocommand, fall back to using the current
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 95f1e054b9..6014dbfd15 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -22,6 +22,7 @@
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
+#include "nvim/func_attr.h"
#include "nvim/indent.h"
#include "nvim/mark.h"
#include "nvim/memline.h"
@@ -1680,7 +1681,9 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen)
* When 'foldtext' isn't set puts the result in "buf[51]". Otherwise the
* result is in allocated memory.
*/
-char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T *foldinfo, char_u *buf)
+char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
+ foldinfo_T *foldinfo, char_u *buf)
+ FUNC_ATTR_NONNULL_ARG(1)
{
char_u *text = NULL;
/* an error occurred when evaluating 'fdt' setting */
@@ -1689,8 +1692,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T *foldi
static win_T *last_wp = NULL;
static linenr_T last_lnum = 0;
- if (last_wp != wp || last_wp == NULL
- || last_lnum > lnum || last_lnum == 0)
+ if (last_wp == NULL || last_wp != wp || last_lnum > lnum || last_lnum == 0)
/* window changed, try evaluating foldtext setting once again */
got_fdt_error = FALSE;
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index c6354d6c5f..2ef35fdac6 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -3006,7 +3006,7 @@ int mch_print_text_out(char_u *p, int len)
/* Convert from multi-byte to 8-bit encoding */
p = string_convert(&prt_conv, p, &len);
if (p == NULL)
- p = (char_u *)"";
+ p = (char_u *)xstrdup("");
}
if (prt_out_mbyte) {
@@ -3054,7 +3054,7 @@ int mch_print_text_out(char_u *p, int len)
}
/* Need to free any translated characters */
- if (prt_do_conv && (*p != NUL))
+ if (prt_do_conv)
free(p);
prt_text_run += char_width;
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index d243c4ed95..c2c406a235 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -49,17 +49,11 @@ static void try_to_free_memory(void)
/// @return pointer to allocated space. NULL if out of memory
void *try_malloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1)
{
+ size = size ? size : 1;
void *ret = malloc(size);
-
- if (!ret && !size) {
- ret = malloc(1);
- }
if (!ret) {
try_to_free_memory();
ret = malloc(size);
- if (!ret && !size) {
- ret = malloc(1);
- }
}
return ret;
}
@@ -91,7 +85,6 @@ void *xmalloc(size_t size)
FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1) FUNC_ATTR_NONNULL_RET
{
void *ret = try_malloc(size);
-
if (!ret) {
OUT_STR(e_outofmem);
out_char('\n');
@@ -109,23 +102,16 @@ void *xmalloc(size_t size)
void *xcalloc(size_t count, size_t size)
FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE_PROD(1, 2) FUNC_ATTR_NONNULL_RET
{
- void *ret = calloc(count, size);
-
- if (!ret && (!count || !size))
- ret = calloc(1, 1);
-
+ void *ret = count && size ? calloc(count, size) : calloc(1, 1);
if (!ret) {
try_to_free_memory();
- ret = calloc(count, size);
- if (!ret && (!count || !size))
- ret = calloc(1, 1);
+ ret = count && size ? calloc(count, size) : calloc(1, 1);
if (!ret) {
OUT_STR(e_outofmem);
out_char('\n');
preserve_exit();
}
}
-
return ret;
}
@@ -137,23 +123,16 @@ void *xcalloc(size_t count, size_t size)
void *xrealloc(void *ptr, size_t size)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALLOC_SIZE(2) FUNC_ATTR_NONNULL_RET
{
- void *ret = realloc(ptr, size);
-
- if (!ret && !size)
- ret = realloc(ptr, 1);
-
+ void *ret = size ? realloc(ptr, size) : realloc(ptr, 1);
if (!ret) {
try_to_free_memory();
- ret = realloc(ptr, size);
- if (!ret && !size)
- ret = realloc(ptr, 1);
+ ret = size ? realloc(ptr, size) : realloc(ptr, 1);
if (!ret) {
OUT_STR(e_outofmem);
out_char('\n');
preserve_exit();
}
}
-
return ret;
}
@@ -166,14 +145,12 @@ void *xmallocz(size_t size)
FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
{
size_t total_size = size + 1;
- void *ret;
-
if (total_size < size) {
OUT_STR(_("Vim: Data too large to fit into virtual memory space\n"));
preserve_exit();
}
- ret = xmalloc(total_size);
+ void *ret = xmalloc(total_size);
((char*)ret)[size] = 0;
return ret;
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 58dbee8cf9..ee83fd371e 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -12,6 +12,7 @@
#define MESSAGE_FILE /* don't include prototype for smsg() */
+#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -691,8 +692,10 @@ int delete_first_msg(void)
return FAIL;
p = first_msg_hist;
first_msg_hist = p->next;
- if (first_msg_hist == NULL)
- last_msg_hist = NULL; /* history is empty */
+ if (first_msg_hist == NULL) { /* history is becoming empty */
+ assert(msg_hist_len == 1);
+ last_msg_hist = NULL;
+ }
free(p->msg);
free(p);
--msg_hist_len;
@@ -3320,7 +3323,6 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
case 'c':
case 's':
case 'S':
- length_modifier = '\0';
str_arg_l = 1;
switch (fmt_spec) {
case '%':
@@ -3584,7 +3586,6 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
* zero value is formatted with an
* explicit precision of zero */
precision = num_of_digits + 1;
- precision_specified = 1;
}
}
/* zero padding to specified precision? */
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index aa6008558f..da1dc8d1b5 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -119,7 +119,7 @@ void channel_teardown(void)
/// Creates an API channel by starting a job and connecting to its
/// stdin/stdout. stderr is forwarded to the editor error stream.
///
-/// @param argv The argument vector for the process
+/// @param argv The argument vector for the process. [consumed]
/// @return The channel id
uint64_t channel_from_job(char **argv)
{
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index e74fcef8d9..e7079e02d0 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -11,6 +11,7 @@
* op_change, op_yank, do_put, do_join
*/
+#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
@@ -3436,7 +3437,7 @@ int do_join(long count,
&& has_format_option(FO_REMOVE_COMS);
int prev_was_comment;
-
+ assert(count > 1);
if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1),
(linenr_T)(curwin->w_cursor.lnum + count)) == FAIL)
return FAIL;
@@ -5027,6 +5028,8 @@ void cursor_pos_info(void)
pos_T min_pos, max_pos;
oparg_T oparg;
struct block_def bd;
+ const int l_VIsual_active = VIsual_active;
+ const int l_VIsual_mode = VIsual_mode;
/*
* Compute the length of the file in characters.
@@ -5039,7 +5042,7 @@ void cursor_pos_info(void)
else
eol_size = 1;
- if (VIsual_active) {
+ if (l_VIsual_active) {
if (lt(VIsual, curwin->w_cursor)) {
min_pos = VIsual;
max_pos = curwin->w_cursor;
@@ -5050,7 +5053,7 @@ void cursor_pos_info(void)
if (*p_sel == 'e' && max_pos.col > 0)
--max_pos.col;
- if (VIsual_mode == Ctrl_V) {
+ if (l_VIsual_mode == Ctrl_V) {
char_u * saved_sbr = p_sbr;
/* Make 'sbr' empty for a moment to get the correct size. */
@@ -5083,12 +5086,12 @@ void cursor_pos_info(void)
}
/* Do extra processing for VIsual mode. */
- if (VIsual_active
+ if (l_VIsual_active
&& lnum >= min_pos.lnum && lnum <= max_pos.lnum) {
char_u *s = NULL;
long len = 0L;
- switch (VIsual_mode) {
+ switch (l_VIsual_mode) {
case Ctrl_V:
virtual_op = virtual_active();
block_prep(&oparg, &bd, lnum, 0);
@@ -5141,8 +5144,8 @@ void cursor_pos_info(void)
if (!curbuf->b_p_eol && curbuf->b_p_bin)
byte_count -= eol_size;
- if (VIsual_active) {
- if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL) {
+ if (l_VIsual_active) {
+ if (l_VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL) {
getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
&max_pos.col);
vim_snprintf((char *)buf1, sizeof(buf1), _("%" PRId64 " Cols; "),
diff --git a/src/nvim/os/job.c b/src/nvim/os/job.c
index 7ae2a86fc2..17872ab9c9 100644
--- a/src/nvim/os/job.c
+++ b/src/nvim/os/job.c
@@ -105,7 +105,8 @@ void job_teardown(void)
/// Tries to start a new job.
///
/// @param argv Argument vector for the process. The first item is the
-/// executable to run.
+/// executable to run.
+/// [consumed]
/// @param data Caller data that will be associated with the job
/// @param writable If true the job stdin will be available for writing with
/// job_write, otherwise it will be redirected to /dev/null
@@ -139,6 +140,7 @@ Job *job_start(char **argv,
if (i == MAX_RUNNING_JOBS) {
// No free slots
+ shell_free_argv(argv);
*status = 0;
return NULL;
}
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 7449ac637c..1b279f18f5 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -244,6 +244,9 @@ static int shell(const char *cmd,
job_stop(job);
return -1;
}
+ // close the input stream after everything is written
+ job_write_cb(job, shell_write_cb);
+ } else {
// close the input stream, let the process know that no more input is
// coming
job_close_in(job);
@@ -447,3 +450,9 @@ static void write_output(char *output, size_t remaining)
curbuf->b_no_eol_lnum = 0;
}
}
+
+static void shell_write_cb(WStream *wstream, void *data, int status)
+{
+ Job *job = data;
+ job_close_in(job);
+}
diff --git a/src/nvim/os/wstream.c b/src/nvim/os/wstream.c
index a1f3612418..6a650ce775 100644
--- a/src/nvim/os/wstream.c
+++ b/src/nvim/os/wstream.c
@@ -230,7 +230,11 @@ static void write_cb(uv_write_t *req, int status)
if (data->wstream->freed && data->wstream->pending_reqs == 0) {
// Last pending write, free the wstream;
- free(data->wstream);
+ if (data->wstream->free_handle) {
+ uv_close((uv_handle_t *)data->wstream->stream, close_cb);
+ } else {
+ free(data->wstream);
+ }
}
kmp_free(WRequestPool, wrequest_pool, data);
diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt
index 0ed39e8c49..6a56e302e9 100644
--- a/src/nvim/po/CMakeLists.txt
+++ b/src/nvim/po/CMakeLists.txt
@@ -50,7 +50,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG AND
-DPOT_FILE=${NVIM_POT}
-DSEARCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}
"'-DSOURCES=${NEOVIM_RELATIVE_SOURCES}'"
- -P ${CMAKE_MODULE_PATH}/RunXgettext.cmake
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunXgettext.cmake
DEPENDS ${NEOVIM_SOURCES})
add_custom_target(potfile DEPENDS ${NVIM_POT})
@@ -68,7 +68,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG AND
-DMSGFMT_PRG=${GETTEXT_MSGFMT_EXECUTABLE}
-DMO_FILE=${moFile}
-DPO_FILE=${poFile}
- -P ${CMAKE_MODULE_PATH}/RunMsgfmt.cmake
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunMsgfmt.cmake
DEPENDS ${poFile} ${NVIM_POT})
install_helper(
@@ -107,7 +107,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG AND
-DINPUT_ENC=${inputEnc}
-DOUTPUT_ENC=${outputEnc}
-DOUTPUT_CHARSET=${outputCharSet}
- -P ${CMAKE_MODULE_PATH}/ConvertPo.cmake
+ -P ${PROJECT_SOURCE_DIR}/cmake/ConvertPo.cmake
COMMENT "Updating ${outputName}.po"
DEPENDS ${inputFile})
@@ -190,7 +190,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG AND
-DMSGMERGE_PRG=${GETTEXT_MSGMERGE_EXECUTABLE}
-DPO_FILE=${poFile}
-DPOT_FILE=${NVIM_POT}
- -P ${CMAKE_MODULE_PATH}/RunMsgmerge.cmake
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunMsgmerge.cmake
COMMENT "Updating ${LANGUAGE}.po"
DEPENDS ${NVIM_POT})
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 90da02bb1b..cef2e6d9bf 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -43,6 +43,7 @@
/* #undef REGEXP_DEBUG */
/* #define REGEXP_DEBUG */
+#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
@@ -1199,10 +1200,7 @@ char_u *skip_regexp(char_u *startp, int dirc, int magic, char_u **newp)
*newp = vim_strsave(startp);
p = *newp + (p - startp);
}
- if (*newp != NULL)
- STRMOVE(p, p + 1);
- else
- ++p;
+ STRMOVE(p, p + 1);
} else
++p; /* skip next character */
if (*p == 'v')
@@ -1300,16 +1298,18 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags)
r->regstart = (*mb_ptr2char)(OPERAND(scan));
else
r->regstart = *OPERAND(scan);
- } else if ((OP(scan) == BOW
- || OP(scan) == EOW
- || OP(scan) == NOTHING
- || OP(scan) == MOPEN + 0 || OP(scan) == NOPEN
- || OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE)
- && OP(regnext(scan)) == EXACTLY) {
- if (has_mbyte)
- r->regstart = (*mb_ptr2char)(OPERAND(regnext(scan)));
- else
- r->regstart = *OPERAND(regnext(scan));
+ } else if (OP(scan) == BOW
+ || OP(scan) == EOW
+ || OP(scan) == NOTHING
+ || OP(scan) == MOPEN + 0 || OP(scan) == NOPEN
+ || OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE) {
+ char_u *regnext_scan = regnext(scan);
+ if (OP(regnext_scan) == EXACTLY) {
+ if (has_mbyte)
+ r->regstart = (*mb_ptr2char)(OPERAND(regnext_scan));
+ else
+ r->regstart = *OPERAND(regnext_scan);
+ }
}
/*
@@ -5626,6 +5626,8 @@ static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T e
/* Get the line to compare with. */
p = reg_getline(clnum);
+ assert(p);
+
if (clnum == end_lnum)
len = end_col - ccol;
else
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ac726f7988..e217945ac3 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -244,6 +244,9 @@ int redraw_asap(int type)
u8char_T *screenlineUC = NULL; /* copy from ScreenLinesUC[] */
u8char_T *screenlineC[MAX_MCO]; /* copy from ScreenLinesC[][] */
schar_T *screenline2 = NULL; /* copy from ScreenLines2[] */
+ const bool l_enc_utf8 = enc_utf8;
+ const int l_enc_dbcs = enc_dbcs;
+ const long l_p_mco = p_mco;
redraw_later(type);
if (msg_scrolled || (State != NORMAL && State != NORMAL_BUSY))
@@ -254,14 +257,14 @@ int redraw_asap(int type)
screenline = xmalloc((size_t)(rows * Columns * sizeof(schar_T)));
screenattr = xmalloc((size_t)(rows * Columns * sizeof(sattr_T)));
- if (enc_utf8) {
+ if (l_enc_utf8) {
screenlineUC = xmalloc((size_t)(rows * Columns * sizeof(u8char_T)));
- for (i = 0; i < p_mco; ++i) {
+ for (i = 0; i < l_p_mco; ++i) {
screenlineC[i] = xmalloc((size_t)(rows * Columns * sizeof(u8char_T)));
}
}
- if (enc_dbcs == DBCS_JPNU) {
+ if (l_enc_dbcs == DBCS_JPNU) {
screenline2 = xmalloc((size_t)(rows * Columns * sizeof(schar_T)));
}
@@ -273,16 +276,16 @@ int redraw_asap(int type)
memmove(screenattr + r * Columns,
ScreenAttrs + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(sattr_T));
- if (enc_utf8) {
+ if (l_enc_utf8) {
memmove(screenlineUC + r * Columns,
ScreenLinesUC + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
+ for (i = 0; i < l_p_mco; ++i)
memmove(screenlineC[i] + r * Columns,
ScreenLinesC[r] + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(u8char_T));
}
- if (enc_dbcs == DBCS_JPNU)
+ if (l_enc_dbcs == DBCS_JPNU)
memmove(screenline2 + r * Columns,
ScreenLines2 + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(schar_T));
@@ -302,16 +305,16 @@ int redraw_asap(int type)
memmove(ScreenAttrs + off,
screenattr + r * Columns,
(size_t)Columns * sizeof(sattr_T));
- if (enc_utf8) {
+ if (l_enc_utf8) {
memmove(ScreenLinesUC + off,
screenlineUC + r * Columns,
(size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
+ for (i = 0; i < l_p_mco; ++i)
memmove(ScreenLinesC[i] + off,
screenlineC[i] + r * Columns,
(size_t)Columns * sizeof(u8char_T));
}
- if (enc_dbcs == DBCS_JPNU)
+ if (l_enc_dbcs == DBCS_JPNU)
memmove(ScreenLines2 + off,
screenline2 + r * Columns,
(size_t)Columns * sizeof(schar_T));
@@ -322,12 +325,12 @@ int redraw_asap(int type)
free(screenline);
free(screenattr);
- if (enc_utf8) {
+ if (l_enc_utf8) {
free(screenlineUC);
- for (i = 0; i < p_mco; ++i)
+ for (i = 0; i < l_p_mco; ++i)
free(screenlineC[i]);
}
- if (enc_dbcs == DBCS_JPNU)
+ if (l_enc_dbcs == DBCS_JPNU)
free(screenline2);
/* Show the intro message when appropriate. */
@@ -3474,7 +3477,6 @@ win_line (
n_extra = tab_len;
} else {
char_u *p;
- int len = n_extra;
int i;
int saved_nextra = n_extra;
@@ -3485,7 +3487,7 @@ win_line (
/* if n_extra > 0, it gives the number of chars to use for
* a tab, else we need to calculate the width for a tab */
- len = (tab_len * mb_char2len(lcs_tab2));
+ int len = (tab_len * mb_char2len(lcs_tab2));
if (n_extra > 0) {
len += n_extra - tab_len;
}
@@ -3865,7 +3867,7 @@ win_line (
/* Get rid of the boguscols now, we want to draw until the right
* edge for 'cursorcolumn'. */
col -= boguscols;
- boguscols = 0;
+ // boguscols = 0; // Disabled because value never read after this
if (draw_color_col)
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
@@ -7532,7 +7534,6 @@ int showmode(void)
msg_puts_attr(edit_submode_extra, sub_attr);
}
}
- length = 0;
} else {
if (State & VREPLACE_FLAG)
MSG_PUTS_ATTR(_(" VREPLACE"), attr);
@@ -7708,7 +7709,6 @@ static void draw_tabline(void)
attr = attr_nosel;
tabcount = 0;
- scol = 0;
FOR_ALL_TABS(tp) {
if (col >= Columns - 4) {
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 4d81cc86bf..137f85bb2b 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -21,6 +21,8 @@
char *Version = VIM_VERSION_SHORT;
char *longVersion = NVIM_VERSION_LONG " (compiled " __DATE__ " " __TIME__ ")";
char *version_commit = "Commit: " NVIM_VERSION_COMMIT;
+char *version_buildtype = "Build type: " NVIM_VERSION_BUILD_TYPE;
+char *version_cflags = "Compilation: " NVIM_VERSION_CFLAGS;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "version.c.generated.h"
@@ -778,6 +780,8 @@ void list_version(void)
// internal variables in eval.c!
MSG(longVersion);
MSG(version_commit);
+ MSG(version_buildtype);
+ MSG(version_cflags);
// Print the list of extra patch descriptions if there is at least one.
char *s = "";
@@ -857,10 +861,6 @@ void list_version(void)
version_msg("\"\n");
}
#endif // ifdef HAVE_PATHDEF
-#ifdef DEBUG
- version_msg("\n");
- version_msg(_(" DEBUG BUILD"));
-#endif // ifdef DEBUG
}
/// Output a string for the version message. If it's going to wrap, output a
diff --git a/src/nvim/version_defs.h b/src/nvim/version_defs.h
index d8e1b4ea82..0ba6143632 100644
--- a/src/nvim/version_defs.h
+++ b/src/nvim/version_defs.h
@@ -22,13 +22,19 @@
#define NVIM_VERSION_PATCH 0
#endif
#ifndef NVIM_VERSION_PRERELEASE
-#define NVIM_VERSION_PRERELEASE
+#define NVIM_VERSION_PRERELEASE "?"
#endif
#ifndef NVIM_VERSION_BUILD
-#define NVIM_VERSION_BUILD
+#define NVIM_VERSION_BUILD "?"
#endif
#ifndef NVIM_VERSION_COMMIT
-#define NVIM_VERSION_COMMIT
+#define NVIM_VERSION_COMMIT "?"
+#endif
+#ifndef NVIM_VERSION_CFLAGS
+#define NVIM_VERSION_CFLAGS "?"
+#endif
+#ifndef NVIM_VERSION_BUILD_TYPE
+#define NVIM_VERSION_BUILD_TYPE "?"
#endif
// for the startup-screen
#define NVIM_VERSION_MEDIUM STR(NVIM_VERSION_MAJOR) "." STR(NVIM_VERSION_MINOR)
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index bf6e3dd38a..6c3f5190c9 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -25,7 +25,7 @@ if os.getenv('VALGRIND') then
nvim_argv = valgrind_argv
end
-local session, loop_running, last_error
+local session, loop_running, loop_stopped, last_error
local function request(method, ...)
local status, rv = session:request(method, ...)
@@ -39,7 +39,11 @@ local function request(method, ...)
end
-- Make sure this will only return after all buffered characters have been
-- processed
- session:request('vim_eval', '1')
+ if not loop_stopped then
+ -- Except when the loop has been stopped by a notification triggered
+ -- by the initial request, for example.
+ session:request('vim_eval', '1')
+ end
return rv
end
@@ -71,6 +75,7 @@ local function run(request_cb, notification_cb, setup_cb)
call_and_stop_on_error(setup_cb)
end
+ loop_stopped = false
loop_running = true
session:run(on_request, on_notification, on_setup)
loop_running = false
@@ -82,6 +87,7 @@ local function run(request_cb, notification_cb, setup_cb)
end
local function stop()
+ loop_stopped = true
session:stop()
end
diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua
index a8bab8e26e..91e115aedf 100644
--- a/test/functional/shell/viml_system_spec.lua
+++ b/test/functional/shell/viml_system_spec.lua
@@ -3,8 +3,8 @@
-- - `systemlist()`
local helpers = require('test.functional.helpers')
-local eq, clear, eval, feed =
- helpers.eq, helpers.clear, helpers.eval, helpers.feed
+local eq, clear, eval, feed, nvim =
+ helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.nvim
local function create_file_with_nuls(name)
@@ -55,6 +55,21 @@ describe('system()', function()
end)
end)
+ describe('passing a lot of input', function()
+ it('returns the program output', function()
+ local input = {}
+ -- write more than 1mb of data, which should be enough to overcome
+ -- the os buffer limit and force multiple event loop iterations to write
+ -- everything
+ for i = 1, 0xffff do
+ input[#input + 1] = '01234567890ABCDEFabcdef'
+ end
+ input = table.concat(input, '\n')
+ nvim('set_var', 'input', input)
+ eq(input, eval('system("cat -", g:input)'))
+ end)
+ end)
+
describe('passing number as input', function()
it('stringifies the input', function()
eq('1', eval('system("cat", 1)'))
@@ -129,6 +144,17 @@ describe('systemlist()', function()
end)
end)
+ describe('passing a lot of input', function()
+ it('returns the program output', function()
+ local input = {}
+ for i = 1, 0xffff do
+ input[#input + 1] = '01234567890ABCDEFabcdef'
+ end
+ nvim('set_var', 'input', input)
+ eq(input, eval('systemlist("cat -", g:input)'))
+ end)
+ end)
+
describe('with output containing NULs', function()
local fname = 'Xtest'
@@ -166,7 +192,7 @@ describe('systemlist()', function()
if xclip then
describe("with a program that doesn't close stdout", function()
it('will exit properly after passing input', function()
- eq(nil, eval(
+ eq({}, eval(
"systemlist('xclip -i -selection clipboard', ['clip', 'data'])"))
eq({'clip', 'data'}, eval(
"systemlist('xclip -o -selection clipboard')"))