Merge branch 'master' into s-dash-stdin

This commit is contained in:
ZyX 2017-12-03 16:49:30 +03:00
commit c49e22d396
1530 changed files with 112129 additions and 74550 deletions

View File

@ -1,25 +0,0 @@
#!/usr/bin/env bash
set -e
set -o pipefail
if [[ -n "${CI_TARGET}" ]]; then
exit
fi
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
brew update
fi
echo "Upgrade Python 2 pip."
pip2.7 -q install --user --upgrade pip
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
echo "Install Python 3."
brew install python3
echo "Upgrade Python 3 pip."
pip3 -q install --user --upgrade pip
else
echo "Upgrade Python 3 pip."
pip3 -q install --user --upgrade pip
fi

View File

@ -1,148 +0,0 @@
print_core() {
local app="$1"
local core="$2"
if test "$app" = quiet ; then
echo "Found core $core"
return 0
fi
echo "======= Core file $core ======="
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
lldb -Q -o "bt all" -f "${app}" -c "${core}"
else
gdb -n -batch -ex 'thread apply all bt full' "${app}" -c "${core}"
fi
}
check_core_dumps() {
local del=
if test "$1" = "--delete" ; then
del=1
shift
fi
local app="${1:-${BUILD_DIR}/bin/nvim}"
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
local cores="$(find /cores/ -type f -print)"
else
local cores="$(find ./ -type f -name 'core.*' -print)"
fi
if [ -z "${cores}" ]; then
return
fi
local core
for core in $cores; do
if test "$del" = "1" ; then
print_core "$app" "$core" >&2
rm "$core"
else
print_core "$app" "$core"
fi
done
if test "$app" = quiet ; then
return 0
fi
exit 1
}
check_logs() {
# Iterate through each log to remove an useless warning.
for log in $(find "${1}" -type f -name "${2}"); do
sed -i "${log}" \
-e '/Warning: noted but unhandled ioctl/d' \
-e '/could cause spurious value errors to appear/d' \
-e '/See README_MISSING_SYSCALL_OR_IOCTL for guidance/d'
done
# Now do it again, but only consider files with size > 0.
local err=""
for log in $(find "${1}" -type f -name "${2}" -size +0); do
cat "${log}"
err=1
done
if [[ -n "${err}" ]]; then
echo "Runtime errors detected."
exit 1
fi
}
valgrind_check() {
check_logs "${1}" "valgrind-*"
}
asan_check() {
check_logs "${1}" "*san.*"
}
run_unittests() {
ulimit -c unlimited
if ! ${MAKE_CMD} -C "${BUILD_DIR}" unittest ; then
check_core_dumps "$(which luajit)"
exit 1
fi
check_core_dumps "$(which luajit)"
}
run_functionaltests() {
ulimit -c unlimited
if ! ${MAKE_CMD} -C "${BUILD_DIR}" ${FUNCTIONALTEST}; then
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
check_core_dumps
exit 1
fi
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
check_core_dumps
}
run_oldtests() {
ulimit -c unlimited
if ! make -C "${TRAVIS_BUILD_DIR}/src/nvim/testdir"; then
reset
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
check_core_dumps
exit 1
fi
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
check_core_dumps
}
install_nvim() {
${MAKE_CMD} -C "${BUILD_DIR}" install
"${INSTALL_PREFIX}/bin/nvim" --version
"${INSTALL_PREFIX}/bin/nvim" -u NONE -e -c ':help' -c ':qall' || {
echo "Running ':help' in the installed nvim failed."
echo "Maybe the helptags have not been generated properly."
exit 1
}
local genvimsynf=syntax/vim/generated.vim
# Check that all runtime files were installed
for file in doc/tags $genvimsynf $(
cd runtime ; git ls-files | grep -e '.vim$' -e '.ps$' -e '.dict$' -e '.py$' -e '.tutor$'
) ; do
if ! test -e "${INSTALL_PREFIX}/share/nvim/runtime/$file" ; then
echo "It appears that $file is not installed."
exit 1
fi
done
# Check that generated syntax file has function names, #5060.
local gpat='syn keyword vimFuncName .*eval'
if ! grep -q "$gpat" "${INSTALL_PREFIX}/share/nvim/runtime/$genvimsynf"; then
echo "It appears that $genvimsynf does not contain $gpat."
exit 1
fi
for file in $(
cd runtime ; git ls-files | grep -e '.awk$' -e '.sh$' -e '.bat$'
) ; do
if ! test -x "${INSTALL_PREFIX}/share/nvim/runtime/$file" ; then
echo "It appears that $file is not installed or is not executable."
exit 1
fi
done
}

View File

@ -7,6 +7,10 @@ end_of_line = lf
insert_final_newline = true insert_final_newline = true
charset = utf_8 charset = utf_8
[runtime/doc/*.txt]
indent_style = tab
indent_size = 8
[Makefile] [Makefile]
indent_style = tab indent_style = tab
tab_width = 4 tab_width = 4

12
.gitignore vendored
View File

@ -1,11 +1,10 @@
# Build/deps dir # Build/deps dir
/build/ /build/
/cmake-build-debug/
/dist/ /dist/
/.deps/ /.deps/
/tmp/ /tmp/
*.rej
*.orig
*.mo *.mo
.*.sw? .*.sw?
*~ *~
@ -18,6 +17,9 @@ tags
/src/nvim/po/vim.pot /src/nvim/po/vim.pot
/src/nvim/po/*.ck /src/nvim/po/*.ck
# generated by tests with $NVIM_LOG_FILE set.
/.nvimlog
# Files generated by scripts/vim-patch.sh # Files generated by scripts/vim-patch.sh
/.vim-src/ /.vim-src/
@ -40,9 +42,6 @@ tags
# generated by luacheck during `make testlint' # generated by luacheck during `make testlint'
/test/.luacheckcache /test/.luacheckcache
# luarocks, not added as a subtree because of the large number of blobs
/third-party/luarocks
# local make targets # local make targets
local.mk local.mk
@ -50,6 +49,3 @@ local.mk
/runtime/doc/*.html /runtime/doc/*.html
/runtime/doc/tags.ref /runtime/doc/tags.ref
/runtime/doc/errors.log /runtime/doc/errors.log
# clint errors, generated by `make lint`
/errors.json

View File

@ -10,7 +10,7 @@ env:
# http://docs.travis-ci.com/user/speeding-up-the-build/#Paralellizing-your-build-on-one-VM # http://docs.travis-ci.com/user/speeding-up-the-build/#Paralellizing-your-build-on-one-VM
- MAKE_CMD="make -j2" - MAKE_CMD="make -j2"
# Update PATH for pip. # Update PATH for pip.
- PATH="$(python2.7 -c 'import site; print(site.getuserbase())')/bin:/usr/lib/llvm-symbolizer-3.8/bin:$PATH" - PATH="$(python2.7 -c 'import site; print(site.getuserbase())')/bin:/usr/lib/llvm-symbolizer-4.0/bin:$PATH"
# Build directory for Neovim. # Build directory for Neovim.
- BUILD_DIR="$TRAVIS_BUILD_DIR/build" - BUILD_DIR="$TRAVIS_BUILD_DIR/build"
# Build directory for third-party dependencies. # Build directory for third-party dependencies.
@ -21,13 +21,15 @@ env:
- INSTALL_PREFIX="$HOME/nvim-install" - INSTALL_PREFIX="$HOME/nvim-install"
# Log directory for Clang sanitizers and Valgrind. # Log directory for Clang sanitizers and Valgrind.
- LOG_DIR="$BUILD_DIR/log" - LOG_DIR="$BUILD_DIR/log"
# Nvim log file.
- NVIM_LOG_FILE="$BUILD_DIR/.nvimlog"
# Default CMake flags. # Default CMake flags.
- CMAKE_FLAGS="-DTRAVIS_CI_BUILD=ON - CMAKE_FLAGS="-DTRAVIS_CI_BUILD=ON
-DCMAKE_BUILD_TYPE=Debug -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX
-DBUSTED_OUTPUT_TYPE=gtest -DBUSTED_OUTPUT_TYPE=nvim
-DDEPS_PREFIX=$DEPS_BUILD_DIR/usr -DDEPS_PREFIX=$DEPS_BUILD_DIR/usr
-DMIN_LOG_LEVEL=2" -DMIN_LOG_LEVEL=3"
- DEPS_CMAKE_FLAGS="-DDEPS_DOWNLOAD_DIR:PATH=$DEPS_DOWNLOAD_DIR" - DEPS_CMAKE_FLAGS="-DDEPS_DOWNLOAD_DIR:PATH=$DEPS_DOWNLOAD_DIR"
# Additional CMake flags for 32-bit builds. # Additional CMake flags for 32-bit builds.
- CMAKE_FLAGS_32BIT="-DCMAKE_SYSTEM_LIBRARY_PATH=/lib32:/usr/lib32:/usr/local/lib32 - CMAKE_FLAGS_32BIT="-DCMAKE_SYSTEM_LIBRARY_PATH=/lib32:/usr/lib32:/usr/local/lib32
@ -43,22 +45,20 @@ env:
# If this file exists, we know that the cache contains compiled # If this file exists, we know that the cache contains compiled
# dependencies and we can use it. # dependencies and we can use it.
- CACHE_MARKER="$HOME/.cache/nvim-deps/.travis_cache_marker" - CACHE_MARKER="$HOME/.cache/nvim-deps/.travis_cache_marker"
# Test success marker. If this file exists, we know that all tests
# were successful. Required because we only want to update the cache
# if the tests were successful, but don't have this information
# available in before_cache (which is run before after_success).
- SUCCESS_MARKER="$BUILD_DIR/.tests_successful"
# default target name for functional tests # default target name for functional tests
- FUNCTIONALTEST=functionaltest - FUNCTIONALTEST=functionaltest
- CI_TARGET=tests
matrix: jobs:
include: include:
- os: linux - stage: sanitizers
env: CI_TARGET=lint os: linux
- os: linux compiler: clang-4.0
compiler: gcc-5 env: >
env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON" CLANG_SANITIZER=ASAN_UBSAN
- os: linux CMAKE_FLAGS="$CMAKE_FLAGS -DPREFER_LUA=ON"
- stage: normal builds
os: linux
compiler: gcc-5 compiler: gcc-5
env: FUNCTIONALTEST=functionaltest-lua env: FUNCTIONALTEST=functionaltest-lua
- os: linux - os: linux
@ -67,40 +67,45 @@ matrix:
# dependencies in a separate cache. # dependencies in a separate cache.
compiler: gcc-5 -m32 compiler: gcc-5 -m32
env: BUILD_32BIT=ON env: BUILD_32BIT=ON
- os: linux
compiler: clang-3.8
env: CLANG_SANITIZER=ASAN_UBSAN
- os: linux
compiler: clang-3.8
env: CLANG_SANITIZER=TSAN
- os: osx - os: osx
compiler: clang compiler: clang
osx_image: xcode7.3 # macOS 10.11 osx_image: xcode7.3 # macOS 10.11
- os: osx - os: osx
compiler: gcc-4.9 compiler: gcc-4.9
osx_image: xcode7.3 # macOS 10.11 osx_image: xcode7.3 # macOS 10.11
- stage: lint
os: linux
env: CI_TARGET=lint
- stage: Flaky builds
os: linux
compiler: gcc-5
env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON"
- os: linux
compiler: clang-4.0
env: CLANG_SANITIZER=TSAN
allow_failures: allow_failures:
- env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON" - env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON"
- env: CLANG_SANITIZER=TSAN
fast_finish: true fast_finish: true
before_install: .ci/before_install.sh before_install: ci/before_install.sh
install: .ci/install.sh install: ci/install.sh
before_script: .ci/before_script.sh before_script: ci/before_script.sh
script: .ci/script.sh script: ci/script.sh
before_cache: .ci/before_cache.sh before_cache: ci/before_cache.sh
after_success: .ci/after_success.sh after_success: ci/after_success.sh
addons: addons:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8 - llvm-toolchain-trusty-4.0
packages: packages:
- autoconf - autoconf
- automake - automake
- apport - apport
- build-essential - build-essential
- clang-3.8 - clang-4.0
- cmake - cmake
- cscope - cscope
- g++-5-multilib - g++-5-multilib
@ -108,9 +113,11 @@ addons:
- gcc-5-multilib - gcc-5-multilib
- gcc-multilib - gcc-multilib
- gdb - gdb
- language-pack-tr
- libc6-dev-i386 - libc6-dev-i386
- libtool - libtool
- llvm-3.8-dev - llvm-4.0-dev
- locales
- pkg-config - pkg-config
- unzip - unzip
- valgrind - valgrind

4
BSDmakefile Normal file
View File

@ -0,0 +1,4 @@
.DONE:
@echo "Please use GNU Make (gmake) to build neovim"
.DEFAULT:
@echo "Please use GNU Make (gmake) to build neovim"

View File

@ -51,26 +51,26 @@ endif()
# Set default build type. # Set default build type.
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
message(STATUS "CMAKE_BUILD_TYPE not given, defaulting to 'Dev'.") message(STATUS "CMAKE_BUILD_TYPE not given, defaulting to 'Debug'.")
set(CMAKE_BUILD_TYPE "Dev" CACHE STRING "Choose the type of build." FORCE) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
endif() endif()
# Set available build types for CMake GUIs. # Set available build types for CMake GUIs.
# A different build type can still be set by -DCMAKE_BUILD_TYPE=... # A different build type can still be set by -DCMAKE_BUILD_TYPE=...
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "Debug" "Dev" "Release" "MinSizeRel" "RelWithDebInfo") STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
# If not in a git repo (e.g., a tarball) these tokens define the complete # If not in a git repo (e.g., a tarball) these tokens define the complete
# version string, else they are combined with the result of `git describe`. # version string, else they are combined with the result of `git describe`.
set(NVIM_VERSION_MAJOR 0) set(NVIM_VERSION_MAJOR 0)
set(NVIM_VERSION_MINOR 2) set(NVIM_VERSION_MINOR 2)
set(NVIM_VERSION_PATCH 0) set(NVIM_VERSION_PATCH 3)
set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers
# API level # API level
set(NVIM_API_LEVEL 2) # Bump this after any API change. set(NVIM_API_LEVEL 3) # Bump this after any API change.
set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change. set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change.
set(NVIM_API_PRERELEASE true) set(NVIM_API_PRERELEASE false)
file(TO_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/.git FORCED_GIT_DIR) file(TO_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/.git FORCED_GIT_DIR)
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
@ -96,57 +96,34 @@ if(CMAKE_C_FLAGS_RELEASE MATCHES "-O3")
string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
endif() endif()
# Disable logging for release-type builds. # Minimize logging for release-type builds.
if(NOT CMAKE_C_FLAGS_RELEASE MATCHES DDISABLE_LOG) if(NOT CMAKE_C_FLAGS_RELEASE MATCHES DMIN_LOG_LEVEL)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DDISABLE_LOG") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DMIN_LOG_LEVEL=3")
endif() endif()
if(NOT CMAKE_C_FLAGS_MINSIZEREL MATCHES DDISABLE_LOG) if(NOT CMAKE_C_FLAGS_MINSIZEREL MATCHES DMIN_LOG_LEVEL)
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -DDISABLE_LOG") set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -DMIN_LOG_LEVEL=3")
endif() endif()
if(NOT CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DDISABLE_LOG) if(NOT CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DMIN_LOG_LEVEL)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DDISABLE_LOG") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DMIN_LOG_LEVEL=3")
endif() endif()
# Enable assertions for RelWithDebInfo. if(CMAKE_COMPILER_IS_GNUCC)
check_c_compiler_flag(-Og HAS_OG_FLAG)
else()
set(HAS_OG_FLAG 0)
endif()
#
# Build-type: RelWithDebInfo
#
if(HAS_OG_FLAG)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -Og -g")
endif()
# We _want_ assertions in RelWithDebInfo build-type.
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG) if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG)
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endif() endif()
# Set build flags for custom Dev build type.
# -DNDEBUG purposely omitted because we want assertions.
if(MSVC)
SET(CMAKE_C_FLAGS_DEV ""
CACHE STRING "Flags used by the compiler during development (optimized, but with debug info and logging) builds."
FORCE)
else()
if(CMAKE_COMPILER_IS_GNUCC)
check_c_compiler_flag(-Og HAS_OG_FLAG)
else()
set(HAS_OG_FLAG 0)
endif()
if(HAS_OG_FLAG)
set(CMAKE_C_FLAGS_DEV "-Og -g"
CACHE STRING "Flags used by the compiler during development (optimized, but with debug info and logging) builds."
FORCE)
else()
set(CMAKE_C_FLAGS_DEV "-O2 -g"
CACHE STRING "Flags used by the compiler during development (optimized, but with debug info and logging) builds."
FORCE)
endif()
endif()
SET(CMAKE_EXE_LINKER_FLAGS_DEV ""
CACHE STRING "Flags used for linking binaries during development (optimized, but with debug info and logging) builds."
FORCE)
SET(CMAKE_SHARED_LINKER_FLAGS_DEV ""
CACHE STRING "Flags used by the shared libraries linker during development (optimized, but with debug info and logging) builds."
FORCE)
MARK_AS_ADVANCED(
CMAKE_C_FLAGS_DEV
CMAKE_EXE_LINKER_FLAGS_DEV
CMAKE_SHARED_LINKER_FLAGS_DEV)
# Enable -Wconversion. # Enable -Wconversion.
if(NOT MSVC) if(NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion")
@ -214,6 +191,16 @@ if(CMAKE_EXE_LINKER_FLAGS MATCHES "--sort-common" OR
string(REGEX REPLACE "-Wl($| )" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}") string(REGEX REPLACE "-Wl($| )" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
endif() endif()
check_c_source_compiles("
#include <execinfo.h>
int main(void)
{
void *trace[1];
int trace_size = backtrace(trace, 1);
return 0;
}
" HAVE_EXECINFO_BACKTRACE)
if(MSVC) if(MSVC)
# XXX: /W4 gives too many warnings. #3241 # XXX: /W4 gives too many warnings. #3241
add_definitions(/W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(/W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
@ -221,9 +208,14 @@ else()
add_definitions(-Wall -Wextra -pedantic -Wno-unused-parameter add_definitions(-Wall -Wextra -pedantic -Wno-unused-parameter
-Wstrict-prototypes -std=gnu99) -Wstrict-prototypes -std=gnu99)
check_c_compiler_flag(-Wimplicit-fallthrough HAS_WIMPLICIT_FALLTHROUGH_FLAG)
if(HAS_WIMPLICIT_FALLTHROUGH_FLAG)
add_definitions(-Wimplicit-fallthrough)
endif()
# On FreeBSD 64 math.h uses unguarded C11 extension, which taints clang # On FreeBSD 64 math.h uses unguarded C11 extension, which taints clang
# 3.4.1 used there. # 3.4.1 used there.
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND CMAKE_C_COMPILER_ID MATCHES "Clang")
add_definitions(-Wno-c11-extensions) add_definitions(-Wno-c11-extensions)
endif() endif()
endif() endif()
@ -257,6 +249,17 @@ if(HAS_DIAG_COLOR_FLAG)
add_definitions(-fdiagnostics-color=auto) add_definitions(-fdiagnostics-color=auto)
endif() endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.5")
# Array-bounds testing is broken in some GCC versions before 4.8.5.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
check_c_compiler_flag(-Wno-array-bounds HAS_NO_ARRAY_BOUNDS_FLAG)
if(HAS_NO_ARRAY_BOUNDS_FLAG)
add_definitions(-Wno-array-bounds)
endif()
endif()
endif()
option(TRAVIS_CI_BUILD "Travis/QuickBuild CI. Extra flags will be set." OFF) option(TRAVIS_CI_BUILD "Travis/QuickBuild CI. Extra flags will be set." OFF)
if(TRAVIS_CI_BUILD) if(TRAVIS_CI_BUILD)
@ -275,7 +278,6 @@ else()
endif() endif()
add_definitions(-DINCLUDE_GENERATED_DECLARATIONS) add_definitions(-DINCLUDE_GENERATED_DECLARATIONS)
add_definitions(-DHAVE_CONFIG_H)
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_NAME STREQUAL "Linux") if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
@ -310,16 +312,55 @@ include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
find_package(Msgpack 1.0.0 REQUIRED) find_package(Msgpack 1.0.0 REQUIRED)
include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS}) include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS})
if(UNIX) # Note: The test lib requires LuaJIT; it will be skipped if LuaJIT is missing.
option(FEAT_TUI "Enable the Terminal UI" ON) option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF)
if(PREFER_LUA)
find_package(Lua REQUIRED)
set(LUA_PREFERRED_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
set(LUA_PREFERRED_LIBRARIES ${LUA_LIBRARIES})
find_package(LuaJit)
else() else()
option(FEAT_TUI "Enable the Terminal UI" OFF) find_package(LuaJit REQUIRED)
set(LUA_PREFERRED_INCLUDE_DIRS ${LUAJIT_INCLUDE_DIRS})
set(LUA_PREFERRED_LIBRARIES ${LUAJIT_LIBRARIES})
endif() endif()
list(APPEND CMAKE_REQUIRED_INCLUDES "${MSGPACK_INCLUDE_DIRS}")
check_c_source_compiles("
#include <msgpack.h>
int
main(void)
{
return MSGPACK_OBJECT_FLOAT32;
}
" MSGPACK_HAS_FLOAT32)
if(MSGPACK_HAS_FLOAT32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNVIM_MSGPACK_HAS_FLOAT32")
endif()
option(FEAT_TUI "Enable the Terminal UI" ON)
if(FEAT_TUI) if(FEAT_TUI)
find_package(Unibilium REQUIRED) find_package(Unibilium REQUIRED)
include_directories(SYSTEM ${UNIBILIUM_INCLUDE_DIRS}) include_directories(SYSTEM ${UNIBILIUM_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES "${UNIBILIUM_INCLUDE_DIRS}")
list(APPEND CMAKE_REQUIRED_LIBRARIES "${UNIBILIUM_LIBRARIES}")
check_c_source_compiles("
#include <unibilium.h>
int
main(void)
{
return unibi_num_from_var(unibi_var_from_num(0));
}
" UNIBI_HAS_VAR_FROM)
if(UNIBI_HAS_VAR_FROM)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNVIM_UNIBI_HAS_VAR_FROM")
endif()
find_package(LibTermkey REQUIRED) find_package(LibTermkey REQUIRED)
include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS}) include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS})
endif() endif()
@ -327,6 +368,11 @@ endif()
find_package(LibVterm REQUIRED) find_package(LibVterm REQUIRED)
include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS}) include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS})
if(WIN32)
find_package(Winpty REQUIRED)
include_directories(SYSTEM ${WINPTY_INCLUDE_DIRS})
endif()
option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF) option(CLANG_ASAN_UBSAN "Enable Clang address & undefined behavior sanitizer for nvim binary." OFF)
option(CLANG_MSAN "Enable Clang memory sanitizer for nvim binary." OFF) option(CLANG_MSAN "Enable Clang memory sanitizer for nvim binary." OFF)
option(CLANG_TSAN "Enable Clang thread sanitizer for nvim binary." OFF) option(CLANG_TSAN "Enable Clang thread sanitizer for nvim binary." OFF)
@ -416,11 +462,7 @@ message(STATUS "Using the Lua interpreter ${LUA_PRG}.")
find_program(BUSTED_PRG NAMES busted busted.bat) find_program(BUSTED_PRG NAMES busted busted.bat)
find_program(BUSTED_LUA_PRG busted-lua) find_program(BUSTED_LUA_PRG busted-lua)
if(NOT BUSTED_OUTPUT_TYPE) if(NOT BUSTED_OUTPUT_TYPE)
if(WIN32) set(BUSTED_OUTPUT_TYPE "nvim")
set(BUSTED_OUTPUT_TYPE "plainTerminal")
else()
set(BUSTED_OUTPUT_TYPE "utfTerminal")
endif()
endif() endif()
find_program(LUACHECK_PRG luacheck) find_program(LUACHECK_PRG luacheck)
@ -431,26 +473,24 @@ include(InstallHelpers)
file(GLOB MANPAGES file(GLOB MANPAGES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
man/nvim.1) man/nvim.1)
install_helper( install_helper(
FILES ${MANPAGES} FILES ${MANPAGES}
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
# MIN_LOG_LEVEL for log.h # MIN_LOG_LEVEL for log.h
if(DEFINED MIN_LOG_LEVEL) if("${MIN_LOG_LEVEL}" MATCHES "^$")
message(STATUS "MIN_LOG_LEVEL not specified")
else()
if(NOT MIN_LOG_LEVEL MATCHES "^[0-3]$") if(NOT MIN_LOG_LEVEL MATCHES "^[0-3]$")
message(FATAL_ERROR "MIN_LOG_LEVEL must be a number 0-3") message(FATAL_ERROR "invalid MIN_LOG_LEVEL: " ${MIN_LOG_LEVEL})
endif() endif()
message(STATUS "MIN_LOG_LEVEL set to ${MIN_LOG_LEVEL}") message(STATUS "MIN_LOG_LEVEL set to ${MIN_LOG_LEVEL}")
else()
message(STATUS "MIN_LOG_LEVEL not specified, defaulting to INFO(1)")
endif() endif()
# Go down the tree. # Go down the tree.
add_subdirectory(src/nvim) add_subdirectory(src/nvim)
# Read compilation flags from src/nvim, # Read compilation flags from src/nvim, used in config subdirectory below.
# used in config subdirectory below.
include(GetCompileFlags) include(GetCompileFlags)
get_compile_flags(NVIM_VERSION_CFLAGS) get_compile_flags(NVIM_VERSION_CFLAGS)
@ -576,9 +616,26 @@ if(LUACHECK_PRG)
add_custom_target(testlint add_custom_target(testlint
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DLUACHECK_PRG=${LUACHECK_PRG} -DLUACHECK_PRG=${LUACHECK_PRG}
-DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test -DLUAFILES_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
-DIGNORE_PATTERN="*/preload.lua"
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-P ${PROJECT_SOURCE_DIR}/cmake/RunTestsLint.cmake) -P ${PROJECT_SOURCE_DIR}/cmake/RunLuacheck.cmake)
add_custom_target(
blobcodelint
COMMAND
${CMAKE_COMMAND}
-DLUACHECK_PRG=${LUACHECK_PRG}
-DLUAFILES_DIR=${CMAKE_CURRENT_SOURCE_DIR}/src/nvim/lua
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DREAD_GLOBALS=vim
-P ${PROJECT_SOURCE_DIR}/cmake/RunLuacheck.cmake
)
# TODO(ZyX-I): Run linter for all lua code in src
add_custom_target(
lualint
DEPENDS blobcodelint
)
endif() endif()
set(CPACK_PACKAGE_NAME "Neovim") set(CPACK_PACKAGE_NAME "Neovim")

View File

@ -6,10 +6,16 @@ Getting started
If you want to help but don't know where to start, here are some If you want to help but don't know where to start, here are some
low-risk/isolated tasks: low-risk/isolated tasks:
- Help us [review pull requests](#reviewing)! - [Merge a Vim patch].
- Merge a [Vim patch].
- Try a [complexity:low] issue. - Try a [complexity:low] issue.
- Fix [clang-scan] or [coverity](#coverity) warnings. - Fix bugs found by [clang scan-build](#clang-scan-build),
[coverity](#coverity), and [PVS](#pvs-studio).
Developer guidelines
--------------------
- Nvim developers should read `:help dev-help`.
- External UI developers should read `:help dev-ui`.
Reporting problems Reporting problems
------------------ ------------------
@ -17,26 +23,33 @@ Reporting problems
- Check the [**FAQ**][wiki-faq]. - Check the [**FAQ**][wiki-faq].
- Search [existing issues][github-issues] (including closed!) - Search [existing issues][github-issues] (including closed!)
- Update Neovim to the latest version to see if your problem persists. - Update Neovim to the latest version to see if your problem persists.
- If you're using a plugin manager, comment out your plugins, then add them back - Disable plugins incrementally, to narrow down the cause of the issue.
in one by one, to narrow down the cause of the issue. - When reporting a crash, include a stacktrace.
- Crash reports which include a stacktrace are 10x more valuable. - [Bisect][git-bisect] to the cause of a regression, if you are able. This is _extremely_ helpful.
- [Bisecting][git-bisect] to the cause of a regression often leads to an - Check `$NVIM_LOG_FILE`, if it exists.
immediate fix. - Include `cmake --system-information` for **build** issues.
Pull requests ("PRs") Pull requests ("PRs")
--------------------- ---------------------
- To avoid duplicate work, you may want to create a `[WIP]` pull request so that - To avoid duplicate work, create a `[WIP]` pull request as soon as possible.
others know what you are working on. - Avoid cosmetic changes to unrelated files in the same commit.
- Avoid cosmetic changes to unrelated files in the same commit: extra noise
makes reviews more difficult.
- Use a [feature branch][git-feature-branch] instead of the master branch. - Use a [feature branch][git-feature-branch] instead of the master branch.
- [Rebase your feature branch][git-rebasing] onto (upstream) master before - Use a **rebase workflow** for small PRs.
opening the PR. - After addressing review comments, it's fine to rebase and force-push.
- After addressing the review comments, it's fine to rebase and force-push to - Use a **merge workflow** for big, high-risk PRs.
your review. - Merge `master` into your PR when there are conflicts or when master
- Try to [tidy your history][git-history-rewriting]: combine related commits introduces breaking changes.
with interactive rebasing, separate monolithic commits, etc. - Use the `ri` git alias:
```
[alias]
ri = "!sh -c 't=\"${1:-master}\"; s=\"${2:-HEAD}\"; mb=\"$(git merge-base \"$t\" \"$s\")\"; if test \"x$mb\" = x ; then o=\"$t\"; else lm=\"$(git log -n1 --merges \"$t..$s\" --pretty=%H)\"; if test \"x$lm\" = x ; then o=\"$mb\"; else o=\"$lm\"; fi; fi; test $# -gt 0 && shift; test $# -gt 0 && shift; git rebase --interactive \"$o\" \"$@\"'"
```
This avoids unnecessary rebases yet still allows you to combine related
commits, separate monolithic commits, etc.
- Do not edit commits that come before the merge commit.
- During a squash/fixup, use `exec make -C build unittest` between each
pick/edit/reword.
### Stages: WIP, RFC, RDY ### Stages: WIP, RFC, RDY
@ -73,16 +86,18 @@ the VCS/git logs more valuable.
### Automated builds (CI) ### Automated builds (CI)
Each pull request must pass the automated builds ([travis CI] and [quickbuild]). Each pull request must pass the automated builds on [travis CI], [quickbuild]
and [AppVeyor].
- CI builds are compiled with [`-Werror`][gcc-warnings], so if your PR - CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings
introduces any compiler warnings, the build will fail. will fail the build.
- If any tests fail, the build will fail. - If any tests fail, the build will fail.
See [Building Neovim#running-tests][wiki-run-tests] to run tests locally. See [Building Neovim#running-tests][wiki-run-tests] to run tests locally.
Passing locally doesn't guarantee passing the CI build, because of the Passing locally doesn't guarantee passing the CI build, because of the
different compilers and platforms tested against. different compilers and platforms tested against.
- CI runs [ASan] and other analyzers. To run valgrind locally: - CI runs [ASan] and other analyzers.
`VALGRIND=1 make test` - To run valgrind locally: `VALGRIND=1 make test`
- To run Clang ASan/UBSan locally: `CC=clang make CMAKE_FLAGS="-DCLANG_ASAN_UBSAN=ON"`
- The `lint` build ([#3174][3174]) checks modified lines _and their immediate - The `lint` build ([#3174][3174]) checks modified lines _and their immediate
neighbors_. This is to encourage incrementally updating the legacy style to neighbors_. This is to encourage incrementally updating the legacy style to
meet our style guidelines. meet our style guidelines.
@ -99,11 +114,19 @@ QuickBuild uses this invocation:
VERBOSE=1 nvim unittest-prereqs functionaltest-prereqs VERBOSE=1 nvim unittest-prereqs functionaltest-prereqs
### Clang scan-build
The auto-generated [clang-scan] report presents walk-throughs of bugs found by
Clang's [scan-build](https://clang-analyzer.llvm.org/scan-build.html) static
analyzer. To verify a fix locally, run `scan-build` like this:
rm -rf build/
scan-build --use-analyzer=/usr/bin/clang make
### Coverity ### Coverity
[Coverity](https://scan.coverity.com/projects/neovim-neovim) runs against the [Coverity](https://scan.coverity.com/projects/neovim-neovim) runs against the
master build. If you want to view the defects, just request access at the master build. To view the defects, just request access; you will be approved.
_Contributor_ level. An Admin will grant you permission.
Use this commit-message format for coverity fixes: Use this commit-message format for coverity fixes:
@ -111,6 +134,12 @@ Use this commit-message format for coverity fixes:
where `<id>` is the Coverity ID (CID). For example see [#804](https://github.com/neovim/neovim/pull/804). where `<id>` is the Coverity ID (CID). For example see [#804](https://github.com/neovim/neovim/pull/804).
### PVS-Studio
View the [PVS analysis report](https://neovim.io/doc/reports/pvs/) to see bugs
found by [PVS Studio](https://www.viva64.com/en/pvs-studio/).
You can run `scripts/pvscheck.sh` locally to run PVS on your machine.
Reviewing Reviewing
--------- ---------
@ -145,6 +174,7 @@ as context, use the `-W` argument as well.
[3174]: https://github.com/neovim/neovim/issues/3174 [3174]: https://github.com/neovim/neovim/issues/3174
[travis CI]: https://travis-ci.org/neovim/neovim [travis CI]: https://travis-ci.org/neovim/neovim
[quickbuild]: http://neovim-qb.szakmeister.net/dashboard [quickbuild]: http://neovim-qb.szakmeister.net/dashboard
[Vim patch]: https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-Vim [AppVeyor]: https://ci.appveyor.com/project/neovim/neovim
[Merge a Vim patch]: https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-Vim
[clang-scan]: https://neovim.io/doc/reports/clang/ [clang-scan]: https://neovim.io/doc/reports/clang/
[complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow [complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow

View File

@ -1,16 +1,19 @@
<!-- Before reporting: search existing issues and check the FAQ. -->
- `nvim --version`: - `nvim --version`:
- Vim (version: ) behaves differently? - Vim (version: ) behaves differently?
- Operating system/version: - Operating system/version:
- Terminal name/version: - Terminal name/version:
- `$TERM`: - `$TERM`:
### Actual behaviour
### Expected behaviour
### Steps to reproduce using `nvim -u NORC` ### Steps to reproduce using `nvim -u NORC`
``` ```
nvim -u NORC nvim -u NORC
``` ```
### Actual behaviour
### Expected behaviour

View File

@ -107,6 +107,9 @@ functionaltest-lua: | nvim
testlint: | build/.ran-cmake deps testlint: | build/.ran-cmake deps
$(BUILD_CMD) -C build testlint $(BUILD_CMD) -C build testlint
lualint: | build/.ran-cmake deps
$(BUILD_CMD) -C build lualint
unittest: | nvim unittest: | nvim
+$(BUILD_CMD) -C build unittest +$(BUILD_CMD) -C build unittest
@ -126,12 +129,18 @@ distclean: clean
install: | nvim install: | nvim
+$(BUILD_CMD) -C build install +$(BUILD_CMD) -C build install
clint: clint: build/.ran-cmake
$(CMAKE_PRG) -DLINT_PRG=./src/clint.py \ +$(BUILD_CMD) -C build clint
-DLINT_DIR=src \
-DLINT_SUPPRESS_URL="$(DOC_DOWNLOAD_URL_BASE)$(CLINT_ERRORS_FILE_PATH)" \
-P cmake/RunLint.cmake
lint: clint testlint clint-full: build/.ran-cmake
+$(BUILD_CMD) -C build clint-full
.PHONY: test testlint functionaltest unittest lint clint clean distclean nvim libnvim cmake deps install check-single-includes: build/.ran-cmake
+$(BUILD_CMD) -C build check-single-includes
appimage:
bash scripts/genappimage.sh
lint: check-single-includes clint testlint lualint
.PHONY: test testlint lualint functionaltest unittest lint clint clean distclean nvim libnvim cmake deps install appimage

View File

@ -8,11 +8,13 @@
[![Travis Build Status](https://travis-ci.org/neovim/neovim.svg?branch=master)](https://travis-ci.org/neovim/neovim) [![Travis Build Status](https://travis-ci.org/neovim/neovim.svg?branch=master)](https://travis-ci.org/neovim/neovim)
[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/urdqjrik5u521fac/branch/master?svg=true)](https://ci.appveyor.com/project/neovim/neovim/branch/master) [![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/urdqjrik5u521fac/branch/master?svg=true)](https://ci.appveyor.com/project/neovim/neovim/branch/master)
[![Pull requests waiting for review](https://badge.waffle.io/neovim/neovim.svg?label=RFC&title=RFCs)](https://waffle.io/neovim/neovim) [![codecov](https://img.shields.io/codecov/c/github/neovim/neovim.svg)](https://codecov.io/gh/neovim/neovim)
[![Coverage Status](https://img.shields.io/coveralls/neovim/neovim.svg)](https://coveralls.io/r/neovim/neovim)
[![Coverity Scan Build](https://scan.coverity.com/projects/2227/badge.svg)](https://scan.coverity.com/projects/2227) [![Coverity Scan Build](https://scan.coverity.com/projects/2227/badge.svg)](https://scan.coverity.com/projects/2227)
[![Clang Scan Build](https://neovim.io/doc/reports/clang/badge.svg)](https://neovim.io/doc/reports/clang) [![Clang Scan Build](https://neovim.io/doc/reports/clang/badge.svg)](https://neovim.io/doc/reports/clang)
<a href="https://buildd.debian.org/neovim"><img src="https://www.debian.org/logos/openlogo-nd-25.png" width="13" height="15">Debian</a> [![PVS-studio Check](https://neovim.io/doc/reports/pvs/badge.svg)](https://neovim.io/doc/reports/pvs)
[![Debian CI](https://badges.debian.net/badges/debian/testing/neovim/version.svg)](https://buildd.debian.org/neovim)
[![Downloads](https://img.shields.io/github/downloads/neovim/neovim/total.svg?maxAge=2592000)](https://github.com/neovim/neovim/releases/)
Neovim is a project that seeks to aggressively refactor Vim in order to: Neovim is a project that seeks to aggressively refactor Vim in order to:
@ -32,39 +34,58 @@ Install from source
make CMAKE_BUILD_TYPE=RelWithDebInfo make CMAKE_BUILD_TYPE=RelWithDebInfo
sudo make install sudo make install
To install to a non-default location, specify `CMAKE_INSTALL_PREFIX`:
make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=/full/path/"
make install
See [the wiki](https://github.com/neovim/neovim/wiki/Building-Neovim) for details. See [the wiki](https://github.com/neovim/neovim/wiki/Building-Neovim) for details.
Install from package Install from package
-------------------- --------------------
Packages are in [Homebrew], [Debian], [Ubuntu], [Fedora], [Arch Linux], and Pre-built packages for Windows, macOS, and Linux are found at the
[more](https://github.com/neovim/neovim/wiki/Installing-Neovim). [Releases](https://github.com/neovim/neovim/releases/) page.
Managed packages are in [Homebrew], [Debian], [Ubuntu], [Fedora], [Arch Linux], [Gentoo],
and [more](https://github.com/neovim/neovim/wiki/Installing-Neovim)!
Project layout Project layout
-------------- --------------
- `.ci/`: Build server scripts ├─ ci/ build automation
- `cmake/`: Build scripts ├─ cmake/ build scripts
- `runtime/`: Application files ├─ runtime/ user plugins/docs
- [`src/`](src/nvim/README.md): Application source code ├─ src/ application source code (see src/nvim/README.md)
- `third-party/`: CMake sub-project to build third-party dependencies (if the │ ├─ api/ API subsystem
`USE_BUNDLED_DEPS` flag is undefined or `USE_BUNDLED` CMake option is false). │ ├─ eval/ VimL subsystem
- [`test/`](test/README.md): Test files │ ├─ event/ event-loop subsystem
│ ├─ generators/ code generation (pre-compilation)
│ ├─ lib/ generic data structures
│ ├─ lua/ lua subsystem
│ ├─ msgpack_rpc/ RPC subsystem
│ ├─ os/ low-level platform code
│ └─ tui/ built-in UI
├─ third-party/ cmake subproject to build dependencies
└─ test/ tests (see test/README.md)
What's been done so far - To disable `third-party/` specify `USE_BUNDLED_DEPS=NO` or `USE_BUNDLED=NO`
----------------------- (CMake option).
- RPC API based on [MessagePack](https://msgpack.org) Features
- Embedded [terminal emulator](https://neovim.io/doc/user/nvim_terminal_emulator.html) --------
- Modern [GUIs](https://github.com/neovim/neovim/wiki/Related-projects#gui)
- [API](https://github.com/neovim/neovim/wiki/Related-projects#api-clients)
access from any language including clojure, lisp, go, haskell, lua,
javascript, perl, python, ruby, rust.
- Embedded, scriptable [terminal emulator](https://neovim.io/doc/user/nvim_terminal_emulator.html)
- Asynchronous [job control](https://github.com/neovim/neovim/pull/2247) - Asynchronous [job control](https://github.com/neovim/neovim/pull/2247)
- [Shared data (shada)](https://github.com/neovim/neovim/pull/2506) among multiple editor instances - [Shared data (shada)](https://github.com/neovim/neovim/pull/2506) among multiple editor instances
- [XDG base directories](https://github.com/neovim/neovim/pull/3470) support - [XDG base directories](https://github.com/neovim/neovim/pull/3470) support
- [libuv](https://github.com/libuv/libuv/)-based platform/OS layer - Compatible with most Vim plugins, including Ruby and Python plugins.
- [Pushdown automaton](https://github.com/neovim/neovim/pull/3413) input model
- 1000s of new tests
- Legacy tests converted to Lua tests
See [`:help nvim-features`][nvim-features] for a comprehensive list. See [`:help nvim-features`][nvim-features] for the full list!
License License
------- -------
@ -95,11 +116,12 @@ See `LICENSE` for details.
[license-commit]: https://github.com/neovim/neovim/commit/b17d9691a24099c9210289f16afb1a498a89d803 [license-commit]: https://github.com/neovim/neovim/commit/b17d9691a24099c9210289f16afb1a498a89d803
[nvim-features]: https://neovim.io/doc/user/vim_diff.html#nvim-features [nvim-features]: https://neovim.io/doc/user/vim_diff.html#nvim-features
[Roadmap]: https://neovim.io/roadmap/ [Roadmap]: https://neovim.io/roadmap/
[advanced UIs]: https://github.com/neovim/neovim/wiki/Related-projects#gui-projects [advanced UIs]: https://github.com/neovim/neovim/wiki/Related-projects#gui
[Homebrew]: https://github.com/neovim/homebrew-neovim#installation [Homebrew]: https://github.com/neovim/homebrew-neovim#installation
[Debian]: https://packages.debian.org/testing/neovim [Debian]: https://packages.debian.org/testing/neovim
[Ubuntu]: http://packages.ubuntu.com/search?keywords=neovim [Ubuntu]: http://packages.ubuntu.com/search?keywords=neovim
[Fedora]: https://admin.fedoraproject.org/pkgdb/package/rpms/neovim [Fedora]: https://admin.fedoraproject.org/pkgdb/package/rpms/neovim
[Arch Linux]: https://www.archlinux.org/packages/?q=neovim [Arch Linux]: https://www.archlinux.org/packages/?q=neovim
[Gentoo]: https://packages.gentoo.org/packages/app-editors/neovim
<!-- vim: set tw=80: --> <!-- vim: set tw=80: -->

View File

@ -1,13 +1,19 @@
version: '{build}' version: '{build}'
environment:
APPVEYOR_CACHE_ENTRY_ZIP_ARGS: "-t7z -m0=lzma -mx=9"
configuration: configuration:
- MINGW_64 - MINGW_64
- MINGW_32 - MINGW_32
- MINGW_64-gcov
matrix:
allow_failures:
- configuration: MINGW_64-gcov
install: [] install: []
build_script: build_script:
- call .ci\build.bat - call ci\build.bat
cache: cache:
- C:\msys64\var\cache\pacman\pkg -> .ci\build.bat - C:\msys64\var\cache\pacman\pkg -> ci\build.bat
- .deps -> third-party/CMakeLists.txt - .deps -> third-party\**
artifacts: artifacts:
- path: build/Neovim.zip - path: build/Neovim.zip
- path: build/bin/nvim.exe - path: build/bin/nvim.exe

View File

@ -0,0 +1,92 @@
-- TODO(jkeyes): remove this and use the upstream version as soon as it is
-- available in a release of busted.
local pretty = require 'pl.pretty'
return function(options)
local busted = require 'busted'
local handler = require 'busted.outputHandlers.base'()
local success = 'ok %u - %s'
local failure = 'not ' .. success
local skip = 'ok %u - # SKIP %s'
local counter = 0
handler.suiteReset = function()
counter = 0
return nil, true
end
handler.suiteEnd = function()
print('1..' .. counter)
io.flush()
return nil, true
end
local function showFailure(t)
local message = t.message
local trace = t.trace or {}
if message == nil then
message = 'Nil error'
elseif type(message) ~= 'string' then
message = pretty.write(message)
end
print(failure:format(counter, t.name))
print('# ' .. t.element.trace.short_src .. ' @ ' .. t.element.trace.currentline)
if t.randomseed then print('# Random seed: ' .. t.randomseed) end
print('# Failure message: ' .. message:gsub('\n', '\n# '))
if options.verbose and trace.traceback then
print('# ' .. trace.traceback:gsub('^\n', '', 1):gsub('\n', '\n# '))
end
end
handler.testStart = function(element, parent)
local trace = element.trace
if options.verbose and trace and trace.short_src then
local fileline = trace.short_src .. ' @ ' .. trace.currentline .. ': '
local testName = fileline .. handler.getFullName(element)
print('# ' .. testName)
end
io.flush()
return nil, true
end
handler.testEnd = function(element, parent, status, trace)
counter = counter + 1
if status == 'success' then
local t = handler.successes[#handler.successes]
print(success:format(counter, t.name))
elseif status == 'pending' then
local t = handler.pendings[#handler.pendings]
print(skip:format(counter, (t.message or t.name)))
elseif status == 'failure' then
showFailure(handler.failures[#handler.failures])
elseif status == 'error' then
showFailure(handler.errors[#handler.errors])
end
io.flush()
return nil, true
end
handler.error = function(element, parent, message, debug)
if element.descriptor ~= 'it' then
counter = counter + 1
showFailure(handler.errors[#handler.errors])
end
io.flush()
return nil, true
end
busted.subscribe({ 'suite', 'reset' }, handler.suiteReset)
busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)
busted.subscribe({ 'test', 'start' }, handler.testStart, { predicate = handler.cancelOnPending })
busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending })
busted.subscribe({ 'error' }, handler.error)
return handler
end

View File

@ -0,0 +1,305 @@
local s = require 'say'
local pretty = require 'pl.pretty'
local term = require 'term'
local colors
local isWindows = package.config:sub(1,1) == '\\'
if isWindows then
colors = setmetatable({}, {__index = function() return function(s) return s end end})
else
colors = require 'term.colors'
end
return function(options)
local busted = require 'busted'
local handler = require 'busted.outputHandlers.base'()
local c = {
succ = function(s) return colors.bright(colors.green(s)) end,
skip = function(s) return colors.bright(colors.yellow(s)) end,
fail = function(s) return colors.bright(colors.magenta(s)) end,
errr = function(s) return colors.bright(colors.red(s)) end,
test = tostring,
file = colors.cyan,
time = colors.dim,
note = colors.yellow,
sect = function(s) return colors.green(colors.dim(s)) end,
nmbr = colors.bright,
}
local repeatSuiteString = '\nRepeating all tests (run %d of %d) . . .\n\n'
local randomizeString = c.note('Note: Randomizing test order with a seed of %d.\n')
local globalSetup = c.sect('[----------]') .. ' Global test environment setup.\n'
local fileStartString = c.sect('[----------]') .. ' Running tests from ' .. c.file('%s') .. '\n'
local runString = c.sect('[ RUN ]') .. ' ' .. c.test('%s') .. ': '
local successString = c.succ('OK') .. '\n'
local skippedString = c.skip('SKIP') .. '\n'
local failureString = c.fail('FAIL') .. '\n'
local errorString = c.errr('ERR') .. '\n'
local fileEndString = c.sect('[----------]') .. ' '.. c.nmbr('%d') .. ' %s from ' .. c.file('%s') .. ' ' .. c.time('(%.2f ms total)') .. '\n\n'
local globalTeardown = c.sect('[----------]') .. ' Global test environment teardown.\n'
local suiteEndString = c.sect('[==========]') .. ' ' .. c.nmbr('%d') .. ' %s from ' .. c.nmbr('%d') .. ' test %s ran. ' .. c.time('(%.2f ms total)') .. '\n'
local successStatus = c.succ('[ PASSED ]') .. ' ' .. c.nmbr('%d') .. ' %s.\n'
local timeString = c.time('%.2f ms')
local summaryStrings = {
skipped = {
header = c.skip('[ SKIPPED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
test = c.skip('[ SKIPPED ]') .. ' %s\n',
footer = ' ' .. c.nmbr('%d') .. ' SKIPPED %s\n',
},
failure = {
header = c.fail('[ FAILED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
test = c.fail('[ FAILED ]') .. ' %s\n',
footer = ' ' .. c.nmbr('%d') .. ' FAILED %s\n',
},
error = {
header = c.errr('[ ERROR ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
test = c.errr('[ ERROR ]') .. ' %s\n',
footer = ' ' .. c.nmbr('%d') .. ' %s\n',
},
}
c = nil
local fileCount = 0
local fileTestCount = 0
local testCount = 0
local successCount = 0
local skippedCount = 0
local failureCount = 0
local errorCount = 0
local pendingDescription = function(pending)
local name = pending.name
local string = ''
if type(pending.message) == 'string' then
string = string .. pending.message .. '\n'
elseif pending.message ~= nil then
string = string .. pretty.write(pending.message) .. '\n'
end
return string
end
local failureDescription = function(failure)
local string = failure.randomseed and ('Random seed: ' .. failure.randomseed .. '\n') or ''
if type(failure.message) == 'string' then
string = string .. failure.message
elseif failure.message == nil then
string = string .. 'Nil error'
else
string = string .. pretty.write(failure.message)
end
string = string .. '\n'
if options.verbose and failure.trace and failure.trace.traceback then
string = string .. failure.trace.traceback .. '\n'
end
return string
end
local getFileLine = function(element)
local fileline = ''
if element.trace or element.trace.short_src then
fileline = colors.cyan(element.trace.short_src) .. ' @ ' ..
colors.cyan(element.trace.currentline) .. ': '
end
return fileline
end
local getTestList = function(status, count, list, getDescription)
local string = ''
local header = summaryStrings[status].header
if count > 0 and header then
local tests = (count == 1 and 'test' or 'tests')
local errors = (count == 1 and 'error' or 'errors')
string = header:format(count, status == 'error' and errors or tests)
local testString = summaryStrings[status].test
if testString then
for _, t in ipairs(list) do
local fullname = getFileLine(t.element) .. colors.bright(t.name)
string = string .. testString:format(fullname)
string = string .. getDescription(t)
end
end
end
return string
end
local getSummary = function(status, count)
local string = ''
local footer = summaryStrings[status].footer
if count > 0 and footer then
local tests = (count == 1 and 'TEST' or 'TESTS')
local errors = (count == 1 and 'ERROR' or 'ERRORS')
string = footer:format(count, status == 'error' and errors or tests)
end
return string
end
local getSummaryString = function()
local tests = (successCount == 1 and 'test' or 'tests')
local string = successStatus:format(successCount, tests)
string = string .. getTestList('skipped', skippedCount, handler.pendings, pendingDescription)
string = string .. getTestList('failure', failureCount, handler.failures, failureDescription)
string = string .. getTestList('error', errorCount, handler.errors, failureDescription)
string = string .. ((skippedCount + failureCount + errorCount) > 0 and '\n' or '')
string = string .. getSummary('skipped', skippedCount)
string = string .. getSummary('failure', failureCount)
string = string .. getSummary('error', errorCount)
return string
end
handler.suiteReset = function()
fileCount = 0
fileTestCount = 0
testCount = 0
successCount = 0
skippedCount = 0
failureCount = 0
errorCount = 0
return nil, true
end
handler.suiteStart = function(suite, count, total, randomseed)
if total > 1 then
io.write(repeatSuiteString:format(count, total))
end
if randomseed then
io.write(randomizeString:format(randomseed))
end
io.write(globalSetup)
io.flush()
return nil, true
end
local function getElapsedTime(tbl)
if tbl.duration then
return tbl.duration * 1000
else
return tonumber('nan')
end
end
handler.suiteEnd = function(suite, count, total)
local elapsedTime_ms = getElapsedTime(suite)
local tests = (testCount == 1 and 'test' or 'tests')
local files = (fileCount == 1 and 'file' or 'files')
io.write(globalTeardown)
io.write(suiteEndString:format(testCount, tests, fileCount, files, elapsedTime_ms))
io.write(getSummaryString())
io.flush()
return nil, true
end
handler.fileStart = function(file)
fileTestCount = 0
io.write(fileStartString:format(file.name))
io.flush()
return nil, true
end
handler.fileEnd = function(file)
local elapsedTime_ms = getElapsedTime(file)
local tests = (fileTestCount == 1 and 'test' or 'tests')
fileCount = fileCount + 1
io.write(fileEndString:format(fileTestCount, tests, file.name, elapsedTime_ms))
io.flush()
return nil, true
end
handler.testStart = function(element, parent)
io.write(runString:format(handler.getFullName(element)))
io.flush()
return nil, true
end
handler.testEnd = function(element, parent, status, debug)
local elapsedTime_ms = getElapsedTime(element)
local string
fileTestCount = fileTestCount + 1
testCount = testCount + 1
if status == 'success' then
successCount = successCount + 1
string = successString
elseif status == 'pending' then
skippedCount = skippedCount + 1
string = skippedString
elseif status == 'failure' then
failureCount = failureCount + 1
string = nil
elseif status == 'error' then
errorCount = errorCount + 1
string = nil
end
if string ~= nil then
if elapsedTime_ms == elapsedTime_ms then
string = timeString:format(elapsedTime_ms) .. ' ' .. string
end
io.write(string)
io.flush()
end
return nil, true
end
handler.testFailure = function(element, parent, message, debug)
io.write(failureString)
io.flush()
io.write(failureDescription(handler.failures[#handler.failures]))
io.flush()
return nil, true
end
handler.testError = function(element, parent, message, debug)
io.write(errorString)
io.flush()
io.write(failureDescription(handler.errors[#handler.errors]))
io.flush()
return nil, true
end
handler.error = function(element, parent, message, debug)
if element.descriptor ~= 'it' then
io.write(failureDescription(handler.errors[#handler.errors]))
io.flush()
errorCount = errorCount + 1
end
return nil, true
end
busted.subscribe({ 'suite', 'reset' }, handler.suiteReset)
busted.subscribe({ 'suite', 'start' }, handler.suiteStart)
busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)
busted.subscribe({ 'file', 'start' }, handler.fileStart)
busted.subscribe({ 'file', 'end' }, handler.fileEnd)
busted.subscribe({ 'test', 'start' }, handler.testStart, { predicate = handler.cancelOnPending })
busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending })
busted.subscribe({ 'failure', 'it' }, handler.testFailure)
busted.subscribe({ 'error', 'it' }, handler.testError)
busted.subscribe({ 'failure' }, handler.error)
busted.subscribe({ 'error' }, handler.error)
return handler
end

View File

@ -5,4 +5,5 @@ set -o pipefail
if [[ -n "${GCOV}" ]]; then if [[ -n "${GCOV}" ]]; then
coveralls --gcov "$(which "${GCOV}")" --encoding iso-8859-1 || echo 'coveralls upload failed.' coveralls --gcov "$(which "${GCOV}")" --encoding iso-8859-1 || echo 'coveralls upload failed.'
bash <(curl -s https://codecov.io/bash) || echo 'codecov upload failed.'
fi fi

View File

@ -3,12 +3,15 @@
set -e set -e
set -o pipefail set -o pipefail
CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CI_DIR}/common/suite.sh"
# Don't cache pip's log and selfcheck. # Don't cache pip's log and selfcheck.
rm -rf "${HOME}/.cache/pip/log" rm -rf "${HOME}/.cache/pip/log"
rm -f "${HOME}/.cache/pip/selfcheck.json" rm -f "${HOME}/.cache/pip/selfcheck.json"
# Update the third-party dependency cache only if the build was successful. # Update the third-party dependency cache only if the build was successful.
if [[ -f "${SUCCESS_MARKER}" ]]; then if ended_successfully; then
rm -rf "${HOME}/.cache/nvim-deps" rm -rf "${HOME}/.cache/nvim-deps"
mv "${DEPS_BUILD_DIR}" "${HOME}/.cache/nvim-deps" mv "${DEPS_BUILD_DIR}" "${HOME}/.cache/nvim-deps"
touch "${CACHE_MARKER}" touch "${CACHE_MARKER}"

39
ci/before_install.sh Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -e
set -o pipefail
if [[ "${CI_TARGET}" == lint ]]; then
exit
fi
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
brew update
fi
echo 'python info:'
(
2>&1 python --version || true
2>&1 python2 --version || true
2>&1 python3 --version || true
2>&1 pip --version || true
2>&1 pip2 --version || true
2>&1 pip3 --version || true
echo 'pyenv versions:'
2>&1 pyenv versions || true
) | sed 's/^/ /'
echo "Upgrade Python 2 pip."
pip2.7 -q install --user --upgrade pip
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
echo "Install Python 3."
brew install python3
echo "Upgrade Python 3 pip."
pip3 -q install --user --upgrade pip
else
echo "Upgrade Python 3 pip."
# Allow failure. pyenv pip3 on travis is broken:
# https://github.com/travis-ci/travis-ci/issues/8363
pip3 -q install --user --upgrade pip || true
fi

View File

@ -3,7 +3,7 @@
set -e set -e
set -o pipefail set -o pipefail
if [[ -n "${CI_TARGET}" ]]; then if [[ "${CI_TARGET}" == lint ]]; then
exit exit
fi fi

View File

@ -9,6 +9,10 @@ if "%CONFIGURATION%" == "MINGW_32" (
set ARCH=x86_64 set ARCH=x86_64
set BITS=64 set BITS=64
) )
if "%CONFIGURATION%" == "MINGW_64-gcov" (
set USE_GCOV="-DUSE_GCOV=ON"
)
:: We cannot have sh.exe in the PATH (MinGW) :: We cannot have sh.exe in the PATH (MinGW)
set PATH=%PATH:C:\Program Files\Git\usr\bin;=% set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
set PATH=C:\msys64\mingw%BITS%\bin;C:\Windows\System32;C:\Windows;%PATH% set PATH=C:\msys64\mingw%BITS%\bin;C:\Windows\System32;C:\Windows;%PATH%
@ -17,7 +21,7 @@ set PATH=C:\Program Files (x86)\CMake\bin\cpack.exe;%PATH%
:: Build third-party dependencies :: Build third-party dependencies
C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Su" || goto :error C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Su" || goto :error
C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm --needed -S mingw-w64-%ARCH%-cmake mingw-w64-%ARCH%-perl mingw-w64-%ARCH%-diffutils gperf" || goto :error C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm --needed -S mingw-w64-%ARCH%-cmake mingw-w64-%ARCH%-perl mingw-w64-%ARCH%-diffutils mingw-w64-%ARCH%-unibilium gperf" || goto :error
:: Setup python (use AppVeyor system python) :: Setup python (use AppVeyor system python)
C:\Python27\python.exe -m pip install neovim || goto :error C:\Python27\python.exe -m pip install neovim || goto :error
@ -31,23 +35,27 @@ python3 -c "import neovim; print(str(neovim))" || goto :error
mkdir .deps mkdir .deps
cd .deps cd .deps
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ..\third-party\ || goto :error cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo ..\third-party\ || goto :error
mingw32-make VERBOSE=1 || goto :error mingw32-make VERBOSE=1 || goto :error
cd .. cd ..
:: Build Neovim :: Build Neovim
mkdir build mkdir build
cd build cd build
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUSTED_OUTPUT_TYPE=gtest -DGPERF_PRG="C:\msys64\usr\bin\gperf.exe" .. || goto :error cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUSTED_OUTPUT_TYPE=nvim %USE_GCOV% -DGPERF_PRG="C:\msys64\usr\bin\gperf.exe" .. || goto :error
mingw32-make VERBOSE=1 || goto :error mingw32-make VERBOSE=1 || goto :error
bin\nvim --version || goto :error bin\nvim --version || goto :error
:: Functional tests :: Functional tests
mingw32-make functionaltest VERBOSE=1 || goto :error mingw32-make functionaltest VERBOSE=1 || goto :error
if defined USE_GCOV (
C:\msys64\usr\bin\bash -lc "cd /c/projects/neovim; bash <(curl -s https://codecov.io/bash) || echo 'codecov upload failed.'"
)
:: Build artifacts :: Build artifacts
cpack -G ZIP -C Release cpack -G ZIP -C RelWithDebInfo
if defined APPVEYOR_REPO_TAG_NAME cpack -G NSIS -C Release if defined APPVEYOR_REPO_TAG_NAME cpack -G NSIS -C RelWithDebInfo
goto :EOF goto :EOF
:error :error

View File

@ -1,8 +1,17 @@
top_make() {
${MAKE_CMD} "$@"
}
build_make() {
top_make -C "${BUILD_DIR}" "$@"
}
build_deps() { build_deps() {
if [[ "${BUILD_32BIT}" == ON ]]; then if test "${BUILD_32BIT}" = ON ; then
DEPS_CMAKE_FLAGS="${DEPS_CMAKE_FLAGS} ${CMAKE_FLAGS_32BIT}" DEPS_CMAKE_FLAGS="${DEPS_CMAKE_FLAGS} ${CMAKE_FLAGS_32BIT}"
fi fi
if [[ "${FUNCTIONALTEST}" == "functionaltest-lua" ]]; then if test "${FUNCTIONALTEST}" = "functionaltest-lua" \
|| test "${CLANG_SANITIZER}" = "ASAN_UBSAN" ; then
DEPS_CMAKE_FLAGS="${DEPS_CMAKE_FLAGS} -DUSE_BUNDLED_LUA=ON" DEPS_CMAKE_FLAGS="${DEPS_CMAKE_FLAGS} -DUSE_BUNDLED_LUA=ON"
fi fi
@ -10,16 +19,15 @@ build_deps() {
# If there is a valid cache and we're not forced to recompile, # If there is a valid cache and we're not forced to recompile,
# use cached third-party dependencies. # use cached third-party dependencies.
if [[ -f "${CACHE_MARKER}" ]] && [[ "${BUILD_NVIM_DEPS}" != true ]]; then if test -f "${CACHE_MARKER}" && test "${BUILD_NVIM_DEPS}" != "true" ; then
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then local statcmd="stat -c '%y'"
local statcmd="stat -f '%Sm'" if test "${TRAVIS_OS_NAME}" = osx ; then
else statcmd="stat -f '%Sm'"
local statcmd="stat -c '%y'"
fi fi
echo "Using third-party dependencies from Travis's cache (last updated: $(${statcmd} "${CACHE_MARKER}"))." echo "Using third-party dependencies from Travis's cache (last updated: $(${statcmd} "${CACHE_MARKER}"))."
mkdir -p "$(dirname "${DEPS_BUILD_DIR}")" mkdir -p "$(dirname "${DEPS_BUILD_DIR}")"
mv "${HOME}/.cache/nvim-deps" "${DEPS_BUILD_DIR}" mv "${HOME}/.cache/nvim-deps" "${DEPS_BUILD_DIR}"
else else
mkdir -p "${DEPS_BUILD_DIR}" mkdir -p "${DEPS_BUILD_DIR}"
fi fi
@ -30,7 +38,7 @@ build_deps() {
echo "Configuring with '${DEPS_CMAKE_FLAGS}'." echo "Configuring with '${DEPS_CMAKE_FLAGS}'."
CC= cmake ${DEPS_CMAKE_FLAGS} "${TRAVIS_BUILD_DIR}/third-party/" CC= cmake ${DEPS_CMAKE_FLAGS} "${TRAVIS_BUILD_DIR}/third-party/"
if ! ${MAKE_CMD}; then if ! top_make; then
exit 1 exit 1
fi fi
@ -38,10 +46,10 @@ build_deps() {
} }
prepare_build() { prepare_build() {
if [[ -n "${CLANG_SANITIZER}" ]]; then if test -n "${CLANG_SANITIZER}" ; then
CMAKE_FLAGS="${CMAKE_FLAGS} -DCLANG_${CLANG_SANITIZER}=ON" CMAKE_FLAGS="${CMAKE_FLAGS} -DCLANG_${CLANG_SANITIZER}=ON"
fi fi
if [[ "${BUILD_32BIT}" == ON ]]; then if test "${BUILD_32BIT}" = ON ; then
CMAKE_FLAGS="${CMAKE_FLAGS} ${CMAKE_FLAGS_32BIT}" CMAKE_FLAGS="${CMAKE_FLAGS} ${CMAKE_FLAGS_32BIT}"
fi fi
@ -53,24 +61,24 @@ prepare_build() {
build_nvim() { build_nvim() {
echo "Building nvim." echo "Building nvim."
if ! ${MAKE_CMD} nvim; then if ! top_make nvim ; then
exit 1 exit 1
fi fi
if [ "$CLANG_SANITIZER" != "TSAN" ]; then if test "$CLANG_SANITIZER" != "TSAN" ; then
echo "Building libnvim." echo "Building libnvim."
if ! ${MAKE_CMD} libnvim; then if ! top_make libnvim ; then
exit 1 exit 1
fi fi
echo "Building nvim-test." echo "Building nvim-test."
if ! ${MAKE_CMD} nvim-test; then if ! top_make nvim-test ; then
exit 1 exit 1
fi fi
fi fi
# Invoke nvim to trigger *San early. # Invoke nvim to trigger *San early.
if ! (bin/nvim --version && bin/nvim -u NONE -e -c ':qall'); then if ! (bin/nvim --version && bin/nvim -u NONE -e -c ':qall') ; then
asan_check "${LOG_DIR}" asan_check "${LOG_DIR}"
exit 1 exit 1
fi fi

199
ci/common/suite.sh Normal file
View File

@ -0,0 +1,199 @@
# HACK: get newline for use in strings given that "\n" and $'' do not work.
NL="$(printf '\nE')"
NL="${NL%E}"
FAIL_SUMMARY=""
# Test success marker. If END_MARKER file exists, we know that all tests
# finished. If FAIL_SUMMARY_FILE exists we know that some tests failed, this
# file will contain information about failed tests. Build is considered
# successful if tests ended without any of them failing.
END_MARKER="$BUILD_DIR/.tests_finished"
FAIL_SUMMARY_FILE="$BUILD_DIR/.test_errors"
ANSI_CLEAR="\033[0K"
travis_fold() {
local action="$1"
local name="$2"
name="$(echo -n "$name" | tr '\n\0' '--' | sed 's/[^A-Za-z0-9]\{1,\}/-/g')"
name="$(echo -n "$name" | sed 's/-$//')"
echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}"
}
if test "$TRAVIS" != "true" ; then
travis_fold() {
return 0
}
fi
enter_suite() {
set +x
FAILED=0
rm -f "${END_MARKER}"
local suite_name="$1"
export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE}/$suite_name"
travis_fold start "${NVIM_TEST_CURRENT_SUITE}"
set -x
}
exit_suite() {
set +x
if test -f "$NVIM_LOG_FILE" ; then
printf "===============================================================================\n"
printf "NVIM_LOG_FILE: $NVIM_LOG_FILE\n"
cat "$NVIM_LOG_FILE" 2>/dev/null || printf '(empty)'
printf "\n"
rm -rf "$NVIM_LOG_FILE"
fi
travis_fold end "${NVIM_TEST_CURRENT_SUITE}"
if test $FAILED -ne 0 ; then
echo "Suite ${NVIM_TEST_CURRENT_SUITE} failed, summary:"
echo "${FAIL_SUMMARY}"
fi
export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE%/*}"
if test "$1" != "--continue" ; then
exit $FAILED
else
local saved_failed=$FAILED
FAILED=0
return $saved_failed
fi
}
fail() {
local test_name="$1"
local fail_char="$2"
local message="$3"
: ${fail_char:=F}
: ${message:=Test $test_name failed}
local full_msg="$fail_char $NVIM_TEST_CURRENT_SUITE|$test_name :: $message"
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
echo "${full_msg}" >> "${FAIL_SUMMARY_FILE}"
echo "Failed: $full_msg"
FAILED=1
}
run_test() {
local cmd="$1"
test $# -gt 0 && shift
local test_name="$1"
: ${test_name:=$cmd}
test $# -gt 0 && shift
if ! eval "$cmd" ; then
fail "${test_name}" "$@"
fi
}
run_test_wd() {
local hang_ok=
if test "$1" = "--allow-hang" ; then
hang_ok=1
shift
fi
local timeout="$1"
test $# -gt 0 && shift
local cmd="$1"
test $# -gt 0 && shift
local restart_cmd="$1"
: ${restart_cmd:=true}
test $# -gt 0 && shift
local test_name="$1"
: ${test_name:=$cmd}
test $# -gt 0 && shift
local output_file="$(mktemp)"
local status_file="$(mktemp)"
local sid_file="$(mktemp)"
local restarts=5
local prev_tmpsize=-1
while test $restarts -gt 0 ; do
: > "$status_file"
: > "$sid_file"
setsid \
env \
output_file="$output_file" \
status_file="$status_file" \
sid_file="$sid_file" \
cmd="$cmd" \
CI_DIR="$CI_DIR" \
sh -c '
. "${CI_DIR}/common/test.sh"
ps -o sid= > "$sid_file"
(
ret=0
if ! eval "$cmd" 2>&1 ; then
ret=1
fi
echo "$ret" > "$status_file"
) | tee -a "$output_file"
'
while test "$(stat -c "%s" "$status_file")" -eq 0 ; do
prev_tmpsize=$tmpsize
sleep $timeout
tmpsize="$(stat -c "%s" "$output_file")"
if test $tempsize -eq $prev_temsize ; then
# no output, assuming either hang or exit
break
fi
done
restarts=$(( restarts - 1 ))
if test "$(stat -c "%s" "$status_file")" -eq 0 ; then
# Status file not updated, assuming hang
# SID not known, this should not ever happen
if test "$(stat -c "%s" "$sid_file")" -eq 0 ; then
fail "$test_name" E "Shell did not run"
break
fi
# Kill all processes which belong to one session: should get rid of test
# processes as well as sh itself.
pkill -KILL -s$(cat "$sid_file")
if test $restarts -eq 0 ; then
if test -z "$hang_ok" ; then
fail "$test_name" E "Test hang up"
fi
else
echo "Test ${test_name} hang up, restarting"
eval "$restart_cmd"
fi
else
local new_failed="$(cat "$status_file")"
if test "$new_failed" != "0" ; then
fail "$test_name" F "Test failed in run_test_wd"
fi
break
fi
done
rm -f "$output_file"
rm -f "$status_file"
rm -f "$sid_file"
}
ended_successfully() {
if test -f "${FAIL_SUMMARY_FILE}" ; then
echo 'Test failed, complete summary:'
cat "${FAIL_SUMMARY_FILE}"
return 1
fi
if ! test -f "${END_MARKER}" ; then
echo 'ended_successfully called before end marker was touched'
return 1
fi
return 0
}
end_tests() {
touch "${END_MARKER}"
ended_successfully
}

174
ci/common/test.sh Normal file
View File

@ -0,0 +1,174 @@
. "${CI_DIR}/common/build.sh"
. "${CI_DIR}/common/suite.sh"
print_core() {
local app="$1"
local core="$2"
if test "$app" = quiet ; then
echo "Found core $core"
return 0
fi
echo "======= Core file $core ======="
if test "${TRAVIS_OS_NAME}" = osx ; then
lldb -Q -o "bt all" -f "${app}" -c "${core}"
else
gdb -n -batch -ex 'thread apply all bt full' "${app}" -c "${core}"
fi
}
check_core_dumps() {
local del=
if test "$1" = "--delete" ; then
del=1
shift
fi
local app="${1:-${BUILD_DIR}/bin/nvim}"
if test "${TRAVIS_OS_NAME}" = osx ; then
local cores="$(find /cores/ -type f -print)"
else
local cores="$(find ./ -type f -name 'core.*' -print)"
fi
if test -z "${cores}" ; then
return
fi
local core
for core in $cores; do
if test "$del" = "1" ; then
print_core "$app" "$core" >&2
rm "$core"
else
print_core "$app" "$core"
fi
done
if test "$app" != quiet ; then
fail 'cores' E 'Core dumps found'
fi
}
check_logs() {
# Iterate through each log to remove an useless warning.
for log in $(find "${1}" -type f -name "${2}"); do
sed -i "${log}" \
-e '/Warning: noted but unhandled ioctl/d' \
-e '/could cause spurious value errors to appear/d' \
-e '/See README_MISSING_SYSCALL_OR_IOCTL for guidance/d'
done
# Now do it again, but only consider files with size > 0.
local err=""
for log in $(find "${1}" -type f -name "${2}" -size +0); do
cat "${log}"
err=1
done
if test -n "${err}" ; then
fail 'logs' E 'Runtime errors detected.'
fi
}
valgrind_check() {
check_logs "${1}" "valgrind-*"
}
asan_check() {
check_logs "${1}" "*san.*"
}
run_unittests() {(
enter_suite unittests
ulimit -c unlimited || true
if ! build_make unittest ; then
fail 'unittests' F 'Unit tests failed'
fi
check_core_dumps "$(which luajit)"
exit_suite
)}
run_functionaltests() {(
enter_suite functionaltests
ulimit -c unlimited || true
if ! build_make ${FUNCTIONALTEST}; then
fail 'functionaltests' F 'Functional tests failed'
fi
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
check_core_dumps
exit_suite
)}
run_oldtests() {(
enter_suite oldtests
ulimit -c unlimited || true
if ! make -C "${TRAVIS_BUILD_DIR}/src/nvim/testdir"; then
reset
fail 'oldtests' F 'Legacy tests failed'
fi
asan_check "${LOG_DIR}"
valgrind_check "${LOG_DIR}"
check_core_dumps
exit_suite
)}
check_runtime_files() {(
set +x
local test_name="$1" ; shift
local message="$1" ; shift
local tst="$1" ; shift
cd runtime
for file in $(git ls-files "$@") ; do
# Check that test is not trying to work with files with spaces/etc
# Prefer failing the build over using more robust construct because files
# with IFS are not welcome.
if ! test -e "$file" ; then
fail "$test_name" E \
"It appears that $file is only a part of the file name"
fi
if ! test "$tst" "$INSTALL_PREFIX/share/nvim/runtime/$file" ; then
fail "$test_name" F "$(printf "$message" "$file")"
fi
done
)}
install_nvim() {(
enter_suite 'install_nvim'
if ! build_make install ; then
fail 'install' E 'make install failed'
exit_suite
fi
"${INSTALL_PREFIX}/bin/nvim" --version
if ! "${INSTALL_PREFIX}/bin/nvim" -u NONE -e -c ':help' -c ':qall' ; then
echo "Running ':help' in the installed nvim failed."
echo "Maybe the helptags have not been generated properly."
fail 'help' F 'Failed running :help'
fi
# Check that all runtime files were installed
check_runtime_files \
'runtime-install' \
'It appears that %s is not installed.' \
-e \
'*.vim' '*.ps' '*.dict' '*.py' '*.tutor'
# Check that some runtime files are installed and are executables
check_runtime_files \
'not-exe' \
'It appears that %s is not installed or is not executable.' \
-x \
'*.awk' '*.sh' '*.bat'
# Check that generated syntax file has function names, #5060.
local genvimsynf=syntax/vim/generated.vim
local gpat='syn keyword vimFuncName .*eval'
if ! grep -q "$gpat" "${INSTALL_PREFIX}/share/nvim/runtime/$genvimsynf" ; then
fail 'funcnames' F "It appears that $genvimsynf does not contain $gpat."
fi
exit_suite
)}
csi_clean() {
find "${BUILD_DIR}/bin" -name 'test-includes-*' -delete
find "${BUILD_DIR}" -name '*test-include*.o' -delete
}

View File

@ -3,7 +3,7 @@
set -e set -e
set -o pipefail set -o pipefail
if [[ -n "${CI_TARGET}" ]]; then if [[ "${CI_TARGET}" == lint ]]; then
exit exit
fi fi
@ -17,7 +17,9 @@ echo "Install neovim module and coveralls for Python 2."
CC=cc pip2.7 -q install --user --upgrade neovim cpp-coveralls CC=cc pip2.7 -q install --user --upgrade neovim cpp-coveralls
echo "Install neovim module for Python 3." echo "Install neovim module for Python 3."
CC=cc pip3 -q install --user --upgrade neovim # Allow failure. pyenv pip3 on travis is broken:
# https://github.com/travis-ci/travis-ci/issues/8363
CC=cc pip3 -q install --user --upgrade neovim || true
echo "Install neovim RubyGem." echo "Install neovim RubyGem."
gem install --no-document --version ">= 0.2.0" neovim gem install --no-document --version ">= 0.2.0" neovim

40
ci/run_lint.sh Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -e
set -o pipefail
CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CI_DIR}/common/build.sh"
source "${CI_DIR}/common/suite.sh"
enter_suite 'clint'
run_test 'top_make clint-full' clint
exit_suite --continue
enter_suite 'testlint'
run_test 'top_make testlint' testlint
exit_suite --continue
enter_suite 'lualint'
run_test 'top_make lualint' lualint
exit_suite --continue
enter_suite single-includes
CLICOLOR_FORCE=1 run_test_wd \
--allow-hang \
10s \
'top_make check-single-includes' \
'csi_clean' \
single-includes
exit_suite --continue
end_tests

View File

@ -6,20 +6,29 @@ set -o pipefail
CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CI_DIR}/common/build.sh" source "${CI_DIR}/common/build.sh"
source "${CI_DIR}/common/test.sh" source "${CI_DIR}/common/test.sh"
source "${CI_DIR}/common/suite.sh"
enter_suite build
check_core_dumps --delete quiet check_core_dumps --delete quiet
prepare_build prepare_build
build_nvim build_nvim
if [ "$CLANG_SANITIZER" != "TSAN" ]; then exit_suite --continue
enter_suite tests
if test "$CLANG_SANITIZER" != "TSAN" ; then
# Additional threads are only created when the builtin UI starts, which # Additional threads are only created when the builtin UI starts, which
# doesn't happen in the unit/functional tests # doesn't happen in the unit/functional tests
run_unittests run_test run_unittests
run_functionaltests run_test run_functionaltests
fi fi
run_oldtests run_test run_oldtests
install_nvim run_test install_nvim
touch "${SUCCESS_MARKER}" exit_suite --continue
end_tests

View File

@ -3,16 +3,11 @@
set -e set -e
set -o pipefail set -o pipefail
if [[ -n "${CI_TARGET}" ]]; then
make "${CI_TARGET}"
exit 0
fi
# This will pass the environment variables down to a bash process which runs # This will pass the environment variables down to a bash process which runs
# as $USER, while retaining the environment variables defined and belonging # as $USER, while retaining the environment variables defined and belonging
# to secondary groups given above in usermod. # to secondary groups given above in usermod.
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
sudo -E su "${USER}" -c ".ci/run_tests.sh" sudo -E su "${USER}" -c "ci/run_${CI_TARGET}.sh"
else else
.ci/run_tests.sh ci/run_${CI_TARGET}.sh
fi fi

18
cmake/Download.cmake Normal file
View File

@ -0,0 +1,18 @@
file(
DOWNLOAD "${URL}" "${FILE}"
STATUS status
LOG log
)
list(GET status 0 status_code)
list(GET status 1 status_string)
if(NOT status_code EQUAL 0)
if(NOT ALLOW_FAILURE)
message(FATAL_ERROR "error: downloading '${URL}' failed
status_code: ${status_code}
status_string: ${status_string}
log: ${log}
")
endif()
endif()

View File

@ -4,7 +4,7 @@
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories # JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc # JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
if(NOT JEMALLOC_USE_BUNDLED) if(NOT USE_BUNDLED_JEMALLOC)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_JEMALLOC QUIET jemalloc) pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
@ -27,6 +27,9 @@ find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h
if(JEMALLOC_USE_STATIC) if(JEMALLOC_USE_STATIC)
list(APPEND JEMALLOC_NAMES list(APPEND JEMALLOC_NAMES
"${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}") "${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(INSERT JEMALLOC_NAMES 0
"${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif() endif()
list(APPEND JEMALLOC_NAMES jemalloc) list(APPEND JEMALLOC_NAMES jemalloc)

View File

@ -46,6 +46,7 @@ check_c_source_compiles("
int main(int argc, char** argv) { int main(int argc, char** argv) {
gettext(\"foo\"); gettext(\"foo\");
ngettext(\"foo\", \"bar\", 1);
bindtextdomain(\"foo\", \"bar\"); bindtextdomain(\"foo\", \"bar\");
bind_textdomain_codeset(\"foo\", \"bar\"); bind_textdomain_codeset(\"foo\", \"bar\");
textdomain(\"foo\"); textdomain(\"foo\");

View File

@ -4,7 +4,7 @@
# LIBTERMKEY_INCLUDE_DIRS - The libtermkey include directories # LIBTERMKEY_INCLUDE_DIRS - The libtermkey include directories
# LIBTERMKEY_LIBRARIES - The libraries needed to use libtermkey # LIBTERMKEY_LIBRARIES - The libraries needed to use libtermkey
if(NOT LIBTERMKEY_USE_BUNDLED) if(NOT USE_BUNDLED_LIBTERMKEY)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_LIBTERMKEY QUIET termkey) pkg_check_modules(PC_LIBTERMKEY QUIET termkey)

View File

@ -8,7 +8,7 @@
# Set the LIBUV_USE_STATIC variable to specify if static libraries should # Set the LIBUV_USE_STATIC variable to specify if static libraries should
# be preferred to shared ones. # be preferred to shared ones.
if(NOT LIBUV_USE_BUNDLED) if(NOT USE_BUNDLED_LIBUV)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_LIBUV QUIET libuv) pkg_check_modules(PC_LIBUV QUIET libuv)
@ -65,7 +65,7 @@ if(HAVE_LIBKSTAT)
endif() endif()
check_library_exists(kvm kvm_open "kvm.h" HAVE_LIBKVM) check_library_exists(kvm kvm_open "kvm.h" HAVE_LIBKVM)
if(HAVE_LIBKVM) if(HAVE_LIBKVM AND NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
list(APPEND LIBUV_LIBRARIES kvm) list(APPEND LIBUV_LIBRARIES kvm)
endif() endif()

View File

@ -4,7 +4,7 @@
# LIBVTERM_INCLUDE_DIRS - The libvterm include directories # LIBVTERM_INCLUDE_DIRS - The libvterm include directories
# LIBVTERM_LIBRARIES - The libraries needed to use libvterm # LIBVTERM_LIBRARIES - The libraries needed to use libvterm
if(NOT LIBVTERM_USE_BUNDLED) if(NOT USE_BUNDLED_LIBVTERM)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_LIBVTERM QUIET vterm) pkg_check_modules(PC_LIBVTERM QUIET vterm)

197
cmake/FindLua.cmake Normal file
View File

@ -0,0 +1,197 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindLua
# -------
#
#
#
# Locate Lua library This module defines
#
# ::
#
# LUA_FOUND - if false, do not try to link to Lua
# LUA_LIBRARIES - both lua and lualib
# LUA_INCLUDE_DIR - where to find lua.h
# LUA_VERSION_STRING - the version of Lua found
# LUA_VERSION_MAJOR - the major version of Lua
# LUA_VERSION_MINOR - the minor version of Lua
# LUA_VERSION_PATCH - the patch version of Lua
#
#
#
# Note that the expected include convention is
#
# ::
#
# #include "lua.h"
#
# and not
#
# ::
#
# #include <lua/lua.h>
#
# This is because, the lua location is not standardized and may exist in
# locations other than lua/
unset(_lua_include_subdirs)
unset(_lua_library_names)
unset(_lua_append_versions)
# this is a function only to have all the variables inside go away automatically
function(_lua_set_version_vars)
set(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
if (Lua_FIND_VERSION_EXACT)
if (Lua_FIND_VERSION_COUNT GREATER 1)
set(_lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
endif ()
elseif (Lua_FIND_VERSION)
# once there is a different major version supported this should become a loop
if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
if (Lua_FIND_VERSION_COUNT EQUAL 1)
set(_lua_append_versions ${LUA_VERSIONS5})
else ()
foreach (subver IN LISTS LUA_VERSIONS5)
if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
list(APPEND _lua_append_versions ${subver})
endif ()
endforeach ()
endif ()
endif ()
else ()
# once there is a different major version supported this should become a loop
set(_lua_append_versions ${LUA_VERSIONS5})
endif ()
list(APPEND _lua_include_subdirs "include/lua" "include")
foreach (ver IN LISTS _lua_append_versions)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
list(APPEND _lua_include_subdirs
include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
)
endforeach ()
set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
set(_lua_append_versions "${_lua_append_versions}" PARENT_SCOPE)
endfunction(_lua_set_version_vars)
function(_lua_check_header_version _hdr_file)
# At least 5.[012] have different ways to express the version
# so all of them need to be tested. Lua 5.2 defines LUA_VERSION
# and LUA_RELEASE as joined by the C preprocessor, so avoid those.
file(STRINGS "${_hdr_file}" lua_version_strings
REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
else ()
string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
endif ()
string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
endif ()
foreach (ver IN LISTS _lua_append_versions)
if (ver STREQUAL "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
set(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR} PARENT_SCOPE)
set(LUA_VERSION_MINOR ${LUA_VERSION_MINOR} PARENT_SCOPE)
set(LUA_VERSION_PATCH ${LUA_VERSION_PATCH} PARENT_SCOPE)
set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)
return()
endif ()
endforeach ()
endfunction(_lua_check_header_version)
_lua_set_version_vars()
if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
_lua_check_header_version("${LUA_INCLUDE_DIR}/lua.h")
endif ()
if (NOT LUA_VERSION_STRING)
foreach (subdir IN LISTS _lua_include_subdirs)
unset(LUA_INCLUDE_PREFIX CACHE)
find_path(LUA_INCLUDE_PREFIX ${subdir}/lua.h
HINTS
ENV LUA_DIR
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
if (LUA_INCLUDE_PREFIX)
_lua_check_header_version("${LUA_INCLUDE_PREFIX}/${subdir}/lua.h")
if (LUA_VERSION_STRING)
set(LUA_INCLUDE_DIR "${LUA_INCLUDE_PREFIX}/${subdir}")
break()
endif ()
endif ()
endforeach ()
endif ()
unset(_lua_include_subdirs)
unset(_lua_append_versions)
if (LUA_VERSION_STRING)
set(_lua_library_names
lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}
lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
lua.${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
)
endif ()
find_library(LUA_LIBRARY
NAMES ${_lua_library_names} lua
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
unset(_lua_library_names)
if (LUA_LIBRARY)
# include the math library for Unix
if (UNIX AND NOT APPLE AND NOT BEOS)
find_library(LUA_MATH_LIBRARY m)
set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
# include dl library for statically-linked Lua library
get_filename_component(LUA_LIB_EXT ${LUA_LIBRARY} EXT)
if(LUA_LIB_EXT STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX)
list(APPEND LUA_LIBRARIES ${CMAKE_DL_LIBS})
endif()
# For Windows and Mac, don't need to explicitly include the math library
else ()
set(LUA_LIBRARIES "${LUA_LIBRARY}")
endif ()
endif ()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)

View File

@ -4,7 +4,7 @@
# LUAJIT_INCLUDE_DIRS - The luajit include directories # LUAJIT_INCLUDE_DIRS - The luajit include directories
# LUAJIT_LIBRARIES - The libraries needed to use luajit # LUAJIT_LIBRARIES - The libraries needed to use luajit
if(NOT LUAJIT_USE_BUNDLED) if(NOT USE_BUNDLED_LUAJIT)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_LUAJIT QUIET luajit) pkg_check_modules(PC_LUAJIT QUIET luajit)

View File

@ -4,7 +4,7 @@
# MSGPACK_INCLUDE_DIRS - The msgpack include directories # MSGPACK_INCLUDE_DIRS - The msgpack include directories
# MSGPACK_LIBRARIES - The libraries needed to use msgpack # MSGPACK_LIBRARIES - The libraries needed to use msgpack
if(NOT MSGPACK_USE_BUNDLED) if(NOT USE_BUNDLED_MSGPACK)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_search_module(PC_MSGPACK QUIET pkg_search_module(PC_MSGPACK QUIET

View File

@ -4,7 +4,7 @@
# UNIBILIUM_INCLUDE_DIRS - The unibilium include directories # UNIBILIUM_INCLUDE_DIRS - The unibilium include directories
# UNIBILIUM_LIBRARIES - The libraries needed to use unibilium # UNIBILIUM_LIBRARIES - The libraries needed to use unibilium
if(NOT UNIBILIUM_USE_BUNDLED) if(NOT USE_BUNDLED_UNIBILIUM)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_UNIBILIUM QUIET unibilium) pkg_check_modules(PC_UNIBILIUM QUIET unibilium)

10
cmake/FindWinpty.cmake Normal file
View File

@ -0,0 +1,10 @@
include(LibFindMacros)
find_path(WINPTY_INCLUDE_DIR winpty.h)
set(WINPTY_INCLUDE_DIRS ${WINPTY_INCLUDE_DIR})
find_library(WINPTY_LIBRARY winpty)
find_program(WINPTY_AGENT_EXE winpty-agent.exe)
set(WINPTY_LIBRARIES ${WINPTY_LIBRARY})
find_package_handle_standard_args(Winpty DEFAULT_MSG WINPTY_LIBRARY WINPTY_INCLUDE_DIR)

View File

@ -0,0 +1,2 @@
file(GLOB_RECURSE JSON_FILES *.json)
file(COPY ${JSON_FILES} DESTINATION "${TARGET}")

View File

@ -1,3 +1,12 @@
# Fix CMAKE_INSTALL_MANDIR on BSD before including GNUInstallDirs. #6771
if(CMAKE_SYSTEM_NAME MATCHES "BSD" AND NOT DEFINED CMAKE_INSTALL_MANDIR)
if(DEFINED ENV{MANPREFIX})
set(CMAKE_INSTALL_MANDIR "$ENV{MANPREFIX}/man")
elseif(CMAKE_INSTALL_PREFIX MATCHES "^/usr/local$")
set(CMAKE_INSTALL_MANDIR "man")
endif()
endif()
# For $CMAKE_INSTALL_{DATAROOT,MAN, ...}DIR # For $CMAKE_INSTALL_{DATAROOT,MAN, ...}DIR
include(GNUInstallDirs) include(GNUInstallDirs)

View File

@ -1,32 +0,0 @@
get_filename_component(LINT_DIR ${LINT_DIR} ABSOLUTE)
get_filename_component(LINT_PREFIX ${LINT_DIR} PATH)
set(LINT_SUPPRESS_FILE "${LINT_PREFIX}/errors.json")
if(DEFINED ENV{LINT_FILE})
file(GLOB_RECURSE LINT_FILES "$ENV{LINT_FILE}")
else()
file(GLOB_RECURSE LINT_FILES ${LINT_DIR}/*.c ${LINT_DIR}/*.h)
endif()
set(LINT_ARGS)
if(LINT_SUPPRESS_URL)
file(DOWNLOAD ${LINT_SUPPRESS_URL} ${LINT_SUPPRESS_FILE})
list(APPEND LINT_ARGS "--suppress-errors=${LINT_SUPPRESS_FILE}")
endif()
foreach(lint_file ${LINT_FILES})
file(RELATIVE_PATH lint_file "${LINT_PREFIX}" "${lint_file}")
list(APPEND LINT_ARGS "${lint_file}")
endforeach()
execute_process(
COMMAND ${LINT_PRG} ${LINT_ARGS}
RESULT_VARIABLE res
WORKING_DIRECTORY "${LINT_PREFIX}")
file(REMOVE ${LINT_SUPPRESS_FILE})
if(NOT res EQUAL 0)
message(FATAL_ERROR "Linting failed: ${res}.")
endif()

22
cmake/RunLuacheck.cmake Normal file
View File

@ -0,0 +1,22 @@
set(LUACHECK_ARGS -q "${LUAFILES_DIR}")
if(DEFINED IGNORE_PATTERN)
list(APPEND LUACHECK_ARGS --exclude-files "${LUAFILES_DIR}/${IGNORE_PATTERN}")
endif()
if(DEFINED CHECK_PATTERN)
list(APPEND LUACHECK_ARGS --include-files "${LUAFILES_DIR}/${CHECK_PATTERN}")
endif()
if(DEFINED READ_GLOBALS)
list(APPEND LUACHECK_ARGS --read-globals "${READ_GLOBALS}")
endif()
execute_process(
COMMAND "${LUACHECK_PRG}" ${LUACHECK_ARGS}
WORKING_DIRECTORY "${LUAFILES_DIR}"
ERROR_VARIABLE err
RESULT_VARIABLE res
)
if(NOT res EQUAL 0)
message(STATUS "Output to stderr:\n${err}")
message(FATAL_ERROR "Linting tests failed with error: ${res}.")
endif()

View File

@ -1,8 +1,15 @@
# Set LC_ALL to meet expectations of some locale-sensitive tests.
set(ENV{LC_ALL} "en_US.UTF-8")
set(ENV{VIMRUNTIME} ${WORKING_DIR}/runtime) set(ENV{VIMRUNTIME} ${WORKING_DIR}/runtime)
set(ENV{NVIM_RPLUGIN_MANIFEST} ${WORKING_DIR}/Xtest_rplugin_manifest) set(ENV{NVIM_RPLUGIN_MANIFEST} ${WORKING_DIR}/Xtest_rplugin_manifest)
set(ENV{XDG_CONFIG_HOME} ${WORKING_DIR}/Xtest_xdg/config) set(ENV{XDG_CONFIG_HOME} ${WORKING_DIR}/Xtest_xdg/config)
set(ENV{XDG_DATA_HOME} ${WORKING_DIR}/Xtest_xdg/share) set(ENV{XDG_DATA_HOME} ${WORKING_DIR}/Xtest_xdg/share)
if(NOT DEFINED ENV{NVIM_LOG_FILE})
set(ENV{NVIM_LOG_FILE} ${WORKING_DIR}/.nvimlog)
endif()
if(NVIM_PRG) if(NVIM_PRG)
set(ENV{NVIM_PRG} "${NVIM_PRG}") set(ENV{NVIM_PRG} "${NVIM_PRG}")
endif() endif()
@ -25,6 +32,8 @@ if(DEFINED ENV{TEST_FILTER})
set(TEST_TAG "--filter=$ENV{TEST_FILTER}") set(TEST_TAG "--filter=$ENV{TEST_FILTER}")
endif() endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${WORKING_DIR}/Xtest-tmpdir)
set(ENV{TMPDIR} ${WORKING_DIR}/Xtest-tmpdir)
set(ENV{SYSTEM_NAME} ${SYSTEM_NAME}) set(ENV{SYSTEM_NAME} ${SYSTEM_NAME})
execute_process( execute_process(
COMMAND ${BUSTED_PRG} ${TEST_TAG} ${TEST_FILTER} -v -o ${BUSTED_OUTPUT_TYPE} COMMAND ${BUSTED_PRG} ${TEST_TAG} ${TEST_FILTER} -v -o ${BUSTED_OUTPUT_TYPE}
@ -37,6 +46,7 @@ execute_process(
file(REMOVE ${WORKING_DIR}/Xtest_rplugin_manifest) file(REMOVE ${WORKING_DIR}/Xtest_rplugin_manifest)
file(REMOVE_RECURSE ${WORKING_DIR}/Xtest_xdg) file(REMOVE_RECURSE ${WORKING_DIR}/Xtest_xdg)
file(REMOVE_RECURSE ${WORKING_DIR}/Xtest-tmpdir)
if(NOT res EQUAL 0) if(NOT res EQUAL 0)
message(STATUS "Output to stderr:\n${err}") message(STATUS "Output to stderr:\n${err}")

View File

@ -1,13 +0,0 @@
set(IGNORE_FILES "${TEST_DIR}/*/preload.lua")
execute_process(
COMMAND ${LUACHECK_PRG} -q ${TEST_DIR} --exclude-files ${IGNORE_FILES}
WORKING_DIRECTORY ${TEST_DIR}
ERROR_VARIABLE err
RESULT_VARIABLE res
${EXTRA_ARGS})
if(NOT res EQUAL 0)
message(STATUS "Output to stderr:\n${err}")
message(FATAL_ERROR "Linting tests failed with error: ${res}.")
endif()

27
codecov.yml Normal file
View File

@ -0,0 +1,27 @@
codecov:
notify:
require_ci_to_pass: yes
ci:
- appveyor
- travis
- !neovim-qb.szakmeister.net
coverage:
precision: 2
round: down
range: "70...100"
status:
project: yes
patch: yes
changes: no
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
comment: off

View File

@ -68,4 +68,6 @@
#cmakedefine ORDER_BIG_ENDIAN #cmakedefine ORDER_BIG_ENDIAN
#define ENDIAN_INCLUDE_FILE <@ENDIAN_INCLUDE_FILE@> #define ENDIAN_INCLUDE_FILE <@ENDIAN_INCLUDE_FILE@>
#cmakedefine HAVE_EXECINFO_BACKTRACE
#endif // AUTO_CONFIG_H #endif // AUTO_CONFIG_H

View File

@ -13,27 +13,21 @@
# Sets the build type; defaults to Debug. Valid values: # Sets the build type; defaults to Debug. Valid values:
# #
# - Debug: Disables optimizations (-O0), enables debug information and logging. # - Debug: Disables optimizations (-O0), enables debug information.
# #
# - Dev: Enables all optimizations that do not interfere with # - RelWithDebInfo: Enables optimizations (-Og or -O2) with debug information.
# debugging (-Og if available, -O2 and -g if not).
# Enables debug information and logging.
#
# - RelWithDebInfo: Enables optimizations (-O2) and debug information.
# Disables logging.
# #
# - MinSizeRel: Enables all -O2 optimization that do not typically # - MinSizeRel: Enables all -O2 optimization that do not typically
# increase code size, and performs further optimizations # increase code size, and performs further optimizations
# designed to reduce code size (-Os). # designed to reduce code size (-Os).
# Disables debug information and logging. # Disables debug information.
# #
# - Release: Same as RelWithDebInfo, but disables debug information. # - Release: Same as RelWithDebInfo, but disables debug information.
# #
# CMAKE_BUILD_TYPE := Debug # CMAKE_BUILD_TYPE := Debug
# By default, nvim's log level is INFO (1) (unless CMAKE_BUILD_TYPE is # Log levels: 0 (DEBUG), 1 (INFO), 2 (WARNING), 3 (ERROR)
# "Release", in which case logging is disabled). # Default is 1 (INFO) unless CMAKE_BUILD_TYPE is Release or RelWithDebInfo.
# The log level must be a number DEBUG (0), INFO (1), WARNING (2) or ERROR (3).
# CMAKE_EXTRA_FLAGS += -DMIN_LOG_LEVEL=1 # CMAKE_EXTRA_FLAGS += -DMIN_LOG_LEVEL=1
# By default, nvim uses bundled versions of its required third-party # By default, nvim uses bundled versions of its required third-party

View File

@ -371,27 +371,6 @@ See
Used to set the 'shell' option, which determines the shell used by the Used to set the 'shell' option, which determines the shell used by the
.Ic :terminal .Ic :terminal
command. command.
.It Ev NVIM_TUI_ENABLE_CURSOR_SHAPE
Set to 0 to prevent Nvim from changing the cursor shape.
Set to 1 to enable non-blinking mode-sensitive cursor (this is the default).
Set to 2 to enable blinking mode-sensitive cursor.
Host terminal must support the DECSCUSR CSI escape sequence.
.Pp
Depending on the terminal emulator, using this option with
.Nm
under
.Xr tmux 1
might require adding the following to
.Pa ~/.tmux.conf :
.Bd -literal -offset indent
set -ga terminal-overrides ',*:Ss=\eE[%p1%d q:Se=\eE[2 q'
.Ed
.Pp
See
.Ic terminal-overrides
in the
.Xr tmux 1
manual page for more information.
.El .El
.Sh FILES .Sh FILES
.Bl -tag -width "~/.config/nvim/init.vim" .Bl -tag -width "~/.config/nvim/init.vim"

View File

@ -71,6 +71,7 @@ foreach(DF ${DOCFILES})
endforeach() endforeach()
add_custom_target(helptags add_custom_target(helptags
COMMAND ${CMAKE_COMMAND} -E remove_directory ${GENERATED_RUNTIME_DIR}/doc
COMMAND ${CMAKE_COMMAND} -E copy_directory COMMAND ${CMAKE_COMMAND} -E copy_directory
${PROJECT_SOURCE_DIR}/runtime/doc ${GENERATED_RUNTIME_DIR}/doc ${PROJECT_SOURCE_DIR}/runtime/doc ${GENERATED_RUNTIME_DIR}/doc
COMMAND "${PROJECT_BINARY_DIR}/bin/nvim" COMMAND "${PROJECT_BINARY_DIR}/bin/nvim"
@ -100,20 +101,6 @@ add_custom_target(
${GENERATED_PACKAGE_TAGS} ${GENERATED_PACKAGE_TAGS}
) )
# Optional targets for nvim.desktop file and icon.
find_program(XDG_MENU_PRG xdg-desktop-menu)
find_program(XDG_ICON_PRG xdg-icon-resource)
if(XDG_MENU_PRG)
add_custom_target(desktop-file
COMMAND xdg-desktop-menu install --novendor ${PROJECT_SOURCE_DIR}/runtime/nvim.desktop)
# add_dependencies(runtime desktop-file)
endif()
if(XDG_ICON_PRG)
add_custom_target(desktop-icon
COMMAND xdg-icon-resource install --novendor --size 128 ${PROJECT_SOURCE_DIR}/runtime/nvim.png)
# add_dependencies(runtime desktop-icon)
endif()
# CMake is painful here. It will create the destination using the user's # CMake is painful here. It will create the destination using the user's
# current umask, and we don't want that. And we don't just want to install # current umask, and we don't want that. And we don't just want to install
# the target directory, as it will mess with existing permissions. So this # the target directory, as it will mess with existing permissions. So this
@ -128,6 +115,16 @@ install_helper(
FILES ${GENERATED_SYN_VIM} FILES ${GENERATED_SYN_VIM}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/nvim/runtime/syntax/vim) DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/nvim/runtime/syntax/vim)
if(NOT APPLE)
install_helper(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/nvim.desktop
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
install_helper(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/nvim.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps)
endif()
file(GLOB_RECURSE RUNTIME_PROGRAMS file(GLOB_RECURSE RUNTIME_PROGRAMS
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
*.awk *.sh *.bat) *.awk *.sh *.bat)
@ -140,6 +137,7 @@ endforeach()
file(GLOB_RECURSE RUNTIME_FILES file(GLOB_RECURSE RUNTIME_FILES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
rgb.txt
*.vim *.dict *.py *.rb *.ps *.tutor) *.vim *.dict *.py *.rb *.ps *.tutor)
foreach(F ${RUNTIME_FILES}) foreach(F ${RUNTIME_FILES})

View File

@ -2,12 +2,13 @@
" Description: Perform Ada specific completion & tagging. " Description: Perform Ada specific completion & tagging.
" Language: Ada (2005) " Language: Ada (2005)
" $Id: ada.vim 887 2008-07-08 14:29:01Z krischik $ " $Id: ada.vim 887 2008-07-08 14:29:01Z krischik $
" Maintainer: Martin Krischik <krischik@users.sourceforge.net> " Maintainer: Mathias Brousset <mathiasb17@gmail.com>
" Martin Krischik <krischik@users.sourceforge.net>
" Taylor Venable <taylor@metasyntax.net> " Taylor Venable <taylor@metasyntax.net>
" Neil Bird <neil@fnxweb.com> " Neil Bird <neil@fnxweb.com>
" Ned Okie <nokie@radford.edu> " Ned Okie <nokie@radford.edu>
" $Author: krischik $ " $Author: krischik $
" $Date: 2008-07-08 16:29:01 +0200 (Di, 08 Jul 2008) $ " $Date: 2017-01-31 20:20:05 +0200 (Mon, 01 Jan 2017) $
" Version: 4.6 " Version: 4.6
" $Revision: 887 $ " $Revision: 887 $
" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $ " $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $
@ -23,6 +24,7 @@
" 09.05.2007 MK Session just won't work no matter how much " 09.05.2007 MK Session just won't work no matter how much
" tweaking is done " tweaking is done
" 19.09.2007 NO still some mapleader problems " 19.09.2007 NO still some mapleader problems
" 31.01.2017 MB fix more mapleader problems
" Help Page: ft-ada-functions " Help Page: ft-ada-functions
"------------------------------------------------------------------------------ "------------------------------------------------------------------------------
@ -585,11 +587,11 @@ function ada#Map_Menu (Text, Keys, Command)
\ " :" . a:Command . "<CR>" \ " :" . a:Command . "<CR>"
execute execute
\ "nnoremap <buffer>" . \ "nnoremap <buffer>" .
\ escape(l:leader . "a" . a:Keys , '\') . \ " <Leader>a" . a:Keys .
\" :" . a:Command \" :" . a:Command
execute execute
\ "inoremap <buffer>" . \ "inoremap <buffer>" .
\ escape(l:leader . "a" . a:Keys , '\') . \ " <Leader>a" . a:Keys .
\" <C-O>:" . a:Command \" <C-O>:" . a:Command
endif endif
return return

View File

@ -0,0 +1,184 @@
" Language: ConTeXt typesetting engine
" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com>
" Latest Revision: 2016 Oct 21
let s:keepcpo= &cpo
set cpo&vim
" Helper functions {{{
function! s:context_echo(message, mode)
redraw
echo "\r"
execute 'echohl' a:mode
echomsg '[ConTeXt]' a:message
echohl None
endf
function! s:sh()
return has('win32') || has('win64') || has('win16') || has('win95')
\ ? ['cmd.exe', '/C']
\ : ['/bin/sh', '-c']
endfunction
" For backward compatibility
if exists('*win_getid')
function! s:win_getid()
return win_getid()
endf
function! s:win_id2win(winid)
return win_id2win(a:winid)
endf
else
function! s:win_getid()
return winnr()
endf
function! s:win_id2win(winnr)
return a:winnr
endf
endif
" }}}
" ConTeXt jobs {{{
if has('job')
let g:context_jobs = []
" Print the status of ConTeXt jobs
function! context#job_status()
let l:jobs = filter(g:context_jobs, 'job_status(v:val) == "run"')
let l:n = len(l:jobs)
call s:context_echo(
\ 'There '.(l:n == 1 ? 'is' : 'are').' '.(l:n == 0 ? 'no' : l:n)
\ .' job'.(l:n == 1 ? '' : 's').' running'
\ .(l:n == 0 ? '.' : ' (' . join(l:jobs, ', ').').'),
\ 'ModeMsg')
endfunction
" Stop all ConTeXt jobs
function! context#stop_jobs()
let l:jobs = filter(g:context_jobs, 'job_status(v:val) == "run"')
for job in l:jobs
call job_stop(job)
endfor
sleep 1
let l:tmp = []
for job in l:jobs
if job_status(job) == "run"
call add(l:tmp, job)
endif
endfor
let g:context_jobs = l:tmp
if empty(g:context_jobs)
call s:context_echo('Done. No jobs running.', 'ModeMsg')
else
call s:context_echo('There are still some jobs running. Please try again.', 'WarningMsg')
endif
endfunction
function! context#callback(path, job, status)
if index(g:context_jobs, a:job) != -1 && job_status(a:job) != 'run' " just in case
call remove(g:context_jobs, index(g:context_jobs, a:job))
endif
call s:callback(a:path, a:job, a:status)
endfunction
function! context#close_cb(channel)
call job_status(ch_getjob(a:channel)) " Trigger exit_cb's callback for faster feedback
endfunction
function! s:typeset(path)
call add(g:context_jobs,
\ job_start(add(s:sh(), context#command() . ' ' . shellescape(fnamemodify(a:path, ":t"))), {
\ 'close_cb' : 'context#close_cb',
\ 'exit_cb' : function(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')),
\ [a:path]),
\ 'in_io' : 'null'
\ }))
endfunction
else " No jobs
function! context#job_status()
call s:context_echo('Not implemented', 'WarningMsg')
endfunction!
function! context#stop_jobs()
call s:context_echo('Not implemented', 'WarningMsg')
endfunction
function! context#callback(path, job, status)
call s:callback(a:path, a:job, a:status)
endfunction
function! s:typeset(path)
execute '!' . context#command() . ' ' . shellescape(fnamemodify(a:path, ":t"))
call call(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')),
\ [a:path, 0, v:shell_error])
endfunction
endif " has('job')
function! s:callback(path, job, status) abort
if a:status < 0 " Assume the job was terminated
return
endif
" Get info about the current window
let l:winid = s:win_getid() " Save window id
let l:efm = &l:errorformat " Save local errorformat
let l:cwd = fnamemodify(getcwd(), ":p") " Save local working directory
" Set errorformat to parse ConTeXt errors
execute 'setl efm=' . escape(b:context_errorformat, ' ')
try " Set cwd to expand error file correctly
execute 'lcd' fnameescape(fnamemodify(a:path, ':h'))
catch /.*/
execute 'setl efm=' . escape(l:efm, ' ')
throw v:exception
endtry
try
execute 'cgetfile' fnameescape(fnamemodify(a:path, ':r') . '.log')
botright cwindow
finally " Restore cwd and errorformat
execute s:win_id2win(l:winid) . 'wincmd w'
execute 'lcd ' . fnameescape(l:cwd)
execute 'setl efm=' . escape(l:efm, ' ')
endtry
if a:status == 0
call s:context_echo('Success!', 'ModeMsg')
else
call s:context_echo('There are errors. ', 'ErrorMsg')
endif
endfunction
function! context#command()
return get(b:, 'context_mtxrun', get(g:, 'context_mtxrun', 'mtxrun'))
\ . ' --script context --autogenerate --nonstopmode'
\ . ' --synctex=' . (get(b:, 'context_synctex', get(g:, 'context_synctex', 0)) ? '1' : '0')
\ . ' ' . get(b:, 'context_extra_options', get(g:, 'context_extra_options', ''))
endfunction
" Accepts an optional path (useful for big projects, when the file you are
" editing is not the project's root document). If no argument is given, uses
" the path of the current buffer.
function! context#typeset(...) abort
let l:path = fnamemodify(strlen(a:000[0]) > 0 ? a:1 : expand("%"), ":p")
let l:cwd = fnamemodify(getcwd(), ":p") " Save local working directory
call s:context_echo('Typesetting...', 'ModeMsg')
execute 'lcd' fnameescape(fnamemodify(l:path, ":h"))
try
call s:typeset(l:path)
finally " Restore local working directory
execute 'lcd ' . fnameescape(l:cwd)
endtry
endfunction!
"}}}
let &cpo = s:keepcpo
unlet s:keepcpo
" vim: sw=2 fdm=marker

View File

@ -0,0 +1,25 @@
" Language: ConTeXt typesetting engine
" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com>
" Latest Revision: 2016 Oct 15
let s:keepcpo= &cpo
set cpo&vim
" Complete keywords in MetaPost blocks
function! contextcomplete#Complete(findstart, base)
if a:findstart == 1
if len(synstack(line('.'), 1)) > 0 &&
\ synIDattr(synstack(line('.'), 1)[0], "name") ==# 'contextMPGraphic'
return syntaxcomplete#Complete(a:findstart, a:base)
else
return -3
endif
else
return syntaxcomplete#Complete(a:findstart, a:base)
endif
endfunction
let &cpo = s:keepcpo
unlet s:keepcpo
" vim: sw=2 fdm=marker

View File

@ -1,6 +1,6 @@
" Vim autoload file for editing compressed files. " Vim autoload file for editing compressed files.
" Maintainer: Bram Moolenaar <Bram@vim.org> " Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2014 Nov 05 " Last Change: 2016 Sep 28
" These functions are used by the gzip plugin. " These functions are used by the gzip plugin.
@ -63,6 +63,9 @@ fun gzip#read(cmd)
" set 'modifiable' " set 'modifiable'
let ma_save = &ma let ma_save = &ma
setlocal ma setlocal ma
" set 'write'
let write_save = &write
set write
" Reset 'foldenable', otherwise line numbers get adjusted. " Reset 'foldenable', otherwise line numbers get adjusted.
if has("folding") if has("folding")
let fen_save = &fen let fen_save = &fen
@ -127,6 +130,7 @@ fun gzip#read(cmd)
let &pm = pm_save let &pm = pm_save
let &cpo = cpo_save let &cpo = cpo_save
let &l:ma = ma_save let &l:ma = ma_save
let &write = write_save
if has("folding") if has("folding")
let &l:fen = fen_save let &l:fen = fen_save
endif endif

View File

@ -1,24 +1,24 @@
function! s:enhance_syntax() abort function! s:enhance_syntax() abort
syntax case match syntax case match
syntax keyword healthError ERROR syntax keyword healthError ERROR[:]
\ containedin=markdownCodeBlock,mkdListItemLine \ containedin=markdownCodeBlock,mkdListItemLine
highlight link healthError Error highlight default link healthError Error
syntax keyword healthWarning WARNING syntax keyword healthWarning WARNING[:]
\ containedin=markdownCodeBlock,mkdListItemLine \ containedin=markdownCodeBlock,mkdListItemLine
highlight link healthWarning WarningMsg highlight default link healthWarning WarningMsg
syntax keyword healthSuccess SUCCESS syntax keyword healthSuccess OK[:]
\ containedin=markdownCodeBlock,mkdListItemLine \ containedin=markdownCodeBlock,mkdListItemLine
highlight healthSuccess guibg=#5fff00 guifg=#080808 ctermbg=82 ctermfg=232 highlight default healthSuccess guibg=#5fff00 guifg=#080808 ctermbg=82 ctermfg=232
syntax match healthHelp "|.\{-}|" contains=healthBar syntax match healthHelp "|.\{-}|" contains=healthBar
\ containedin=markdownCodeBlock,mkdListItemLine \ containedin=markdownCodeBlock,mkdListItemLine
syntax match healthBar "|" contained conceal syntax match healthBar "|" contained conceal
highlight link healthHelp Identifier highlight default link healthHelp Identifier
" We do not care about markdown syntax errors in :CheckHealth output. " We do not care about markdown syntax errors in :checkhealth output.
highlight! link markdownError Normal highlight! link markdownError Normal
endfunction endfunction
@ -34,6 +34,7 @@ function! health#check(plugin_names) abort
setlocal filetype=markdown setlocal filetype=markdown
setlocal conceallevel=2 concealcursor=nc setlocal conceallevel=2 concealcursor=nc
setlocal keywordprg=:help setlocal keywordprg=:help
let &l:iskeyword='!-~,^*,^|,^",192-255'
call s:enhance_syntax() call s:enhance_syntax()
if empty(healthchecks) if empty(healthchecks)
@ -66,6 +67,7 @@ function! health#check(plugin_names) abort
" needed for plasticboy/vim-markdown, because it uses fdm=expr " needed for plasticboy/vim-markdown, because it uses fdm=expr
normal! zR normal! zR
setlocal nomodified setlocal nomodified
setlocal bufhidden=hide
redraw|echo '' redraw|echo ''
endfunction endfunction
@ -88,27 +90,27 @@ endfunction
" Changes ':h clipboard' to ':help |clipboard|'. " Changes ':h clipboard' to ':help |clipboard|'.
function! s:help_to_link(s) abort function! s:help_to_link(s) abort
return substitute(a:s, '\v[''"]?:h%[elp] ([^''"]+)[''"]?', '":help |\1|"', 'g') return substitute(a:s, '\v:h%[elp] ([^|][^"\r\n ]+)', ':help |\1|', 'g')
endfunction endfunction
" Format a message for a specific report item " Format a message for a specific report item
function! s:format_report_message(status, msg, ...) abort " {{{ function! s:format_report_message(status, msg, ...) abort " {{{
let output = ' - ' . a:status . ': ' . s:indent_after_line1(a:msg, 4) let output = ' - ' . a:status . ': ' . s:indent_after_line1(a:msg, 4)
let suggestions = [] let advice = []
" Optional parameters " Optional parameters
if a:0 > 0 if a:0 > 0
let suggestions = type(a:1) == type("") ? [a:1] : a:1 let advice = type(a:1) == type("") ? [a:1] : a:1
if type(suggestions) != type([]) if type(advice) != type([])
echoerr "Expected String or List" throw "Expected String or List"
endif endif
endif endif
" Report each suggestion " Report each suggestion
if len(suggestions) > 0 if len(advice) > 0
let output .= "\n - SUGGESTIONS:" let output .= "\n - ADVICE:"
endif endif
for suggestion in suggestions for suggestion in advice
let output .= "\n - " . s:indent_after_line1(suggestion, 10) let output .= "\n - " . s:indent_after_line1(suggestion, 10)
endfor endfor
@ -122,7 +124,7 @@ endfunction " }}}
" Reports a successful healthcheck. " Reports a successful healthcheck.
function! health#report_ok(msg) abort " {{{ function! health#report_ok(msg) abort " {{{
echo s:format_report_message('SUCCESS', a:msg) echo s:format_report_message('OK', a:msg)
endfunction " }}} endfunction " }}}
" Reports a health warning. " Reports a health warning.
@ -157,7 +159,10 @@ endfunction
" Translates a list of plugin names to healthcheck function names. " Translates a list of plugin names to healthcheck function names.
function! s:to_fn_names(plugin_names) abort function! s:to_fn_names(plugin_names) abort
let healthchecks = [] let healthchecks = []
for p in a:plugin_names let plugin_names = type('') ==# type(a:plugin_names)
\ ? split(a:plugin_names, '', v:false)
\ : a:plugin_names
for p in plugin_names
call add(healthchecks, 'health#'.p.'#check') call add(healthchecks, 'health#'.p.'#check')
endfor endfor
return healthchecks return healthchecks

View File

@ -1,15 +1,31 @@
let s:suggest_faq = 'See https://github.com/neovim/neovim/wiki/FAQ' let s:suggest_faq = 'https://github.com/neovim/neovim/wiki/FAQ'
function! s:check_config() abort function! s:check_config() abort
let ok = v:true
call health#report_start('Configuration') call health#report_start('Configuration')
if !get(g:, 'loaded_sensible', 0)
" If $VIM is empty we don't care. Else make sure it is valid.
if !empty($VIM) && !filereadable($VIM.'/runtime/doc/nvim.txt')
let ok = v:false
call health#report_error("$VIM is invalid: ".$VIM)
endif
if exists('$NVIM_TUI_ENABLE_CURSOR_SHAPE')
let ok = v:false
call health#report_warn("$NVIM_TUI_ENABLE_CURSOR_SHAPE is ignored in Nvim 0.2+",
\ [ "Use the 'guicursor' option to configure cursor shape. :help 'guicursor'",
\ 'https://github.com/neovim/neovim/wiki/Following-HEAD#20170402' ])
endif
if &paste
let ok = v:false
call health#report_error("'paste' is enabled. This option is only for pasting text.\nIt should not be set in your config.",
\ [ 'Remove `set paste` from your init.vim, if applicable.',
\ 'Check `:verbose set paste?` to see if a plugin or script set the option.', ])
endif
if ok
call health#report_ok('no issues found') call health#report_ok('no issues found')
else
let sensible_pi = globpath(&runtimepath, '**/sensible.vim', 1, 1)
call health#report_info("found sensible.vim plugin:\n".join(sensible_pi, "\n"))
call health#report_error("sensible.vim plugin is not needed; Nvim has the same defaults built-in."
\ ." Also, sensible.vim sets 'ttimeoutlen' to a sub-optimal value.",
\ ["Remove sensible.vim plugin, or wrap it in a `if !has('nvim')` check."])
endif endif
endfunction endfunction
@ -42,7 +58,7 @@ function! s:check_rplugin_manifest() abort
let contents = join(readfile(script)) let contents = join(readfile(script))
if contents =~# '\<\%(from\|import\)\s\+neovim\>' if contents =~# '\<\%(from\|import\)\s\+neovim\>'
if script =~# '[\/]__init__\.py$' if script =~# '[\/]__init__\.py$'
let script = fnamemodify(script, ':h') let script = tr(fnamemodify(script, ':h'), '\', '/')
endif endif
if !has_key(existing_rplugins, script) if !has_key(existing_rplugins, script)
@ -118,6 +134,12 @@ function! s:check_tmux() abort
let cmd = 'tmux show-option -qvg default-terminal' let cmd = 'tmux show-option -qvg default-terminal'
let out = system(cmd) let out = system(cmd)
let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g') let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g')
if empty(tmux_default_term)
let cmd = 'tmux show-option -qvgs default-terminal'
let out = system(cmd)
let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g')
endif
if v:shell_error if v:shell_error
call health#report_error('command failed: '.cmd."\n".out) call health#report_error('command failed: '.cmd."\n".out)
elseif tmux_default_term !=# $TERM elseif tmux_default_term !=# $TERM
@ -151,6 +173,11 @@ function! s:check_terminal() abort
call health#report_info('key_dc (kdch1) terminfo entry: ' call health#report_info('key_dc (kdch1) terminfo entry: '
\ .(empty(kbs_entry) ? '? (not found)' : kdch1_entry)) \ .(empty(kbs_entry) ? '? (not found)' : kdch1_entry))
endif endif
for env_var in ['XTERM_VERSION', 'VTE_VERSION', 'TERM_PROGRAM', 'COLORTERM', 'SSH_TTY']
if !exists('$'.env_var)
call health#report_info(printf("$%s='%s'", env_var, eval('$'.env_var)))
endif
endfor
endfunction endfunction
function! health#nvim#check() abort function! health#nvim#check() abort

View File

@ -8,6 +8,11 @@ function! s:trim(s) abort
return substitute(a:s, '^\_s*\|\_s*$', '', 'g') return substitute(a:s, '^\_s*\|\_s*$', '', 'g')
endfunction endfunction
" Convert '\' to '/'. Collapse '//' and '/./'.
function! s:normalize_path(s) abort
return substitute(substitute(a:s, '\', '/', 'g'), '/\./\|/\+', '/', 'g')
endfunction
" Simple version comparison. " Simple version comparison.
function! s:version_cmp(a, b) abort function! s:version_cmp(a, b) abort
let a = split(a:a, '\.', 0) let a = split(a:a, '\.', 0)
@ -26,13 +31,23 @@ endfunction
" Handler for s:system() function. " Handler for s:system() function.
function! s:system_handler(jobid, data, event) dict abort function! s:system_handler(jobid, data, event) dict abort
if a:event == 'stdout' || a:event == 'stderr' if a:event ==# 'stdout' || a:event ==# 'stderr'
let self.output .= join(a:data, '') let self.output .= join(a:data, '')
elseif a:event == 'exit' elseif a:event ==# 'exit'
let s:shell_error = a:data let s:shell_error = a:data
endif endif
endfunction endfunction
" Attempts to construct a shell command from an args list.
" Only for display, to help users debug a failed command.
function! s:shellify(cmd) abort
if type(a:cmd) != type([])
return a:cmd
endif
return join(map(copy(a:cmd),
\'v:val =~# ''\m[\-.a-zA-Z_/]'' ? shellescape(v:val) : v:val'), ' ')
endfunction
" Run a system command and timeout after 30 seconds. " Run a system command and timeout after 30 seconds.
function! s:system(cmd, ...) abort function! s:system(cmd, ...) abort
let stdin = a:0 ? a:1 : '' let stdin = a:0 ? a:1 : ''
@ -49,8 +64,7 @@ function! s:system(cmd, ...) abort
let jobid = jobstart(a:cmd, opts) let jobid = jobstart(a:cmd, opts)
if jobid < 1 if jobid < 1
call health#report_error(printf('Command error %d: %s', jobid, call health#report_error(printf('Command error (job=%d): %s', jobid, s:shellify(a:cmd)))
\ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd)))
let s:shell_error = 1 let s:shell_error = 1
return opts.output return opts.output
endif endif
@ -61,13 +75,11 @@ function! s:system(cmd, ...) abort
let res = jobwait([jobid], 30000) let res = jobwait([jobid], 30000)
if res[0] == -1 if res[0] == -1
call health#report_error(printf('Command timed out: %s', call health#report_error(printf('Command timed out: %s', s:shellify(a:cmd)))
\ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd))
call jobstop(jobid) call jobstop(jobid)
elseif s:shell_error != 0 && !ignore_error elseif s:shell_error != 0 && !ignore_error
call health#report_error(printf("Command error (%d) %s: %s", jobid, call health#report_error(printf("Command error (job=%d): %s\nOutput: %s", jobid,
\ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd, \ s:shellify(a:cmd), opts.output))
\ opts.output))
endif endif
return opts.output return opts.output
@ -106,13 +118,17 @@ endfunction
" Check for clipboard tools. " Check for clipboard tools.
function! s:check_clipboard() abort function! s:check_clipboard() abort
call health#report_start('Clipboard') call health#report_start('Clipboard (optional)')
let clipboard_tool = provider#clipboard#Executable() let clipboard_tool = provider#clipboard#Executable()
if empty(clipboard_tool) if exists('g:clipboard') && empty(clipboard_tool)
call health#report_error(
\ provider#clipboard#Error(),
\ ["Use the example in :help g:clipboard as a template, or don't set g:clipboard at all."])
elseif empty(clipboard_tool)
call health#report_warn( call health#report_warn(
\ "No clipboard tool found. Clipboard registers will not work.", \ 'No clipboard tool found. Clipboard registers (`"+` and `"*`) will not work.',
\ ['See ":help clipboard".']) \ [':help clipboard'])
else else
call health#report_ok('Clipboard tool found: '. clipboard_tool) call health#report_ok('Clipboard tool found: '. clipboard_tool)
endif endif
@ -152,7 +168,7 @@ function! s:version_info(python) abort
\ ])) \ ]))
if empty(python_version) if empty(python_version)
let python_version = 'unable to parse python response' let python_version = 'unable to parse '.a:python.' response'
endif endif
let nvim_path = s:trim(s:system([ let nvim_path = s:trim(s:system([
@ -164,14 +180,14 @@ function! s:version_info(python) abort
" Assuming that multiple versions of a package are installed, sort them " Assuming that multiple versions of a package are installed, sort them
" numerically in descending order. " numerically in descending order.
function! s:compare(metapath1, metapath2) function! s:compare(metapath1, metapath2) abort
let a = matchstr(fnamemodify(a:metapath1, ':p:h:t'), '[0-9.]\+') let a = matchstr(fnamemodify(a:metapath1, ':p:h:t'), '[0-9.]\+')
let b = matchstr(fnamemodify(a:metapath2, ':p:h:t'), '[0-9.]\+') let b = matchstr(fnamemodify(a:metapath2, ':p:h:t'), '[0-9.]\+')
return a == b ? 0 : a > b ? 1 : -1 return a == b ? 0 : a > b ? 1 : -1
endfunction endfunction
" Try to get neovim.VERSION (added in 0.1.11dev). " Try to get neovim.VERSION (added in 0.1.11dev).
let nvim_version = s:system(['python', '-c', let nvim_version = s:system([a:python, '-c',
\ 'from neovim import VERSION as v; '. \ 'from neovim import VERSION as v; '.
\ 'print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))'], \ 'print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))'],
\ '', 1, 1) \ '', 1, 1)
@ -208,7 +224,7 @@ endfunction
" Check the Python interpreter's usability. " Check the Python interpreter's usability.
function! s:check_bin(bin) abort function! s:check_bin(bin) abort
if !filereadable(a:bin) if !filereadable(a:bin) && (!has('win32') || !filereadable(a:bin.'.exe'))
call health#report_error(printf('"%s" was not found.', a:bin)) call health#report_error(printf('"%s" was not found.', a:bin))
return 0 return 0
elseif executable(a:bin) != 1 elseif executable(a:bin) != 1
@ -219,11 +235,11 @@ function! s:check_bin(bin) abort
endfunction endfunction
function! s:check_python(version) abort function! s:check_python(version) abort
call health#report_start('Python ' . a:version . ' provider') call health#report_start('Python ' . a:version . ' provider (optional)')
let pyname = 'python'.(a:version == 2 ? '' : '3') let pyname = 'python'.(a:version == 2 ? '' : '3')
let pyenv = resolve(exepath('pyenv')) let pyenv = resolve(exepath('pyenv'))
let pyenv_root = exists('$PYENV_ROOT') ? resolve($PYENV_ROOT) : 'n' let pyenv_root = exists('$PYENV_ROOT') ? resolve($PYENV_ROOT) : ''
let venv = exists('$VIRTUAL_ENV') ? resolve($VIRTUAL_ENV) : '' let venv = exists('$VIRTUAL_ENV') ? resolve($VIRTUAL_ENV) : ''
let host_prog_var = pyname.'_host_prog' let host_prog_var = pyname.'_host_prog'
let loaded_var = 'g:loaded_'.pyname.'_provider' let loaded_var = 'g:loaded_'.pyname.'_provider'
@ -235,6 +251,19 @@ function! s:check_python(version) abort
return return
endif endif
if !empty(pyenv)
if empty(pyenv_root)
call health#report_warn(
\ 'pyenv was found, but $PYENV_ROOT is not set.',
\ ['Did you follow the final install instructions?',
\ 'If you use a shell "framework" like Prezto or Oh My Zsh, try without.',
\ 'Try a different shell (bash).']
\ )
else
call health#report_ok(printf('pyenv found: "%s"', pyenv))
endif
endif
if exists('g:'.host_prog_var) if exists('g:'.host_prog_var)
call health#report_info(printf('Using: g:%s = "%s"', host_prog_var, get(g:, host_prog_var))) call health#report_info(printf('Using: g:%s = "%s"', host_prog_var, get(g:, host_prog_var)))
endif endif
@ -266,15 +295,6 @@ function! s:check_python(version) abort
endif endif
if !empty(pyenv) if !empty(pyenv)
if empty(pyenv_root)
call health#report_warn(
\ 'pyenv was found, but $PYENV_ROOT is not set.',
\ ['Did you follow the final install instructions?']
\ )
else
call health#report_ok(printf('pyenv found: "%s"', pyenv))
endif
let python_bin = s:trim(s:system([pyenv, 'which', pyname], '', 1)) let python_bin = s:trim(s:system([pyenv, 'which', pyname], '', 1))
if empty(python_bin) if empty(python_bin)
@ -287,8 +307,9 @@ function! s:check_python(version) abort
if exists('$PATH') if exists('$PATH')
for path in split($PATH, has('win32') ? ';' : ':') for path in split($PATH, has('win32') ? ';' : ':')
let path_bin = path.'/'.pyname let path_bin = s:normalize_path(path.'/'.pyname)
if path_bin != python_bin && index(python_multiple, path_bin) == -1 if path_bin != s:normalize_path(python_bin)
\ && index(python_multiple, path_bin) == -1
\ && executable(path_bin) \ && executable(path_bin)
call add(python_multiple, path_bin) call add(python_multiple, path_bin)
endif endif
@ -303,9 +324,8 @@ function! s:check_python(version) abort
if python_bin =~# '\<shims\>' if python_bin =~# '\<shims\>'
call health#report_warn(printf('`%s` appears to be a pyenv shim.', python_bin), [ call health#report_warn(printf('`%s` appears to be a pyenv shim.', python_bin), [
\ 'The `pyenv` executable is not in $PATH,', \ '`pyenv` is not in $PATH, your pyenv installation is broken. '
\ 'Your pyenv installation is broken. You should set ' \ .'Set `g:'.host_prog_var.'` to avoid surprises.',
\ . '`g:'.host_prog_var.'` to avoid surprises.',
\ ]) \ ])
endif endif
endif endif
@ -318,7 +338,7 @@ function! s:check_python(version) abort
call health#report_warn('pyenv is not set up optimally.', [ call health#report_warn('pyenv is not set up optimally.', [
\ printf('Create a virtualenv specifically ' \ printf('Create a virtualenv specifically '
\ . 'for Neovim using pyenv, and set `g:%s`. This will avoid ' \ . 'for Neovim using pyenv, and set `g:%s`. This will avoid '
\ . 'the need to install Neovim''s Python module in each ' \ . 'the need to install the Neovim Python module in each '
\ . 'version/virtualenv.', host_prog_var) \ . 'version/virtualenv.', host_prog_var)
\ ]) \ ])
elseif !empty(venv) && exists('g:'.host_prog_var) elseif !empty(venv) && exists('g:'.host_prog_var)
@ -413,7 +433,7 @@ function! s:check_python(version) abort
endfunction endfunction
function! s:check_ruby() abort function! s:check_ruby() abort
call health#report_start('Ruby provider') call health#report_start('Ruby provider (optional)')
let loaded_var = 'g:loaded_ruby_provider' let loaded_var = 'g:loaded_ruby_provider'
if exists(loaded_var) && !exists('*provider#ruby#Call') if exists(loaded_var) && !exists('*provider#ruby#Call')
@ -423,8 +443,8 @@ function! s:check_ruby() abort
if !executable('ruby') || !executable('gem') if !executable('ruby') || !executable('gem')
call health#report_warn( call health#report_warn(
\ "`ruby` and `gem` must be in $PATH.", \ '`ruby` and `gem` must be in $PATH.',
\ ["Install Ruby and verify that `ruby` and `gem` commands work."]) \ ['Install Ruby and verify that `ruby` and `gem` commands work.'])
return return
endif endif
call health#report_info('Ruby: '. s:system('ruby -v')) call health#report_info('Ruby: '. s:system('ruby -v'))
@ -439,21 +459,21 @@ function! s:check_ruby() abort
endif endif
call health#report_info('Host: '. host) call health#report_info('Host: '. host)
let latest_gem_cmd = 'gem list -ra ^neovim$' let latest_gem_cmd = has('win32') ? 'cmd /c gem list -ra ^^neovim$' : 'gem list -ra ^neovim$'
let latest_gem = s:system(split(latest_gem_cmd)) let latest_gem = s:system(split(latest_gem_cmd))
if s:shell_error || empty(latest_gem) if s:shell_error || empty(latest_gem)
call health#report_error('Failed to run: '. latest_gem_cmd, call health#report_error('Failed to run: '. latest_gem_cmd,
\ ["Make sure you're connected to the internet.", \ ["Make sure you're connected to the internet.",
\ "Are you behind a firewall or proxy?"]) \ 'Are you behind a firewall or proxy?'])
return return
endif endif
let latest_gem = get(split(latest_gem, ' (\|, \|)$' ), 1, 'not found') let latest_gem = get(split(latest_gem, 'neovim (\|, \|)$' ), 1, 'not found')
let current_gem_cmd = host .' --version' let current_gem_cmd = host .' --version'
let current_gem = s:system(current_gem_cmd) let current_gem = s:system(current_gem_cmd)
if s:shell_error if s:shell_error
call health#report_error('Failed to run: '. current_gem_cmd, call health#report_error('Failed to run: '. current_gem_cmd,
\ ["Report this issue with the output of: ", current_gem_cmd]) \ ['Report this issue with the output of: ', current_gem_cmd])
return return
endif endif
@ -467,9 +487,71 @@ function! s:check_ruby() abort
endif endif
endfunction endfunction
function! s:check_node() abort
call health#report_start('Node provider (optional)')
let loaded_var = 'g:loaded_node_provider'
if exists(loaded_var) && !exists('*provider#node#Call')
call health#report_info('Disabled. '.loaded_var.'='.eval(loaded_var))
return
endif
if !executable('node') || !executable('npm')
call health#report_warn(
\ '`node` and `npm` must be in $PATH.',
\ ['Install Node.js and verify that `node` and `npm` commands work.'])
return
endif
call health#report_info('Node: '. s:system('node -v'))
let host = provider#node#Detect()
if empty(host)
call health#report_warn('Missing "neovim" npm package.',
\ ['Run in shell: npm install -g neovim',
\ 'Is the npm bin directory in $PATH?'])
return
endif
call health#report_info('Host: '. host)
let latest_npm_cmd = has('win32') ? 'cmd /c npm info neovim --json' : 'npm info neovim --json'
let latest_npm = s:system(split(latest_npm_cmd))
if s:shell_error || empty(latest_npm)
call health#report_error('Failed to run: '. latest_npm_cmd,
\ ["Make sure you're connected to the internet.",
\ 'Are you behind a firewall or proxy?'])
return
endif
if !empty(latest_npm)
try
let pkg_data = json_decode(latest_npm)
catch /E474/
return 'error: '.latest_npm
endtry
let latest_npm = get(get(pkg_data, 'dist-tags', {}), 'latest', 'unable to parse')
endif
let current_npm_cmd = host .' --version'
let current_npm = s:system(current_npm_cmd)
if s:shell_error
call health#report_error('Failed to run: '. current_npm_cmd,
\ ['Report this issue with the output of: ', current_npm_cmd])
return
endif
if s:version_cmp(current_npm, latest_npm) == -1
call health#report_warn(
\ printf('Package "neovim" is out-of-date. Installed: %s, latest: %s',
\ current_npm, latest_npm),
\ ['Run in shell: npm update neovim'])
else
call health#report_ok('Latest "neovim" npm is installed: '. current_npm)
endif
endfunction
function! health#provider#check() abort function! health#provider#check() abort
call s:check_clipboard() call s:check_clipboard()
call s:check_python(2) call s:check_python(2)
call s:check_python(3) call s:check_python(3)
call s:check_ruby() call s:check_ruby()
call s:check_node()
endfunction endfunction

View File

@ -1,7 +1,7 @@
" Vim completion script " Vim completion script
" Language: Java Script " Language: Java Script
" Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) " Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl )
" Last Change: 2006 Apr 30 " Last Change: 2017 Mar 04
function! javascriptcomplete#CompleteJS(findstart, base) function! javascriptcomplete#CompleteJS(findstart, base)
if a:findstart if a:findstart
@ -563,7 +563,7 @@ function! javascriptcomplete#CompleteJS(findstart, base)
for i in arguments for i in arguments
let g:ia = i let g:ia = i
let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))') let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))')
if len(f_elements) == 3 if len(f_elements) >= 3
let b:js_menuinfo[f_elements[1].'('] = f_elements[2] let b:js_menuinfo[f_elements[1].'('] = f_elements[2]
endif endif
endfor endfor

View File

@ -1,16 +1,31 @@
" Maintainer: Anmol Sethi <anmol@aubble.com> " Maintainer: Anmol Sethi <anmol@aubble.com>
let s:man_find_arg = "-w" let s:find_arg = '-w'
let s:localfile_arg = v:true " Always use -l if possible. #6683
let s:section_arg = '-s'
" TODO(nhooyr) Completion may work on SunOS; I'm not sure if `man -l` displays function! s:init_section_flag()
" the list of searched directories. call system(['env', 'MANPAGER=cat', 'man', s:section_arg, '1', 'man'])
try if v:shell_error
if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~# '^5' let s:section_arg = '-S'
let s:man_find_arg = '-l'
endif endif
catch /E145:/ endfunction
" Ignore the error in restricted mode
endtry function! s:init() abort
call s:init_section_flag()
" TODO(nhooyr): Does `man -l` on SunOS list searched directories?
try
if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~# '^5'
let s:find_arg = '-l'
endif
" Check for -l support.
call s:get_page(s:get_path('', 'man')[0:-2])
catch /E145:/
" Ignore the error in restricted mode
catch /command error .*/
let s:localfile_arg = v:false
endtry
endfunction
function! man#open_page(count, count1, mods, ...) abort function! man#open_page(count, count1, mods, ...) abort
if a:0 > 2 if a:0 > 2
@ -79,7 +94,7 @@ function! man#read_page(ref) abort
let [sect, name, path] = s:verify_exists(sect, name) let [sect, name, path] = s:verify_exists(sect, name)
let page = s:get_page(path) let page = s:get_page(path)
catch catch
" call to s:error() is unnecessary call s:error(v:exception)
return return
endtry endtry
let b:man_sect = sect let b:man_sect = sect
@ -88,10 +103,8 @@ endfunction
" Handler for s:system() function. " Handler for s:system() function.
function! s:system_handler(jobid, data, event) dict abort function! s:system_handler(jobid, data, event) dict abort
if a:event == 'stdout' if a:event is# 'stdout' || a:event is# 'stderr'
let self.stdout .= join(a:data, "\n") let self[a:event] .= join(a:data, "\n")
elseif a:event == 'stderr'
let self.stderr .= join(a:data, "\n")
else else
let self.exit_code = a:data let self.exit_code = a:data
endif endif
@ -118,7 +131,7 @@ function! s:system(cmd, ...) abort
try try
call jobstop(jobid) call jobstop(jobid)
throw printf('command timed out: %s', join(a:cmd)) throw printf('command timed out: %s', join(a:cmd))
catch /^Vim\%((\a\+)\)\=:E900/ catch /^Vim(call):E900:/
endtry endtry
elseif res[0] == -2 elseif res[0] == -2
throw printf('command interrupted: %s', join(a:cmd)) throw printf('command interrupted: %s', join(a:cmd))
@ -135,7 +148,8 @@ function! s:get_page(path) abort
let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH
" Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db). " Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).
" http://comments.gmane.org/gmane.editors.vim.devel/29085 " http://comments.gmane.org/gmane.editors.vim.devel/29085
return s:system(['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man', a:path]) let cmd = ['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man']
return s:system(cmd + (s:localfile_arg ? ['-l', a:path] : [a:path]))
endfunction endfunction
function! s:put_page(page) abort function! s:put_page(page) abort
@ -151,6 +165,31 @@ function! s:put_page(page) abort
setlocal filetype=man setlocal filetype=man
endfunction endfunction
function! man#show_toc() abort
let bufname = bufname('%')
let info = getloclist(0, {'winid': 1})
if !empty(info) && getwinvar(info.winid, 'qf_toc') ==# bufname
lopen
return
endif
let toc = []
let lnum = 2
let last_line = line('$') - 1
while lnum && lnum < last_line
let text = getline(lnum)
if text =~# '^\%( \{3\}\)\=\S.*$'
call add(toc, {'bufnr': bufnr('%'), 'lnum': lnum, 'text': text})
endif
let lnum = nextnonblank(lnum + 1)
endwhile
call setloclist(0, toc, ' ')
call setloclist(0, [], 'a', {'title': 'Man TOC'})
lopen
let w:qf_toc = bufname
endfunction
" attempt to extract the name and sect out of 'name(sect)' " attempt to extract the name and sect out of 'name(sect)'
" otherwise just return the largest string of valid characters in ref " otherwise just return the largest string of valid characters in ref
function! man#extract_sect_and_name_ref(ref) abort function! man#extract_sect_and_name_ref(ref) abort
@ -174,14 +213,14 @@ endfunction
function! s:get_path(sect, name) abort function! s:get_path(sect, name) abort
if empty(a:sect) if empty(a:sect)
return s:system(['man', s:man_find_arg, a:name]) return s:system(['man', s:find_arg, a:name])
endif endif
" '-s' flag handles: " '-s' flag handles:
" - tokens like 'printf(echo)' " - tokens like 'printf(echo)'
" - sections starting with '-' " - sections starting with '-'
" - 3pcap section (found on macOS) " - 3pcap section (found on macOS)
" - commas between sections (for section priority) " - commas between sections (for section priority)
return s:system(['man', s:man_find_arg, '-s', a:sect, a:name]) return s:system(['man', s:find_arg, s:section_arg, a:sect, a:name])
endfunction endfunction
function! s:verify_exists(sect, name) abort function! s:verify_exists(sect, name) abort
@ -306,7 +345,7 @@ endfunction
function! s:complete(sect, psect, name) abort function! s:complete(sect, psect, name) abort
try try
let mandirs = join(split(s:system(['man', s:man_find_arg]), ':\|\n'), ',') let mandirs = join(split(s:system(['man', s:find_arg]), ':\|\n'), ',')
catch catch
call s:error(v:exception) call s:error(v:exception)
return return
@ -348,3 +387,5 @@ function! man#init_pager() abort
endtry endtry
execute 'silent file man://'.fnameescape(ref) execute 'silent file man://'.fnameescape(ref)
endfunction endfunction
call s:init()

View File

@ -22,8 +22,8 @@
if &cp || exists("g:loaded_netrw") if &cp || exists("g:loaded_netrw")
finish finish
endif endif
" netrw requires vim having patch 213; netrw will benefit from vim's having patch#656, too " netrw requires vim having patch 7.4.213; netrw will benefit from vim's having patch#656, too
if v:version < 704 || !has("patch213") if v:version < 704 || (v:version == 704 && !has("patch213"))
if !exists("s:needpatch213") if !exists("s:needpatch213")
unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch 213" unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch 213"
endif endif

View File

@ -1,6 +1,6 @@
" Vim support file to help with paste mappings and menus " Vim support file to help with paste mappings and menus
" Maintainer: Bram Moolenaar <Bram@vim.org> " Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2006 Jun 23 " Last Change: 2017 Aug 30
" Define the string to use for items that are present both in Edit, Popup and " Define the string to use for items that are present both in Edit, Popup and
" Toolbar menu. Also used in mswin.vim and macmap.vim. " Toolbar menu. Also used in mswin.vim and macmap.vim.
@ -12,7 +12,7 @@
if has("virtualedit") if has("virtualedit")
let paste#paste_cmd = {'n': ":call paste#Paste()<CR>"} let paste#paste_cmd = {'n': ":call paste#Paste()<CR>"}
let paste#paste_cmd['v'] = '"-c<Esc>' . paste#paste_cmd['n'] let paste#paste_cmd['v'] = '"-c<Esc>' . paste#paste_cmd['n']
let paste#paste_cmd['i'] = 'x<BS><Esc>' . paste#paste_cmd['n'] . 'gi' let paste#paste_cmd['i'] = "\<c-\>\<c-o>\"+gP"
func! paste#Paste() func! paste#Paste()
let ove = &ve let ove = &ve

View File

@ -3,7 +3,7 @@
" Maintainer: Dávid Szabó ( complex857 AT gmail DOT com ) " Maintainer: Dávid Szabó ( complex857 AT gmail DOT com )
" Previous Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) " Previous Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl )
" URL: https://github.com/shawncplus/phpcomplete.vim " URL: https://github.com/shawncplus/phpcomplete.vim
" Last Change: 2015 Jul 13 " Last Change: 2016 Oct 10
" "
" OPTIONS: " OPTIONS:
" "
@ -195,6 +195,8 @@ function! phpcomplete#CompletePHP(findstart, base) " {{{
" }}} " }}}
elseif context =~? 'implements' elseif context =~? 'implements'
return phpcomplete#CompleteClassName(a:base, ['i'], current_namespace, imports) return phpcomplete#CompleteClassName(a:base, ['i'], current_namespace, imports)
elseif context =~? 'instanceof'
return phpcomplete#CompleteClassName(a:base, ['c', 'n'], current_namespace, imports)
elseif context =~? 'extends\s\+.\+$' && a:base == '' elseif context =~? 'extends\s\+.\+$' && a:base == ''
return ['implements'] return ['implements']
elseif context =~? 'extends' elseif context =~? 'extends'
@ -787,6 +789,8 @@ function! phpcomplete#CompleteClassName(base, kinds, current_namespace, imports)
if kinds == ['c', 'i'] if kinds == ['c', 'i']
let filterstr = 'v:val =~? "\\(class\\|interface\\)\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"' let filterstr = 'v:val =~? "\\(class\\|interface\\)\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"'
elseif kinds == ['c', 'n']
let filterstr = 'v:val =~? "\\(class\\|namespace\\)\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"'
elseif kinds == ['c'] elseif kinds == ['c']
let filterstr = 'v:val =~? "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"' let filterstr = 'v:val =~? "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"'
elseif kinds == ['i'] elseif kinds == ['i']
@ -931,7 +935,7 @@ function! phpcomplete#EvaluateModifiers(modifiers, required_modifiers, prohibite
endfor endfor
for modifier in a:modifiers for modifier in a:modifiers
" if the modifier is prohibited its a no match " if the modifier is prohibited it's a no match
if index(a:prohibited_modifiers, modifier) != -1 if index(a:prohibited_modifiers, modifier) != -1
return 0 return 0
endif endif
@ -996,7 +1000,7 @@ function! phpcomplete#CompleteUserClass(context, base, sccontent, visibility) "
let required_modifiers += ['static'] let required_modifiers += ['static']
endif endif
let all_variable = filter(deepcopy(a:sccontent), let all_variable = filter(deepcopy(a:sccontent),
\ 'v:val =~ "^\\s*\\(var\\s\\+\\|public\\s\\+\\|protected\\s\\+\\|private\\s\\+\\|final\\s\\+\\|abstract\\s\\+\\|static\\s\\+\\)\\+\\$"') \ 'v:val =~ "\\(^\\s*\\(var\\s\\+\\|public\\s\\+\\|protected\\s\\+\\|private\\s\\+\\|final\\s\\+\\|abstract\\s\\+\\|static\\s\\+\\)\\+\\$\\|^\\s*\\(\\/\\|\\*\\)*\\s*@property\\s\\+\\S\\+\\s\\S\\{-}\\s*$\\)"')
let variables = [] let variables = []
for i in all_variable for i in all_variable
@ -1160,6 +1164,14 @@ function! phpcomplete#GetTaglist(pattern) " {{{
endif endif
let tags = taglist(a:pattern) let tags = taglist(a:pattern)
for tag in tags
for prop in keys(tag)
if prop == 'cmd' || prop == 'static' || prop == 'kind' || prop == 'builtin'
continue
endif
let tag[prop] = substitute(tag[prop], '\\\\', '\\', 'g')
endfor
endfor
let s:cache_tags[a:pattern] = tags let s:cache_tags[a:pattern] = tags
let has_key = has_key(s:cache_tags, a:pattern) let has_key = has_key(s:cache_tags, a:pattern)
let s:cache_tags_checksum = cache_checksum let s:cache_tags_checksum = cache_checksum
@ -1379,7 +1391,7 @@ function! phpcomplete#GetCallChainReturnType(classname_candidate, class_candidat
" Get Structured information of all classes and subclasses including namespace and includes " Get Structured information of all classes and subclasses including namespace and includes
" try to find the method's return type in docblock comment " try to find the method's return type in docblock comment
for classstructure in classcontents for classstructure in classcontents
let docblock_target_pattern = 'function\s\+&\?'.method.'\|\(public\|private\|protected\|var\).\+\$'.method let docblock_target_pattern = 'function\s\+&\?'.method.'\>\|\(public\|private\|protected\|var\).\+\$'.method.'\>\|@property.\+\$'.method.'\>'
let doc_str = phpcomplete#GetDocBlock(split(classstructure.content, '\n'), docblock_target_pattern) let doc_str = phpcomplete#GetDocBlock(split(classstructure.content, '\n'), docblock_target_pattern)
if doc_str != '' if doc_str != ''
break break
@ -1387,8 +1399,17 @@ function! phpcomplete#GetCallChainReturnType(classname_candidate, class_candidat
endfor endfor
if doc_str != '' if doc_str != ''
let docblock = phpcomplete#ParseDocBlock(doc_str) let docblock = phpcomplete#ParseDocBlock(doc_str)
if has_key(docblock.return, 'type') || has_key(docblock.var, 'type') if has_key(docblock.return, 'type') || has_key(docblock.var, 'type') || len(docblock.properties) > 0
let type = has_key(docblock.return, 'type') ? docblock.return.type : docblock.var.type let type = has_key(docblock.return, 'type') ? docblock.return.type : has_key(docblock.var, 'type') ? docblock.var.type : ''
if type == ''
for property in docblock.properties
if property.description =~? method
let type = property.type
break
endif
endfor
endif
" there's a namespace in the type, threat the type as FQCN " there's a namespace in the type, threat the type as FQCN
if type =~ '\\' if type =~ '\\'
@ -1554,6 +1575,9 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
elseif get(methodstack, 0) =~# function_invocation_pattern elseif get(methodstack, 0) =~# function_invocation_pattern
let function_name = matchstr(methodstack[0], '^\s*\zs'.function_name_pattern) let function_name = matchstr(methodstack[0], '^\s*\zs'.function_name_pattern)
let function_file = phpcomplete#GetFunctionLocation(function_name, a:current_namespace) let function_file = phpcomplete#GetFunctionLocation(function_name, a:current_namespace)
if function_file == ''
let function_file = phpcomplete#GetFunctionLocation(function_name, '\')
endif
if function_file == 'VIMPHP_BUILTINFUNCTION' if function_file == 'VIMPHP_BUILTINFUNCTION'
" built in function, grab the return type from the info string " built in function, grab the return type from the info string
@ -1569,7 +1593,7 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace(file_lines) let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace(file_lines)
" try to expand the classname of the returned type with the context got from the function's source file " try to expand the classname of the returned type with the context got from the function's source file
let [classname_candidate, unused] = phpcomplete#ExpandClassName(classname_candidate, class_candidate_namespace, function_imports) let [classname_candidate, class_candidate_namespace] = phpcomplete#ExpandClassName(classname_candidate, class_candidate_namespace, function_imports)
endif endif
endif endif
if classname_candidate != '' if classname_candidate != ''
@ -1650,9 +1674,10 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
let sub_methodstack = phpcomplete#GetMethodStack(matchstr(line, '^\s*'.object.'\s*=&\?\s*\s\+\zs.*')) let sub_methodstack = phpcomplete#GetMethodStack(matchstr(line, '^\s*'.object.'\s*=&\?\s*\s\+\zs.*'))
let [classname_candidate, class_candidate_namespace] = phpcomplete#GetCallChainReturnType( let [classname_candidate, class_candidate_namespace] = phpcomplete#GetCallChainReturnType(
\ classname, \ classname,
\ a:current_namespace, \ namespace_for_class,
\ a:imports, \ a:imports,
\ sub_methodstack) \ sub_methodstack)
return (class_candidate_namespace == '\' || class_candidate_namespace == '') ? classname_candidate : class_candidate_namespace.'\'.classname_candidate return (class_candidate_namespace == '\' || class_candidate_namespace == '') ? classname_candidate : class_candidate_namespace.'\'.classname_candidate
endif endif
endif endif
@ -1783,6 +1808,9 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
let [function_name, function_namespace] = phpcomplete#ExpandClassName(function_name, a:current_namespace, a:imports) let [function_name, function_namespace] = phpcomplete#ExpandClassName(function_name, a:current_namespace, a:imports)
let function_file = phpcomplete#GetFunctionLocation(function_name, function_namespace) let function_file = phpcomplete#GetFunctionLocation(function_name, function_namespace)
if function_file == ''
let function_file = phpcomplete#GetFunctionLocation(function_name, '\')
endif
if function_file == 'VIMPHP_BUILTINFUNCTION' if function_file == 'VIMPHP_BUILTINFUNCTION'
" built in function, grab the return type from the info string " built in function, grab the return type from the info string
@ -1798,7 +1826,7 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
let classname_candidate = docblock.return.type let classname_candidate = docblock.return.type
let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace(file_lines) let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace(file_lines)
" try to expand the classname of the returned type with the context got from the function's source file " try to expand the classname of the returned type with the context got from the function's source file
let [classname_candidate, unused] = phpcomplete#ExpandClassName(classname_candidate, class_candidate_namespace, function_imports) let [classname_candidate, class_candidate_namespace] = phpcomplete#ExpandClassName(classname_candidate, class_candidate_namespace, function_imports)
break break
endif endif
endif endif
@ -1861,6 +1889,8 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
for tag in tags for tag in tags
if tag.kind ==? 'v' && tag.cmd =~? '=\s*new\s\+\zs'.class_name_pattern.'\ze' if tag.kind ==? 'v' && tag.cmd =~? '=\s*new\s\+\zs'.class_name_pattern.'\ze'
let classname = matchstr(tag.cmd, '=\s*new\s\+\zs'.class_name_pattern.'\ze') let classname = matchstr(tag.cmd, '=\s*new\s\+\zs'.class_name_pattern.'\ze')
" unescape the classname, it would have "\" doubled since it is an ex command
let classname = substitute(classname, '\\\(\_.\)', '\1', 'g')
return classname return classname
endif endif
endfor endfor
@ -2077,6 +2107,19 @@ function! phpcomplete#GetClassContentsStructure(file_path, file_lines, class_nam
endif endif
call searchpair('{', '', '}', 'W') call searchpair('{', '', '}', 'W')
let class_closing_bracket_line = line('.') let class_closing_bracket_line = line('.')
" Include class docblock
let doc_line = cfline - 1
if getline(doc_line) =~? '^\s*\*/'
while doc_line != 0
if getline(doc_line) =~? '^\s*/\*\*'
let cfline = doc_line
break
endif
let doc_line -= 1
endwhile
endif
let classcontent = join(getline(cfline, class_closing_bracket_line), "\n") let classcontent = join(getline(cfline, class_closing_bracket_line), "\n")
let used_traits = [] let used_traits = []
@ -2241,8 +2284,19 @@ function! phpcomplete#GetDocBlock(sccontent, search) " {{{
let line = a:sccontent[i] let line = a:sccontent[i]
" search for a function declaration " search for a function declaration
if line =~? a:search if line =~? a:search
let l = i - 1 if line =~? '@property'
" start backward serch for the comment block let doc_line = i
while doc_line != sccontent_len - 1
if a:sccontent[doc_line] =~? '^\s*\*/'
let l = doc_line
break
endif
let doc_line += 1
endwhile
else
let l = i - 1
endif
" start backward search for the comment block
while l != 0 while l != 0
let line = a:sccontent[l] let line = a:sccontent[l]
" if it's a one line docblock like comment and we can just return it right away " if it's a one line docblock like comment and we can just return it right away
@ -2263,7 +2317,7 @@ function! phpcomplete#GetDocBlock(sccontent, search) " {{{
return '' return ''
end end
while l != 0 while l >= 0
let line = a:sccontent[l] let line = a:sccontent[l]
if line =~? '^\s*/\*\*' if line =~? '^\s*/\*\*'
let comment_start = l let comment_start = l
@ -2297,9 +2351,10 @@ function! phpcomplete#ParseDocBlock(docblock) " {{{
\ 'return': {}, \ 'return': {},
\ 'throws': [], \ 'throws': [],
\ 'var': {}, \ 'var': {},
\ 'properties': [],
\ } \ }
let res.description = substitute(matchstr(a:docblock, '\zs\_.\{-}\ze\(@var\|@param\|@return\|$\)'), '\(^\_s*\|\_s*$\)', '', 'g') let res.description = substitute(matchstr(a:docblock, '\zs\_.\{-}\ze\(@type\|@var\|@param\|@return\|$\)'), '\(^\_s*\|\_s*$\)', '', 'g')
let docblock_lines = split(a:docblock, "\n") let docblock_lines = split(a:docblock, "\n")
let param_lines = filter(copy(docblock_lines), 'v:val =~? "^@param"') let param_lines = filter(copy(docblock_lines), 'v:val =~? "^@param"')
@ -2334,15 +2389,26 @@ function! phpcomplete#ParseDocBlock(docblock) " {{{
endif endif
endfor endfor
let var_line = filter(copy(docblock_lines), 'v:val =~? "^@var"') let var_line = filter(copy(docblock_lines), 'v:val =~? "^\\(@var\\|@type\\)"')
if len(var_line) > 0 if len(var_line) > 0
let var_parts = matchlist(var_line[0], '@var\s\+\(\S\+\)\s*\(.*\)') let var_parts = matchlist(var_line[0], '\(@var\|@type\)\s\+\(\S\+\)\s*\(.*\)')
let res['var'] = { let res['var'] = {
\ 'line': var_parts[0], \ 'line': var_parts[0],
\ 'type': phpcomplete#GetTypeFromDocBlockParam(get(var_parts, 1, '')), \ 'type': phpcomplete#GetTypeFromDocBlockParam(get(var_parts, 2, '')),
\ 'description': get(var_parts, 2, '')} \ 'description': get(var_parts, 3, '')}
endif endif
let property_lines = filter(copy(docblock_lines), 'v:val =~? "^@property"')
for property_line in property_lines
let parts = matchlist(property_line, '\(@property\)\s\+\(\S\+\)\s*\(.*\)')
if len(parts) > 0
call add(res.properties, {
\ 'line': parts[0],
\ 'type': phpcomplete#GetTypeFromDocBlockParam(get(parts, 2, '')),
\ 'description': get(parts, 3, '')})
endif
endfor
return res return res
endfunction endfunction
" }}} " }}}
@ -2498,6 +2564,7 @@ function! phpcomplete#GetCurrentNameSpace(file_lines) " {{{
let name = matchstr(name, '\\\zs[^\\]\+\ze$') let name = matchstr(name, '\\\zs[^\\]\+\ze$')
endif endif
endif endif
" leading slash is not required use imports are always absolute " leading slash is not required use imports are always absolute
let imports[name] = {'name': object, 'kind': ''} let imports[name] = {'name': object, 'kind': ''}
endfor endfor
@ -2533,6 +2600,7 @@ function! phpcomplete#GetCurrentNameSpace(file_lines) " {{{
elseif !exists('no_namespace_candidate') elseif !exists('no_namespace_candidate')
" save the first namespacless match to be used if no better " save the first namespacless match to be used if no better
" candidate found later on " candidate found later on
let tag.namespace = namespace_for_classes
let no_namespace_candidate = tag let no_namespace_candidate = tag
endif endif
endif endif

View File

@ -0,0 +1,20 @@
" Common functionality for providers
let s:stderr = {}
function! provider#stderr_collector(chan_id, data, event)
let stderr = get(s:stderr, a:chan_id, [''])
let stderr[-1] .= a:data[0]
call extend(stderr, a:data[1:])
let s:stderr[a:chan_id] = stderr
endfunction
function! provider#clear_stderr(chan_id)
if has_key(s:stderr, a:chan_id)
call remove(s:stderr, a:chan_id)
endif
endfunction
function! provider#get_stderr(chan_id)
return get(s:stderr, a:chan_id, [])
endfunction

View File

@ -3,28 +3,36 @@
" available. " available.
let s:copy = {} let s:copy = {}
let s:paste = {} let s:paste = {}
let s:clipboard = {}
" When caching is enabled, store the jobid of the xclip/xsel process keeping " When caching is enabled, store the jobid of the xclip/xsel process keeping
" ownership of the selection, so we know how long the cache is valid. " ownership of the selection, so we know how long the cache is valid.
let s:selection = { 'owner': 0, 'data': [] } let s:selection = { 'owner': 0, 'data': [], 'on_stderr': function('provider#stderr_collector') }
function! s:selection.on_exit(jobid, data, event) function! s:selection.on_exit(jobid, data, event) abort
" At this point this nvim instance might already have launched " At this point this nvim instance might already have launched
" a new provider instance. Don't drop ownership in this case. " a new provider instance. Don't drop ownership in this case.
if self.owner == a:jobid if self.owner == a:jobid
let self.owner = 0 let self.owner = 0
endif endif
if a:data != 0
let stderr = provider#get_stderr(a:jobid)
echohl WarningMsg
echomsg 'clipboard: error invoking '.get(self.argv, 0, '?').': '.join(stderr)
echohl None
endif
call provider#clear_stderr(a:jobid)
endfunction endfunction
let s:selections = { '*': s:selection, '+': copy(s:selection)} let s:selections = { '*': s:selection, '+': copy(s:selection) }
function! s:try_cmd(cmd, ...) function! s:try_cmd(cmd, ...) abort
let argv = split(a:cmd, " ") let argv = split(a:cmd, " ")
let out = a:0 ? systemlist(argv, a:1, 1) : systemlist(argv, [''], 1) let out = a:0 ? systemlist(argv, a:1, 1) : systemlist(argv, [''], 1)
if v:shell_error if v:shell_error
if !exists('s:did_error_try_cmd') if !exists('s:did_error_try_cmd')
echohl WarningMsg echohl WarningMsg
echomsg "clipboard: error: ".(len(out) ? out[0] : '') echomsg "clipboard: error: ".(len(out) ? out[0] : v:shell_error)
echohl None echohl None
let s:did_error_try_cmd = 1 let s:did_error_try_cmd = 1
endif endif
@ -34,7 +42,7 @@ function! s:try_cmd(cmd, ...)
endfunction endfunction
" Returns TRUE if `cmd` exits with success, else FALSE. " Returns TRUE if `cmd` exits with success, else FALSE.
function! s:cmd_ok(cmd) function! s:cmd_ok(cmd) abort
call system(a:cmd) call system(a:cmd)
return v:shell_error == 0 return v:shell_error == 0
endfunction endfunction
@ -47,7 +55,18 @@ function! provider#clipboard#Error() abort
endfunction endfunction
function! provider#clipboard#Executable() abort function! provider#clipboard#Executable() abort
if has('mac') && executable('pbcopy') if exists('g:clipboard')
if type({}) isnot# type(g:clipboard)
\ || type({}) isnot# type(get(g:clipboard, 'copy', v:null))
\ || type({}) isnot# type(get(g:clipboard, 'paste', v:null))
let s:err = 'clipboard: invalid g:clipboard'
return ''
endif
let s:copy = get(g:clipboard, 'copy', { '+': v:null, '*': v:null })
let s:paste = get(g:clipboard, 'paste', { '+': v:null, '*': v:null })
let s:cache_enabled = get(g:clipboard, 'cache_enabled', 0)
return get(g:clipboard, 'name', 'g:clipboard')
elseif has('mac') && executable('pbcopy')
let s:copy['+'] = 'pbcopy' let s:copy['+'] = 'pbcopy'
let s:paste['+'] = 'pbpaste' let s:paste['+'] = 'pbpaste'
let s:copy['*'] = s:copy['+'] let s:copy['*'] = s:copy['+']
@ -84,26 +103,33 @@ function! provider#clipboard#Executable() abort
let s:copy['*'] = s:copy['+'] let s:copy['*'] = s:copy['+']
let s:paste['*'] = s:paste['+'] let s:paste['*'] = s:paste['+']
return 'win32yank' return 'win32yank'
elseif exists('$TMUX') && executable('tmux')
let s:copy['+'] = 'tmux load-buffer -'
let s:paste['+'] = 'tmux save-buffer -'
let s:copy['*'] = s:copy['+']
let s:paste['*'] = s:paste['+']
return 'tmux'
endif endif
let s:err = 'clipboard: No clipboard tool available. See :help clipboard' let s:err = 'clipboard: No clipboard tool. :help clipboard'
return '' return ''
endfunction endfunction
if empty(provider#clipboard#Executable()) if empty(provider#clipboard#Executable())
" provider#clipboard#Call() *must not* be defined if the provider is broken.
" Otherwise eval_has_provider() thinks the clipboard provider is
" functioning, and eval_call_provider() will happily call it.
finish finish
endif endif
let s:clipboard = {} function! s:clipboard.get(reg) abort
function! s:clipboard.get(reg)
if s:selections[a:reg].owner > 0 if s:selections[a:reg].owner > 0
return s:selections[a:reg].data return s:selections[a:reg].data
end end
return s:try_cmd(s:paste[a:reg]) return s:try_cmd(s:paste[a:reg])
endfunction endfunction
function! s:clipboard.set(lines, regtype, reg) function! s:clipboard.set(lines, regtype, reg) abort
if a:reg == '"' if a:reg == '"'
call s:clipboard.set(a:lines,a:regtype,'+') call s:clipboard.set(a:lines,a:regtype,'+')
if s:copy['*'] != s:copy['+'] if s:copy['*'] != s:copy['+']
@ -124,20 +150,31 @@ function! s:clipboard.set(lines, regtype, reg)
end end
let selection.data = [a:lines, a:regtype] let selection.data = [a:lines, a:regtype]
let argv = split(s:copy[a:reg], " ") let argv = split(s:copy[a:reg], " ")
let selection.argv = argv
let selection.detach = s:cache_enabled let selection.detach = s:cache_enabled
let selection.cwd = "/" let selection.cwd = "/"
let jobid = jobstart(argv, selection) let jobid = jobstart(argv, selection)
if jobid <= 0 if jobid > 0
call jobsend(jobid, a:lines)
call jobclose(jobid, 'stdin')
let selection.owner = jobid
else
echohl WarningMsg echohl WarningMsg
echo "clipboard: error when invoking provider" echomsg 'clipboard: failed to execute: '.(s:copy[a:reg])
echohl None echohl None
return 0 return 0
endif endif
call jobsend(jobid, a:lines) return 1
call jobclose(jobid, 'stdin')
let selection.owner = jobid
endfunction endfunction
function! provider#clipboard#Call(method, args) function! provider#clipboard#Call(method, args) abort
return call(s:clipboard[a:method],a:args,s:clipboard) if get(s:, 'here', v:false) " Clipboard provider must not recurse. #7184
return 0
endif
let s:here = v:true
try
return call(s:clipboard[a:method],a:args,s:clipboard)
finally
let s:here = v:false
endtry
endfunction endfunction

View File

@ -0,0 +1,80 @@
if exists('g:loaded_node_provider')
finish
endif
let g:loaded_node_provider = 1
let s:job_opts = {'rpc': v:true, 'on_stderr': function('provider#stderr_collector')}
function! provider#node#Detect() abort
return has('win32') ? exepath('neovim-node-host.cmd') : exepath('neovim-node-host')
endfunction
function! provider#node#Prog()
return s:prog
endfunction
function! provider#node#Require(host) abort
if s:err != ''
echoerr s:err
return
endif
if has('win32')
let args = provider#node#Prog()
else
let args = ['node']
if !empty($NVIM_NODE_HOST_DEBUG)
call add(args, '--inspect-brk')
endif
call add(args , provider#node#Prog())
endif
try
let channel_id = jobstart(args, s:job_opts)
if rpcrequest(channel_id, 'poll') ==# 'ok'
return channel_id
endif
catch
echomsg v:throwpoint
echomsg v:exception
for row in provider#get_stderr(channel_id)
echomsg row
endfor
endtry
finally
call provider#clear_stderr(channel_id)
endtry
throw remote#host#LoadErrorForHost(a:host.orig_name, '$NVIM_NODE_LOG_FILE')
endfunction
function! provider#node#Call(method, args)
if s:err != ''
echoerr s:err
return
endif
if !exists('s:host')
try
let s:host = remote#host#Require('node')
catch
let s:err = v:exception
echohl WarningMsg
echomsg v:exception
echohl None
return
endtry
endif
return call('rpcrequest', insert(insert(a:args, 'node_'.a:method), s:host))
endfunction
let s:err = ''
let s:prog = provider#node#Detect()
if empty(s:prog)
let s:err = 'Cannot find the "neovim" node package. Try :CheckHealth'
endif
call remote#host#RegisterPlugin('node-provider', 'node', [])

View File

@ -1,5 +1,5 @@
" The Python provider uses a Python host to emulate an environment for running " The Python provider uses a Python host to emulate an environment for running
" python-vim plugins. See ":help provider". " python-vim plugins. :help provider
" "
" Associating the plugin with the Python host is the first step because plugins " Associating the plugin with the Python host is the first step because plugins
" will be passed as command-line arguments " will be passed as command-line arguments

View File

@ -1,5 +1,5 @@
" The Python3 provider uses a Python3 host to emulate an environment for running " The Python3 provider uses a Python3 host to emulate an environment for running
" python3 plugins. See ":help provider". " python3 plugins. :help provider
" "
" Associating the plugin with the Python3 host is the first step because " Associating the plugin with the Python3 host is the first step because
" plugins will be passed as command-line arguments " plugins will be passed as command-line arguments

View File

@ -5,17 +5,7 @@ endif
let s:loaded_pythonx_provider = 1 let s:loaded_pythonx_provider = 1
let s:stderr = {} let s:job_opts = {'rpc': v:true, 'on_stderr': function('provider#stderr_collector')}
let s:job_opts = {'rpc': v:true}
" TODO(bfredl): this logic is common and should be builtin
function! s:job_opts.on_stderr(chan_id, data, event)
let stderr = get(s:stderr, a:chan_id, [''])
let last = remove(stderr, -1)
let a:data[0] = last.a:data[0]
call extend(stderr, a:data)
let s:stderr[a:chan_id] = stderr
endfunction
function! provider#pythonx#Require(host) abort function! provider#pythonx#Require(host) abort
let ver = (a:host.orig_name ==# 'python') ? 2 : 3 let ver = (a:host.orig_name ==# 'python') ? 2 : 3
@ -38,9 +28,11 @@ function! provider#pythonx#Require(host) abort
catch catch
echomsg v:throwpoint echomsg v:throwpoint
echomsg v:exception echomsg v:exception
for row in get(s:stderr, channel_id, []) for row in provider#get_stderr(channel_id)
echomsg row echomsg row
endfor endfor
finally
call provider#clear_stderr(channel_id)
endtry endtry
throw remote#host#LoadErrorForHost(a:host.orig_name, throw remote#host#LoadErrorForHost(a:host.orig_name,
\ '$NVIM_PYTHON_LOG_FILE') \ '$NVIM_PYTHON_LOG_FILE')
@ -112,15 +104,14 @@ function! s:check_interpreter(prog, major_ver) abort
endif endif
if v:shell_error == 2 if v:shell_error == 2
return [0, prog_path . ' does not have the neovim module installed. ' return [0, prog_path.' does not have the "neovim" module. :help provider-python']
\ . 'See ":help provider-python".']
elseif v:shell_error == 127 elseif v:shell_error == 127
" This can happen with pyenv's shims. " This can happen with pyenv's shims.
return [0, prog_path . ' does not exist: ' . prog_ver] return [0, prog_path . ' does not exist: ' . prog_ver]
elseif v:shell_error elseif v:shell_error
return [0, 'Checking ' . prog_path . ' caused an unknown error. ' return [0, 'Checking ' . prog_path . ' caused an unknown error. '
\ . '(' . v:shell_error . ', output: ' . prog_ver . ')' \ . '(' . v:shell_error . ', output: ' . prog_ver . ')'
\ . ' Please report this at github.com/neovim/neovim.'] \ . ' Report this at https://github.com/neovim/neovim']
endif endif
return [1, ''] return [1, '']

View File

@ -16,7 +16,11 @@ function! s:job_opts.on_stderr(chan_id, data, event)
endfunction endfunction
function! provider#ruby#Detect() abort function! provider#ruby#Detect() abort
return exepath('neovim-ruby-host') if exists("g:ruby_host_prog")
return g:ruby_host_prog
else
return has('win32') ? exepath('neovim-ruby-host.bat') : exepath('neovim-ruby-host')
end
endfunction endfunction
function! provider#ruby#Prog() function! provider#ruby#Prog()
@ -24,15 +28,15 @@ function! provider#ruby#Prog()
endfunction endfunction
function! provider#ruby#Require(host) abort function! provider#ruby#Require(host) abort
let args = [provider#ruby#Prog()] let prog = provider#ruby#Prog()
let ruby_plugins = remote#host#PluginsForHost(a:host.name) let ruby_plugins = remote#host#PluginsForHost(a:host.name)
for plugin in ruby_plugins for plugin in ruby_plugins
call add(args, plugin.path) let prog .= " " . shellescape(plugin.path)
endfor endfor
try try
let channel_id = jobstart(args, s:job_opts) let channel_id = jobstart(prog, s:job_opts)
if rpcrequest(channel_id, 'poll') ==# 'ok' if rpcrequest(channel_id, 'poll') ==# 'ok'
return channel_id return channel_id
endif endif
@ -71,7 +75,7 @@ let s:prog = provider#ruby#Detect()
let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb' let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb'
if empty(s:prog) if empty(s:prog)
let s:err = 'Cannot find the neovim RubyGem. Try :CheckHealth' let s:err = 'Cannot find the neovim RubyGem. Try :checkhealth'
endif endif
call remote#host#RegisterClone('legacy-ruby-provider', 'ruby') call remote#host#RegisterClone('legacy-ruby-provider', 'ruby')

View File

@ -1,8 +1,6 @@
begin begin
require "neovim/ruby_provider" require 'neovim/ruby_provider'
rescue LoadError rescue LoadError
warn( warn('Your neovim RubyGem is missing or out of date.',
"Your neovim RubyGem is missing or out of date. " + 'Install the latest version using `gem install neovim`.')
"Install the latest version using `gem install neovim`."
)
end end

View File

@ -89,7 +89,8 @@ endfunction
function! remote#define#AutocmdOnHost(host, method, sync, name, opts) function! remote#define#AutocmdOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup() let group = s:GetNextAutocmdGroup()
let forward = '"doau '.group.' '.a:name.' ".'.'expand("<amatch>")' let forward = '"doau '.group.' '.a:name.' ".'
\ . 'fnameescape(expand("<amatch>"))'
let a:opts.group = group let a:opts.group = group
let bootstrap_def = s:GetAutocmdPrefix(a:name, a:opts) let bootstrap_def = s:GetAutocmdPrefix(a:name, a:opts)
\ .' call remote#define#AutocmdBootstrap("'.a:host.'"' \ .' call remote#define#AutocmdBootstrap("'.a:host.'"'
@ -168,14 +169,40 @@ function! remote#define#FunctionOnChannel(channel, method, sync, name, opts)
exe function_def exe function_def
endfunction endfunction
let s:busy = {}
let s:pending_notifications = {}
function! s:GetRpcFunction(sync) function! s:GetRpcFunction(sync)
if a:sync if a:sync ==# 'urgent'
return 'rpcrequest' return 'rpcnotify'
elseif a:sync
return 'remote#define#request'
endif endif
return 'rpcnotify' return 'remote#define#notify'
endfunction endfunction
function! remote#define#notify(chan, ...)
if get(s:busy, a:chan, 0) > 0
let pending = get(s:pending_notifications, a:chan, [])
call add(pending, deepcopy(a:000))
let s:pending_notifications[a:chan] = pending
else
call call('rpcnotify', [a:chan] + a:000)
endif
endfunction
function! remote#define#request(chan, ...)
let s:busy[a:chan] = get(s:busy, a:chan, 0)+1
let val = call('rpcrequest', [a:chan]+a:000)
let s:busy[a:chan] -= 1
if s:busy[a:chan] == 0
for msg in get(s:pending_notifications, a:chan, [])
call call('rpcnotify', [a:chan] + msg)
endfor
let s:pending_notifications[a:chan] = []
endif
return val
endfunction
function! s:GetCommandPrefix(name, opts) function! s:GetCommandPrefix(name, opts)
return 'command!'.s:StringifyOpts(a:opts, ['nargs', 'complete', 'range', return 'command!'.s:StringifyOpts(a:opts, ['nargs', 'complete', 'range',

View File

@ -199,3 +199,7 @@ call remote#host#Register('python3', '*',
" Ruby " Ruby
call remote#host#Register('ruby', '*.rb', call remote#host#Register('ruby', '*.rb',
\ function('provider#ruby#Require')) \ function('provider#ruby#Require'))
" nodejs
call remote#host#Register('node', '*',
\ function('provider#node#Require'))

View File

@ -93,7 +93,7 @@ function! s:GetBufferRubyEntity( name, type, ... )
let stopline = 1 let stopline = 1
let crex = '^\s*\<' . a:type . '\>\s*\<' . a:name . '\>\s*\(<\s*.*\s*\)\?' let crex = '^\s*\<' . a:type . '\>\s*\<' . escape(a:name, '*') . '\>\s*\(<\s*.*\s*\)\?'
let [lnum,lcol] = searchpos( crex, 'w' ) let [lnum,lcol] = searchpos( crex, 'w' )
"let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' ) "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' )
@ -149,7 +149,7 @@ function! s:GetRubyVarType(v)
let ctors = ctors.'\)' let ctors = ctors.'\)'
let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)' let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)'
let sstr = ''.a:v.'\>\s*[+\-*/]*'.fstr let sstr = ''.escape(a:v, '*').'\>\s*[+\-*/]*'.fstr
let [lnum,lcol] = searchpos(sstr,'nb',stopline) let [lnum,lcol] = searchpos(sstr,'nb',stopline)
if lnum != 0 && lcol != 0 if lnum != 0 && lcol != 0
let str = matchstr(getline(lnum),fstr,lcol) let str = matchstr(getline(lnum),fstr,lcol)
@ -196,7 +196,7 @@ function! rubycomplete#Complete(findstart, base)
if c =~ '\w' if c =~ '\w'
continue continue
elseif ! c =~ '\.' elseif ! c =~ '\.'
idx = -1 let idx = -1
break break
else else
break break
@ -266,6 +266,28 @@ class VimRubyCompletion
end end
end end
def load_gems
fpath = VIM::evaluate("get(g:, 'rubycomplete_gemfile_path', 'Gemfile')")
return unless File.file?(fpath) && File.readable?(fpath)
want_bundler = VIM::evaluate("get(g:, 'rubycomplete_use_bundler')")
parse_file = !want_bundler
begin
require 'bundler'
Bundler.setup
Bundler.require
rescue Exception
parse_file = true
end
if parse_file
File.new(fpath).each_line do |line|
begin
require $1 if /\s*gem\s*['"]([^'"]+)/.match(line)
rescue Exception
end
end
end
end
def load_buffer_class(name) def load_buffer_class(name)
dprint "load_buffer_class(%s) START" % name dprint "load_buffer_class(%s) START" % name
classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")') classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")')
@ -588,6 +610,10 @@ class VimRubyCompletion
load_rails load_rails
end end
want_gems = VIM::evaluate("get(g:, 'rubycomplete_load_gemfile')")
load_gems unless want_gems.to_i.zero?
input = VIM::Buffer.current.line input = VIM::Buffer.current.line
cpos = VIM::Window.current.cursor[1] - 1 cpos = VIM::Window.current.cursor[1] - 1
input = input[0..cpos] input = input[0..cpos]
@ -678,7 +704,9 @@ class VimRubyCompletion
cv = eval("self.class.constants") cv = eval("self.class.constants")
vartype = get_var_type( receiver ) vartype = get_var_type( receiver )
dprint "vartype: %s" % vartype dprint "vartype: %s" % vartype
if vartype != ''
invalid_vartype = ['', "gets"]
if !invalid_vartype.include?(vartype)
load_buffer_class( vartype ) load_buffer_class( vartype )
begin begin
@ -706,7 +734,7 @@ class VimRubyCompletion
methods.concat m.instance_methods(false) methods.concat m.instance_methods(false)
} }
end end
variables += add_rails_columns( "#{vartype}" ) if vartype && vartype.length > 0 variables += add_rails_columns( "#{vartype}" ) if vartype && !invalid_vartype.include?(vartype)
when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/ when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/
message = $1 message = $1

415
runtime/autoload/rust.vim Normal file
View File

@ -0,0 +1,415 @@
" Author: Kevin Ballard
" Description: Helper functions for Rust commands/mappings
" Last Modified: May 27, 2014
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
" Jump {{{1
function! rust#Jump(mode, function) range
let cnt = v:count1
normal! m'
if a:mode ==# 'v'
norm! gv
endif
let foldenable = &foldenable
set nofoldenable
while cnt > 0
execute "call <SID>Jump_" . a:function . "()"
let cnt = cnt - 1
endwhile
let &foldenable = foldenable
endfunction
function! s:Jump_Back()
call search('{', 'b')
keepjumps normal! w99[{
endfunction
function! s:Jump_Forward()
normal! j0
call search('{', 'b')
keepjumps normal! w99[{%
call search('{')
endfunction
" Run {{{1
function! rust#Run(bang, args)
let args = s:ShellTokenize(a:args)
if a:bang
let idx = index(l:args, '--')
if idx != -1
let rustc_args = idx == 0 ? [] : l:args[:idx-1]
let args = l:args[idx+1:]
else
let rustc_args = l:args
let args = []
endif
else
let rustc_args = []
endif
let b:rust_last_rustc_args = l:rustc_args
let b:rust_last_args = l:args
call s:WithPath(function("s:Run"), rustc_args, args)
endfunction
function! s:Run(dict, rustc_args, args)
let exepath = a:dict.tmpdir.'/'.fnamemodify(a:dict.path, ':t:r')
if has('win32')
let exepath .= '.exe'
endif
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
let rustc_args = [relpath, '-o', exepath] + a:rustc_args
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
let output = s:system(pwd, shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
if output != ''
echohl WarningMsg
echo output
echohl None
endif
if !v:shell_error
exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
endif
endfunction
" Expand {{{1
function! rust#Expand(bang, args)
let args = s:ShellTokenize(a:args)
if a:bang && !empty(l:args)
let pretty = remove(l:args, 0)
else
let pretty = "expanded"
endif
call s:WithPath(function("s:Expand"), pretty, args)
endfunction
function! s:Expand(dict, pretty, args)
try
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
if a:pretty =~? '^\%(everybody_loops$\|flowgraph=\)'
let flag = '--xpretty'
else
let flag = '--pretty'
endif
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
let args = [relpath, '-Z', 'unstable-options', l:flag, a:pretty] + a:args
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
if v:shell_error
echohl WarningMsg
echo output
echohl None
else
new
silent put =output
1
d
setl filetype=rust
setl buftype=nofile
setl bufhidden=hide
setl noswapfile
" give the buffer a nice name
let suffix = 1
let basename = fnamemodify(a:dict.path, ':t:r')
while 1
let bufname = basename
if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
let bufname .= '.pretty.rs'
if bufexists(bufname)
let suffix += 1
continue
endif
exe 'silent noautocmd keepalt file' fnameescape(bufname)
break
endwhile
endif
endtry
endfunction
function! rust#CompleteExpand(lead, line, pos)
if a:line[: a:pos-1] =~ '^RustExpand!\s*\S*$'
" first argument and it has a !
let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph=", "everybody_loops"]
if !empty(a:lead)
call filter(list, "v:val[:len(a:lead)-1] == a:lead")
endif
return list
endif
return glob(escape(a:lead, "*?[") . '*', 0, 1)
endfunction
" Emit {{{1
function! rust#Emit(type, args)
let args = s:ShellTokenize(a:args)
call s:WithPath(function("s:Emit"), a:type, args)
endfunction
function! s:Emit(dict, type, args)
try
let output_path = a:dict.tmpdir.'/output'
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
let args = [relpath, '--emit', a:type, '-o', output_path] + a:args
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
if output != ''
echohl WarningMsg
echo output
echohl None
endif
if !v:shell_error
new
exe 'silent keepalt read' fnameescape(output_path)
1
d
if a:type == "llvm-ir"
setl filetype=llvm
let extension = 'll'
elseif a:type == "asm"
setl filetype=asm
let extension = 's'
endif
setl buftype=nofile
setl bufhidden=hide
setl noswapfile
if exists('l:extension')
" give the buffer a nice name
let suffix = 1
let basename = fnamemodify(a:dict.path, ':t:r')
while 1
let bufname = basename
if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
let bufname .= '.'.extension
if bufexists(bufname)
let suffix += 1
continue
endif
exe 'silent noautocmd keepalt file' fnameescape(bufname)
break
endwhile
endif
endif
endtry
endfunction
" Utility functions {{{1
" Invokes func(dict, ...)
" Where {dict} is a dictionary with the following keys:
" 'path' - The path to the file
" 'tmpdir' - The path to a temporary directory that will be deleted when the
" function returns.
" 'istemp' - 1 if the path is a file inside of {dict.tmpdir} or 0 otherwise.
" If {istemp} is 1 then an additional key is provided:
" 'tmpdir_relpath' - The {path} relative to the {tmpdir}.
"
" {dict.path} may be a path to a file inside of {dict.tmpdir} or it may be the
" existing path of the current buffer. If the path is inside of {dict.tmpdir}
" then it is guaranteed to have a '.rs' extension.
function! s:WithPath(func, ...)
let buf = bufnr('')
let saved = {}
let dict = {}
try
let saved.write = &write
set write
let dict.path = expand('%')
let pathisempty = empty(dict.path)
" Always create a tmpdir in case the wrapped command wants it
let dict.tmpdir = tempname()
call mkdir(dict.tmpdir)
if pathisempty || !saved.write
let dict.istemp = 1
" if we're doing this because of nowrite, preserve the filename
if !pathisempty
let filename = expand('%:t:r').".rs"
else
let filename = 'unnamed.rs'
endif
let dict.tmpdir_relpath = filename
let dict.path = dict.tmpdir.'/'.filename
let saved.mod = &mod
set nomod
silent exe 'keepalt write! ' . fnameescape(dict.path)
if pathisempty
silent keepalt 0file
endif
else
let dict.istemp = 0
update
endif
call call(a:func, [dict] + a:000)
finally
if bufexists(buf)
for [opt, value] in items(saved)
silent call setbufvar(buf, '&'.opt, value)
unlet value " avoid variable type mismatches
endfor
endif
if has_key(dict, 'tmpdir') | silent call s:RmDir(dict.tmpdir) | endif
endtry
endfunction
function! rust#AppendCmdLine(text)
call setcmdpos(getcmdpos())
let cmd = getcmdline() . a:text
return cmd
endfunction
" Tokenize the string according to sh parsing rules
function! s:ShellTokenize(text)
" states:
" 0: start of word
" 1: unquoted
" 2: unquoted backslash
" 3: double-quote
" 4: double-quoted backslash
" 5: single-quote
let l:state = 0
let l:current = ''
let l:args = []
for c in split(a:text, '\zs')
if l:state == 0 || l:state == 1 " unquoted
if l:c ==# ' '
if l:state == 0 | continue | endif
call add(l:args, l:current)
let l:current = ''
let l:state = 0
elseif l:c ==# '\'
let l:state = 2
elseif l:c ==# '"'
let l:state = 3
elseif l:c ==# "'"
let l:state = 5
else
let l:current .= l:c
let l:state = 1
endif
elseif l:state == 2 " unquoted backslash
if l:c !=# "\n" " can it even be \n?
let l:current .= l:c
endif
let l:state = 1
elseif l:state == 3 " double-quote
if l:c ==# '\'
let l:state = 4
elseif l:c ==# '"'
let l:state = 1
else
let l:current .= l:c
endif
elseif l:state == 4 " double-quoted backslash
if stridx('$`"\', l:c) >= 0
let l:current .= l:c
elseif l:c ==# "\n" " is this even possible?
" skip it
else
let l:current .= '\'.l:c
endif
let l:state = 3
elseif l:state == 5 " single-quoted
if l:c == "'"
let l:state = 1
else
let l:current .= l:c
endif
endif
endfor
if l:state != 0
call add(l:args, l:current)
endif
return l:args
endfunction
function! s:RmDir(path)
" sanity check; make sure it's not empty, /, or $HOME
if empty(a:path)
echoerr 'Attempted to delete empty path'
return 0
elseif a:path == '/' || a:path == $HOME
echoerr 'Attempted to delete protected path: ' . a:path
return 0
endif
return system("rm -rf " . shellescape(a:path))
endfunction
" Executes {cmd} with the cwd set to {pwd}, without changing Vim's cwd.
" If {pwd} is the empty string then it doesn't change the cwd.
function! s:system(pwd, cmd)
let cmd = a:cmd
if !empty(a:pwd)
let cmd = 'cd ' . shellescape(a:pwd) . ' && ' . cmd
endif
return system(cmd)
endfunction
" Playpen Support {{{1
" Parts of gist.vim by Yasuhiro Matsumoto <mattn.jp@gmail.com> reused
" gist.vim available under the BSD license, available at
" http://github.com/mattn/gist-vim
function! s:has_webapi()
if !exists("*webapi#http#post")
try
call webapi#http#post()
catch
endtry
endif
return exists("*webapi#http#post")
endfunction
function! rust#Play(count, line1, line2, ...) abort
redraw
let l:rust_playpen_url = get(g:, 'rust_playpen_url', 'https://play.rust-lang.org/')
let l:rust_shortener_url = get(g:, 'rust_shortener_url', 'https://is.gd/')
if !s:has_webapi()
echohl ErrorMsg | echomsg ':RustPlay depends on webapi.vim (https://github.com/mattn/webapi-vim)' | echohl None
return
endif
let bufname = bufname('%')
if a:count < 1
let content = join(getline(a:line1, a:line2), "\n")
else
let save_regcont = @"
let save_regtype = getregtype('"')
silent! normal! gvy
let content = @"
call setreg('"', save_regcont, save_regtype)
endif
let body = l:rust_playpen_url."?code=".webapi#http#encodeURI(content)
if strlen(body) > 5000
echohl ErrorMsg | echomsg 'Buffer too large, max 5000 encoded characters ('.strlen(body).')' | echohl None
return
endif
let payload = "format=simple&url=".webapi#http#encodeURI(body)
let res = webapi#http#post(l:rust_shortener_url.'create.php', payload, {})
let url = res.content
redraw | echomsg 'Done: '.url
endfunction
" }}}1
" vim: set noet sw=8 ts=8:

View File

@ -0,0 +1,107 @@
" Author: Stephen Sugden <stephen@stephensugden.com>
"
" Adapted from https://github.com/fatih/vim-go
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if !exists("g:rustfmt_autosave")
let g:rustfmt_autosave = 0
endif
if !exists("g:rustfmt_command")
let g:rustfmt_command = "rustfmt"
endif
if !exists("g:rustfmt_options")
let g:rustfmt_options = ""
endif
if !exists("g:rustfmt_fail_silently")
let g:rustfmt_fail_silently = 0
endif
let s:got_fmt_error = 0
function! s:RustfmtCommandRange(filename, line1, line2)
let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
return printf("%s %s --write-mode=overwrite --file-lines '[%s]'", g:rustfmt_command, g:rustfmt_options, json_encode(l:arg))
endfunction
function! s:RustfmtCommand(filename)
return g:rustfmt_command . " --write-mode=overwrite " . g:rustfmt_options . " " . shellescape(a:filename)
endfunction
function! s:RunRustfmt(command, curw, tmpname)
if exists("*systemlist")
let out = systemlist(a:command)
else
let out = split(system(a:command), '\r\?\n')
endif
if v:shell_error == 0 || v:shell_error == 3
" remove undo point caused via BufWritePre
try | silent undojoin | catch | endtry
" Replace current file with temp file, then reload buffer
call rename(a:tmpname, expand('%'))
silent edit!
let &syntax = &syntax
" only clear location list if it was previously filled to prevent
" clobbering other additions
if s:got_fmt_error
let s:got_fmt_error = 0
call setloclist(0, [])
lwindow
endif
elseif g:rustfmt_fail_silently == 0
" otherwise get the errors and put them in the location list
let errors = []
for line in out
" src/lib.rs:13:5: 13:10 error: expected `,`, or `}`, found `value`
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\):\s*\(\d\+:\d\+\s*\)\?\s*error: \(.*\)')
if !empty(tokens)
call add(errors, {"filename": @%,
\"lnum": tokens[2],
\"col": tokens[3],
\"text": tokens[5]})
endif
endfor
if empty(errors)
% | " Couldn't detect rustfmt error format, output errors
endif
if !empty(errors)
call setloclist(0, errors, 'r')
echohl Error | echomsg "rustfmt returned error" | echohl None
endif
let s:got_fmt_error = 1
lwindow
" We didn't use the temp file, so clean up
call delete(a:tmpname)
endif
call winrestview(a:curw)
endfunction
function! rustfmt#FormatRange(line1, line2)
let l:curw = winsaveview()
let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt"
call writefile(getline(1, '$'), l:tmpname)
let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2)
call s:RunRustfmt(command, l:curw, l:tmpname)
endfunction
function! rustfmt#Format()
let l:curw = winsaveview()
let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt"
call writefile(getline(1, '$'), l:tmpname)
let command = s:RustfmtCommand(l:tmpname)
call s:RunRustfmt(command, l:curw, l:tmpname)
endfunction

View File

@ -45,7 +45,7 @@ call map(copy(s:SHADA_ENTRY_NAMES),
let s:SHADA_MAP_ENTRIES = { let s:SHADA_MAP_ENTRIES = {
\'search_pattern': ['sp', 'sh', 'ss', 'sb', 'sm', 'sc', 'sl', 'se', 'so', \'search_pattern': ['sp', 'sh', 'ss', 'sb', 'sm', 'sc', 'sl', 'se', 'so',
\ 'su'], \ 'su'],
\'register': ['n', 'rc', 'rw', 'rt'], \'register': ['n', 'rc', 'rw', 'rt', 'ru'],
\'global_mark': ['n', 'f', 'l', 'c'], \'global_mark': ['n', 'f', 'l', 'c'],
\'local_mark': ['f', 'n', 'l', 'c'], \'local_mark': ['f', 'n', 'l', 'c'],
\'jump': ['f', 'l', 'c'], \'jump': ['f', 'l', 'c'],
@ -139,6 +139,7 @@ let s:SHADA_STANDARD_KEYS = {
\'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE], \'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE],
\'rw': ['block width', 'uint', 0], \'rw': ['block width', 'uint', 0],
\'rc': ['contents', 'binarray', s:SHADA_REQUIRED], \'rc': ['contents', 'binarray', s:SHADA_REQUIRED],
\'ru': ['is_unnamed', 'boolean', g:msgpack#false],
\'n': ['name', 'intchar', char2nr('"')], \'n': ['name', 'intchar', char2nr('"')],
\'l': ['line number', 'uint', 1], \'l': ['line number', 'uint', 1],
\'c': ['column', 'uint', 0], \'c': ['column', 'uint', 0],

View File

@ -88,8 +88,8 @@ function! spellfile#LoadFile(lang)
endif endif
endif endif
if newbufnr == winbufnr(0) if newbufnr == winbufnr(0)
" We are back the old buffer, remove any (half-finished) download. " We are back to the old buffer, remove any (half-finished) download.
g/^/d_ keeppatterns g/^/d_
else else
let newbufnr = winbufnr(0) let newbufnr = winbufnr(0)
endif endif
@ -127,7 +127,7 @@ function! spellfile#LoadFile(lang)
exe "write " . dirname . '/' . fname exe "write " . dirname . '/' . fname
" Also download the .sug file. " Also download the .sug file.
g/^/d_ keeppatterns g/^/d_
let fname = substitute(fname, '\.spl$', '.sug', '') let fname = substitute(fname, '\.spl$', '.sug', '')
echo 'Downloading ' . fname . '...' echo 'Downloading ' . fname . '...'
call spellfile#Nread(fname) call spellfile#Nread(fname)
@ -197,7 +197,7 @@ function! spellfile#WritableSpellDir()
" Always use the $XDG_DATA_HOME/nvim/site directory " Always use the $XDG_DATA_HOME/nvim/site directory
if exists('$XDG_DATA_HOME') if exists('$XDG_DATA_HOME')
return $XDG_DATA_HOME . "/nvim/site/spell" return $XDG_DATA_HOME . "/nvim/site/spell"
else elseif !(has('win32') || has('win64'))
return $HOME . "/.local/share/nvim/site/spell" return $HOME . "/.local/share/nvim/site/spell"
endif endif
for dir in split(&rtp, ',') for dir in split(&rtp, ',')

View File

@ -2,7 +2,7 @@
" Language: SQL " Language: SQL
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> " Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
" Version: 16.0 " Version: 16.0
" Last Change: 2015 Dec 29 " Last Change: 2017 Oct 15
" Homepage: http://www.vim.org/scripts/script.php?script_id=1572 " Homepage: http://www.vim.org/scripts/script.php?script_id=1572
" Usage: For detailed help " Usage: For detailed help
" ":help sql.txt" " ":help sql.txt"

View File

@ -117,7 +117,7 @@ fun! tar#Browse(tarfile)
if !filereadable(a:tarfile) if !filereadable(a:tarfile)
" call Decho('a:tarfile<'.a:tarfile.'> not filereadable') " call Decho('a:tarfile<'.a:tarfile.'> not filereadable')
if a:tarfile !~# '^\a\+://' if a:tarfile !~# '^\a\+://'
" if its an url, don't complain, let url-handlers such as vim do its thing " if it's an url, don't complain, let url-handlers such as vim do its thing
redraw! redraw!
echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
endif endif

View File

@ -15,30 +15,17 @@ function! tutor#SetupVim()
endif endif
endfunction endfunction
" Mappings: {{{1 " Loads metadata file, if available
function! tutor#LoadMetadata()
function! s:CheckMaps() let b:tutor_metadata = json_decode(join(readfile(expand('%').'.json'), "\n"))
nmap
endfunction endfunction
function! s:MapKeyWithRedirect(key, cmd) " Mappings: {{{1
if maparg(a:key) !=# ''
redir => l:keys
silent call s:CheckMaps()
redir END
let l:key_list = split(l:keys, '\n')
let l:raw_map = filter(copy(l:key_list), "v:val =~# '\\* ".a:key."'") function! tutor#SetNormalMappings()
if len(l:raw_map) == 0 nnoremap <silent> <buffer> <CR> :call tutor#FollowLink(0)<cr>
exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd nnoremap <silent> <buffer> <2-LeftMouse> :call tutor#MouseDoubleClick()<cr>
return nnoremap <buffer> >> :call tutor#InjectCommand()<cr>
endif
let l:map_data = split(l:raw_map[0], '\s*')
exe "nnoremap <buffer> <expr> ".l:map_data[0]." ".a:cmd
else
exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd
endif
endfunction endfunction
function! tutor#MouseDoubleClick() function! tutor#MouseDoubleClick()
@ -46,7 +33,7 @@ function! tutor#MouseDoubleClick()
normal! zo normal! zo
else else
if match(getline('.'), '^#\{1,} ') > -1 if match(getline('.'), '^#\{1,} ') > -1
normal! zc silent normal! zc
else else
call tutor#FollowLink(0) call tutor#FollowLink(0)
endif endif
@ -59,114 +46,6 @@ function! tutor#InjectCommand()
redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd
endfunction endfunction
function! tutor#SetNormalMappings()
call s:MapKeyWithRedirect('l', 'tutor#ForwardSkipConceal(v:count1)')
call s:MapKeyWithRedirect('h', 'tutor#BackwardSkipConceal(v:count1)')
call s:MapKeyWithRedirect('<right>', 'tutor#ForwardSkipConceal(v:count1)')
call s:MapKeyWithRedirect('<left>', 'tutor#BackwardSkipConceal(v:count1)')
nnoremap <silent> <buffer> <CR> :call tutor#FollowLink(0)<cr>
nnoremap <silent> <buffer> <2-LeftMouse> :call tutor#MouseDoubleClick()<cr>
nnoremap <buffer> >> :call tutor#InjectCommand()<cr>
endfunction
function! tutor#SetSampleTextMappings()
noremap <silent> <buffer> A :if match(getline('.'), '^--->') > -1 \| call search('\s{\@=', 'Wc') \| startinsert \| else \| startinsert! \| endif<cr>
noremap <silent> <buffer> $ :if match(getline('.'), '^--->') > -1 \| call search('.\s{\@=', 'Wc') \| else \| call search('$', 'Wc') \| endif<cr>
onoremap <silent> <buffer> $ :if match(getline('.'), '^--->') > -1 \| call search('.\s{\@=', 'Wc') \| else \| call search('$', 'Wc') \| endif<cr>
noremap <silent> <buffer> ^ :if match(getline('.'), '^--->') > -1 \| call search('\(--->\s\)\@<=.', 'bcW') \| else \| call search('^', 'bcW') \|endif<cr>
onoremap <silent> <buffer> ^ :if match(getline('.'), '^--->') > -1 \| call search('\(--->\s\)\@<=.', 'bcW') \| else \| call search('^', 'bcW') \|endif<cr>
nmap <silent> <buffer> 0 ^<esc>
nmap <silent> <buffer> <Home> ^<esc>
nmap <silent> <buffer> <End> $
imap <silent> <buffer> <Home> <esc>^<esc>:startinsert<cr>
imap <silent> <buffer> <End> <esc>$:startinsert<cr>
noremap <silent> <buffer> I :exe "normal! 0" \| startinsert<cr>
endfunction
" Navigation: {{{1
" taken from http://stackoverflow.com/a/24224578
function! tutor#ForwardSkipConceal(count)
let cnt=a:count
let mvcnt=0
let c=col('.')
let l=line('.')
let lc=col('$')
let line=getline('.')
while cnt
if c>=lc
let mvcnt+=cnt
break
endif
if stridx(&concealcursor, 'n')==-1
let isconcealed=0
else
let [isconcealed, cchar, group] = synconcealed(l, c)
endif
if isconcealed
let cnt-=strchars(cchar)
let oldc=c
let c+=1
while c < lc
let [isconcealed2, cchar2, group2] = synconcealed(l, c)
if !isconcealed2 || cchar2 != cchar
break
endif
let c+= 1
endwhile
let mvcnt+=strchars(line[oldc-1:c-2])
else
let cnt-=1
let mvcnt+=1
let c+=len(matchstr(line[c-1:], '.'))
endif
endwhile
return mvcnt.'l'
endfunction
function! tutor#BackwardSkipConceal(count)
let cnt=a:count
let mvcnt=0
let c=col('.')
let l=line('.')
let lc=0
let line=getline('.')
while cnt
if c<=1
let mvcnt+=cnt
break
endif
if stridx(&concealcursor, 'n')==-1 || c == 0
let isconcealed=0
else
let [isconcealed, cchar, group]=synconcealed(l, c-1)
endif
if isconcealed
let cnt-=strchars(cchar)
let oldc=c
let c-=1
while c>1
let [isconcealed2, cchar2, group2] = synconcealed(l, c-1)
if !isconcealed2 || cchar2 != cchar
break
endif
let c-=1
endwhile
let c = max([c, 1])
let mvcnt+=strchars(line[c-1:oldc-2])
else
let cnt-=1
let mvcnt+=1
let c-=len(matchstr(line[:c-2], '.$'))
endif
endwhile
return mvcnt.'h'
endfunction
" Hypertext: {{{1
function! tutor#FollowLink(force) function! tutor#FollowLink(force)
let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '') let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '')
if l:stack_s =~# 'tutorLink' if l:stack_s =~# 'tutorLink'
@ -209,42 +88,40 @@ function! tutor#InfoText()
return join(l:info_parts, " ") return join(l:info_parts, " ")
endfunction endfunction
" Marks {{{1
function! tutor#PlaceXMarks() " Marks: {{{1
call cursor(1, 1)
let b:tutor_sign_id = 1 function! tutor#ApplyMarks()
while search('^--->', 'W') > 0 hi! link tutorExpect Special
call tutor#CheckText(getline('.')) if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
let b:tutor_sign_id+=1 let b:tutor_sign_id = 1
endwhile for expct in keys(b:tutor_metadata['expect'])
call cursor(1, 1) let lnum = eval(expct)
call matchaddpos('tutorExpect', [lnum])
call tutor#CheckLine(lnum)
endfor
endif
endfunction endfunction
function! tutor#CheckText(text) function! tutor#ApplyMarksOnChanged()
if match(a:text, '{expect:ANYTHING}\s*$') == -1 if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
if match(getline('.'), '^--->\s*$') > -1 let lnum = line('.')
exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%') if index(keys(b:tutor_metadata['expect']), string(lnum)) > -1
else call tutor#CheckLine(lnum)
if match(getline('.'), '|expect:.\+|') == -1
let l:cur_text = matchstr(a:text, '---> \zs.\{-}\ze {expect:')
let l:expected_text = matchstr(a:text, '{expect:\zs.*\ze}\s*$')
else
let l:cur_text = matchstr(a:text, '---> \zs.\{-}\ze |expect:')
let l:expected_text = matchstr(a:text, '|expect:\zs.*\ze|\s*$')
endif
if l:cur_text ==# l:expected_text
exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorok buffer=".bufnr('%')
else
exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%')
endif
endif endif
endif endif
endfunction endfunction
function! tutor#OnTextChanged() function! tutor#CheckLine(line)
let l:text = getline('.') if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
if match(l:text, '^--->') > -1 let bufn = bufnr('%')
call tutor#CheckText(l:text) let ctext = getline(a:line)
if b:tutor_metadata['expect'][string(a:line)] == -1 || ctext ==# b:tutor_metadata['expect'][string(a:line)]
exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorok buffer=".bufn
else
exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorbad buffer=".bufn
endif
let b:tutor_sign_id+=1
endif endif
endfunction endfunction

View File

@ -1,7 +1,7 @@
" zip.vim: Handles browsing zipfiles " zip.vim: Handles browsing zipfiles
" AUTOLOAD PORTION " AUTOLOAD PORTION
" Date: Jul 02, 2013 " Date: Sep 13, 2016
" Version: 27 " Version: 28
" Maintainer: Charles E Campbell <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> " Maintainer: Charles E Campbell <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
" License: Vim License (see vim's :help license) " License: Vim License (see vim's :help license)
" Copyright: Copyright (C) 2005-2013 Charles E. Campbell {{{1 " Copyright: Copyright (C) 2005-2013 Charles E. Campbell {{{1
@ -20,10 +20,10 @@
if &cp || exists("g:loaded_zip") if &cp || exists("g:loaded_zip")
finish finish
endif endif
let g:loaded_zip= "v27" let g:loaded_zip= "v28"
if v:version < 702 if v:version < 702
echohl WarningMsg echohl WarningMsg
echo "***warning*** this version of zip needs vim 7.2" echo "***warning*** this version of zip needs vim 7.2 or later"
echohl Normal echohl Normal
finish finish
endif endif
@ -53,6 +53,9 @@ endif
if !exists("g:zip_unzipcmd") if !exists("g:zip_unzipcmd")
let g:zip_unzipcmd= "unzip" let g:zip_unzipcmd= "unzip"
endif endif
if !exists("g:zip_extractcmd")
let g:zip_extractcmd= g:zip_unzipcmd
endif
" ---------------- " ----------------
" Functions: {{{1 " Functions: {{{1
@ -62,14 +65,14 @@ endif
" zip#Browse: {{{2 " zip#Browse: {{{2
fun! zip#Browse(zipfile) fun! zip#Browse(zipfile)
" call Dfunc("zip#Browse(zipfile<".a:zipfile.">)") " call Dfunc("zip#Browse(zipfile<".a:zipfile.">)")
" sanity check: insure that the zipfile has "PK" as its first two letters " sanity check: ensure that the zipfile has "PK" as its first two letters
" (zipped files have a leading PK as a "magic cookie") " (zipped files have a leading PK as a "magic cookie")
if !filereadable(a:zipfile) || readfile(a:zipfile, "", 1)[0] !~ '^PK' if !filereadable(a:zipfile) || readfile(a:zipfile, "", 1)[0] !~ '^PK'
exe "noautocmd e ".fnameescape(a:zipfile) exe "noautocmd e ".fnameescape(a:zipfile)
" call Dret("zip#Browse : not a zipfile<".a:zipfile.">") " call Dret("zip#Browse : not a zipfile<".a:zipfile.">")
return return
" else " Decho " else " Decho
" call Decho("zip#Browse: a:zipfile<".a:zipfile."> passed PK test - its a zip file") " call Decho("zip#Browse: a:zipfile<".a:zipfile."> passed PK test - it's a zip file")
endif endif
let repkeep= &report let repkeep= &report
@ -92,7 +95,7 @@ fun! zip#Browse(zipfile)
endif endif
if !filereadable(a:zipfile) if !filereadable(a:zipfile)
if a:zipfile !~# '^\a\+://' if a:zipfile !~# '^\a\+://'
" if its an url, don't complain, let url-handlers such as vim do its thing " if it's an url, don't complain, let url-handlers such as vim do its thing
redraw! redraw!
echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
" call inputsave()|call input("Press <cr> to continue")|call inputrestore() " call inputsave()|call input("Press <cr> to continue")|call inputrestore()
@ -136,8 +139,10 @@ fun! zip#Browse(zipfile)
return return
endif endif
" Maps associated with zip plugin
setlocal noma nomod ro setlocal noma nomod ro
noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr> noremap <silent> <buffer> <cr> :call <SID>ZipBrowseSelect()<cr>
noremap <silent> <buffer> x :call zip#Extract()<cr>
let &report= repkeep let &report= repkeep
" call Dret("zip#Browse") " call Dret("zip#Browse")
@ -204,6 +209,15 @@ fun! zip#Read(fname,mode)
endif endif
" call Decho("zipfile<".zipfile.">") " call Decho("zipfile<".zipfile.">")
" call Decho("fname <".fname.">") " call Decho("fname <".fname.">")
" sanity check
if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
redraw!
echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
let &report= repkeep
" call Dret("zip#Write")
return
endif
" the following code does much the same thing as " the following code does much the same thing as
" exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1) " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1)
@ -236,9 +250,9 @@ fun! zip#Write(fname)
set report=10 set report=10
" sanity checks " sanity checks
if !executable(g:zip_zipcmd) if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
redraw! redraw!
echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program" | echohl None
" call inputsave()|call input("Press <cr> to continue")|call inputrestore() " call inputsave()|call input("Press <cr> to continue")|call inputrestore()
let &report= repkeep let &report= repkeep
" call Dret("zip#Write") " call Dret("zip#Write")
@ -344,6 +358,48 @@ fun! zip#Write(fname)
" call Dret("zip#Write") " call Dret("zip#Write")
endfun endfun
" ---------------------------------------------------------------------
" zip#Extract: extract a file from a zip archive {{{2
fun! zip#Extract()
" call Dfunc("zip#Extract()")
let repkeep= &report
set report=10
let fname= getline(".")
" call Decho("fname<".fname.">")
" sanity check
if fname =~ '^"'
let &report= repkeep
" call Dret("zip#Extract")
return
endif
if fname =~ '/$'
redraw!
echohl Error | echo "***error*** (zip#Extract) Please specify a file, not a directory" | echohl None
let &report= repkeep
" call Dret("zip#Extract")
return
endif
" extract the file mentioned under the cursor
" call Decho("system(".g:zip_extractcmd." ".shellescape(b:zipfile)." ".shellescape(shell).")")
call system(g:zip_extractcmd." ".shellescape(b:zipfile)." ".shellescape(shell))
" call Decho("zipfile<".b:zipfile.">")
if v:shell_error != 0
echohl Error | echo "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!" | echohl NONE
elseif !filereadable(fname)
echohl Error | echo "***error*** attempted to extract ".fname." but it doesn't appear to be present!"
else
echo "***note*** successfully extracted ".fname
endif
" restore option
let &report= repkeep
" call Dret("zip#Extract")
endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" s:Escape: {{{2 " s:Escape: {{{2
fun! s:Escape(fname,isfilt) fun! s:Escape(fname,isfilt)

View File

@ -53,7 +53,6 @@
: scriptnames : scriptnames
:endif :endif
:set all :set all
:set termcap
:if has("autocmd") :if has("autocmd")
: au : au
:endif :endif

View File

@ -41,9 +41,16 @@ this autocmd might be useful:
autocmd SourcePre */colors/blue_sky.vim set background=dark autocmd SourcePre */colors/blue_sky.vim set background=dark
Replace "blue_sky" with the name of the colorscheme. Replace "blue_sky" with the name of the colorscheme.
In case you want to tweak a colorscheme after it was loaded, check out that In case you want to tweak a colorscheme after it was loaded, check out the
ColorScheme autocmd event. ColorScheme autocmd event.
To customize a colorscheme use another name, e.g. "~/.vim/colors/mine.vim",
and use `:runtime` to load the original colorscheme:
" load the "evening" colorscheme
runtime colors/evening.vim
" change the color of statements
hi Statement ctermfg=Blue guifg=Blue
To see which highlight group is used where, find the help for To see which highlight group is used where, find the help for
"highlight-groups" and "group-name". "highlight-groups" and "group-name".

View File

@ -1,6 +1,6 @@
" Vim color file " Vim color file
" Maintainer: Bram Moolenaar <Bram@vim.org> " Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2006 Apr 14 " Last Change: 2016 Oct 10
" This color scheme uses a dark grey background. " This color scheme uses a dark grey background.
@ -45,8 +45,8 @@ hi CursorColumn term=reverse ctermbg=Black guibg=grey40
hi CursorLine term=underline cterm=underline guibg=grey40 hi CursorLine term=underline cterm=underline guibg=grey40
" Groups for syntax highlighting " Groups for syntax highlighting
hi Constant term=underline ctermfg=Magenta guifg=#ffa0a0 guibg=grey5 hi Constant term=underline ctermfg=Magenta guifg=#ffa0a0
hi Special term=bold ctermfg=LightRed guifg=Orange guibg=grey5 hi Special term=bold ctermfg=LightRed guifg=Orange
if &t_Co > 8 if &t_Co > 8
hi Statement term=bold cterm=bold ctermfg=Yellow guifg=#ffff60 gui=bold hi Statement term=bold cterm=bold ctermfg=Yellow guifg=#ffff60 gui=bold
endif endif

View File

@ -2,7 +2,7 @@
" vim: tw=0 ts=4 sw=4 " vim: tw=0 ts=4 sw=4
" Vim color file " Vim color file
" Maintainer: Ron Aaron <ron@ronware.org> " Maintainer: Ron Aaron <ron@ronware.org>
" Last Change: 2013 May 23 " Last Change: 2016 Sep 04
hi clear hi clear
set background=dark set background=dark
@ -45,6 +45,7 @@ hi TabLineFill term=bold,reverse cterm=bold ctermfg=lightblue ctermbg=white g
hi TabLineSel term=reverse ctermfg=white ctermbg=lightblue guifg=white guibg=blue hi TabLineSel term=reverse ctermfg=white ctermbg=lightblue guifg=white guibg=blue
hi Underlined term=underline cterm=bold,underline ctermfg=lightblue guifg=lightblue gui=bold,underline hi Underlined term=underline cterm=bold,underline ctermfg=lightblue guifg=lightblue gui=bold,underline
hi Ignore ctermfg=black ctermbg=black guifg=black guibg=black hi Ignore ctermfg=black ctermbg=black guifg=black guibg=black
hi EndOfBuffer term=bold cterm=bold ctermfg=darkred guifg=#cc0000 gui=bold
hi link IncSearch Visual hi link IncSearch Visual
hi link String Constant hi link String Constant
hi link Character Constant hi link Character Constant

View File

@ -1,7 +1,7 @@
" Vim compiler file " Vim compiler file
" Compiler: BDF to PCF Conversion " Compiler: BDF to PCF Conversion
" Maintainer: Nikolai Weibull <now@bitwi.se> " Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2006-04-19 " Latest Revision: 2006-04-19
if exists("current_compiler") if exists("current_compiler")
finish finish

View File

@ -0,0 +1,35 @@
" Vim compiler file
" Compiler: Cargo Compiler
" Maintainer: Damien Radtke <damienradtke@gmail.com>
" Latest Revision: 2014 Sep 24
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if exists('current_compiler')
finish
endif
runtime compiler/rustc.vim
let current_compiler = "cargo"
let s:save_cpo = &cpo
set cpo&vim
if exists(':CompilerSet') != 2
command -nargs=* CompilerSet setlocal <args>
endif
if exists('g:cargo_makeprg_params')
execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*'
else
CompilerSet makeprg=cargo\ $*
endif
" Ignore general cargo progress messages
CompilerSet errorformat+=
\%-G%\\s%#Downloading%.%#,
\%-G%\\s%#Compiling%.%#,
\%-G%\\s%#Finished%.%#,
\%-G%\\s%#error:\ Could\ not\ compile\ %.%#,
\%-G%\\s%#To\ learn\ more\\,%.%#
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,54 @@
" Vim compiler file
" Compiler: ConTeXt typesetting engine
" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com>
" Last Change: 2016 Oct 21
if exists("current_compiler")
finish
endif
let s:keepcpo= &cpo
set cpo&vim
if exists(":CompilerSet") != 2 " older Vim always used :setlocal
command -nargs=* CompilerSet setlocal <args>
endif
" If makefile exists and we are not asked to ignore it, we use standard make
" (do not redefine makeprg)
if get(b:, 'context_ignore_makefile', get(g:, 'context_ignore_makefile', 0)) ||
\ (!filereadable('Makefile') && !filereadable('makefile'))
let current_compiler = 'context'
" The following assumes that the current working directory is set to the
" directory of the file to be typeset
let &l:makeprg = get(b:, 'context_mtxrun', get(g:, 'context_mtxrun', 'mtxrun'))
\ . ' --script context --autogenerate --nonstopmode --synctex='
\ . (get(b:, 'context_synctex', get(g:, 'context_synctex', 0)) ? '1' : '0')
\ . ' ' . get(b:, 'context_extra_options', get(g:, 'context_extra_options', ''))
\ . ' ' . shellescape(expand('%:p:t'))
else
let current_compiler = 'make'
endif
let b:context_errorformat = ''
\ . '%-Popen source%.%#> %f,'
\ . '%-Qclose source%.%#> %f,'
\ . "%-Popen source%.%#name '%f',"
\ . "%-Qclose source%.%#name '%f',"
\ . '%Etex %trror%.%#mp error on line %l in file %f:%.%#,'
\ . 'tex %trror%.%#error on line %l in file %f: %m,'
\ . '%Elua %trror%.%#error on line %l in file %f:,'
\ . '%+Emetapost %#> error: %#,'
\ . '! error: %#%m,'
\ . '%-C %#,'
\ . '%C! %m,'
\ . '%Z[ctxlua]%m,'
\ . '%+C<*> %.%#,'
\ . '%-C%.%#,'
\ . '%Z...%m,'
\ . '%-Zno-error,'
\ . '%-G%.%#' " Skip remaining lines
execute 'CompilerSet errorformat=' . escape(b:context_errorformat, ' ')
let &cpo = s:keepcpo
unlet s:keepcpo

View File

@ -0,0 +1,16 @@
" Vim compiler file
" Compiler: csslint for CSS
" Maintainer: Daniel Moch <daniel@danielmoch.com>
" Last Change: 2016 May 21
if exists("current_compiler")
finish
endif
let current_compiler = "csslint"
if exists(":CompilerSet") != 2 " older Vim always used :setlocal
command -nargs=* CompilerSet setlocal <args>
endif
CompilerSet makeprg=csslint\ --format=compact
CompilerSet errorformat=%-G,%-G%f:\ lint\ free!,%f:\ line\ %l\\,\ col\ %c\\,\ %trror\ -\ %m,%f:\ line\ %l\\,\ col\ %c\\,\ %tarning\ -\ %m,%f:\ line\ %l\\,\ col\ %c\\,\ %m

View File

@ -1,7 +1,7 @@
" Vim compiler file " Vim compiler file
" Compiler: Cucumber " Compiler: Cucumber
" Maintainer: Tim Pope <vimNOSPAM@tpope.org> " Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2010 Aug 09 " Last Change: 2016 Aug 29
if exists("current_compiler") if exists("current_compiler")
finish finish
@ -19,7 +19,7 @@ CompilerSet makeprg=cucumber
CompilerSet errorformat= CompilerSet errorformat=
\%W%m\ (Cucumber::Undefined), \%W%m\ (Cucumber::Undefined),
\%E%m\ (%.%#), \%E%m\ (%\\S%#),
\%Z%f:%l, \%Z%f:%l,
\%Z%f:%l:%.%# \%Z%f:%l:%.%#

View File

@ -1,7 +1,7 @@
" Vim compiler file " Vim compiler file
" Compiler: GNU C Compiler " Compiler: GNU C Compiler
" Maintainer: Nikolai Weibull <now@bitwi.se> " Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2010-10-14 " Latest Revision: 2010-10-14
" added line suggested by Anton Lindqvist 2016 Mar 31 " added line suggested by Anton Lindqvist 2016 Mar 31
if exists("current_compiler") if exists("current_compiler")

26
runtime/compiler/ghc.vim Normal file
View File

@ -0,0 +1,26 @@
" Vim compiler file
" Compiler: GHC Haskell Compiler
" Maintainer: Daniel Campoverde <alx@sillybytes.net>
" Latest Revision: 2016-11-29
if exists("current_compiler")
finish
endif
let current_compiler = "ghc"
let s:cpo_save = &cpo
set cpo&vim
CompilerSet errorformat=
\%-G%.%#:\ build,
\%-G%.%#preprocessing\ library\ %.%#,
\%-G[%.%#]%.%#,
\%E%f:%l:%c:\ %m,
\%-G--%.%#
if exists('g:compiler_ghc_ignore_unmatched_lines')
CompilerSet errorformat+=%-G%.%#
endif
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@ -1,7 +1,7 @@
" Vim compiler file " Vim compiler file
" Compiler: Haml " Compiler: Haml
" Maintainer: Tim Pope <vimNOSPAM@tpope.org> " Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2013 May 30 " Last Change: 2016 Aug 29
if exists("current_compiler") if exists("current_compiler")
finish finish
@ -15,7 +15,7 @@ endif
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo-=C set cpo-=C
CompilerSet makeprg=haml\ -c CompilerSet makeprg=haml
CompilerSet errorformat= CompilerSet errorformat=
\Haml\ %trror\ on\ line\ %l:\ %m, \Haml\ %trror\ on\ line\ %l:\ %m,

View File

@ -0,0 +1,16 @@
" Vim compiler file
" Compiler: Pylint for Python
" Maintainer: Daniel Moch <daniel@danielmoch.com>
" Last Change: 2016 May 20
if exists("current_compiler")
finish
endif
let current_compiler = "pylint"
if exists(":CompilerSet") != 2 " older Vim always used :setlocal
command -nargs=* CompilerSet setlocal <args>
endif
CompilerSet makeprg=pylint\ --output-format=text\ --msg-template=\"{path}:{line}:{column}:{C}:\ [{symbol}]\ {msg}\"\ --reports=no
CompilerSet errorformat=%A%f:%l:%c:%t:\ %m,%A%f:%l:\ %m,%A%f:(%l):\ %m,%-Z%p^%.%#,%-G%.%#

View File

@ -27,7 +27,11 @@ CompilerSet errorformat=
\%\\s%#[%f:%l:\ %#%m, \%\\s%#[%f:%l:\ %#%m,
\%\\s%#%f:%l:\ %#%m, \%\\s%#%f:%l:\ %#%m,
\%\\s%#%f:%l:, \%\\s%#%f:%l:,
\%m\ [%f:%l]: \%m\ [%f:%l]:,
\%+Erake\ aborted!,
\%+EDon't\ know\ how\ to\ build\ task\ %.%#,
\%+Einvalid\ option:%.%#,
\%+Irake\ %\\S%\\+%\\s%\\+#\ %.%#
let &cpo = s:cpo_save let &cpo = s:cpo_save
unlet s:cpo_save unlet s:cpo_save

View File

@ -22,9 +22,10 @@ CompilerSet errorformat=
\%f:%l:\ %tarning:\ %m, \%f:%l:\ %tarning:\ %m,
\%E%.%#:in\ `load':\ %f:%l:%m, \%E%.%#:in\ `load':\ %f:%l:%m,
\%E%f:%l:in\ `%*[^']':\ %m, \%E%f:%l:in\ `%*[^']':\ %m,
\%-Z\ \ \ \ \ \#\ %f:%l:%.%#, \%-Z\ \ \ \ \ %\\+\#\ %f:%l:%.%#,
\%E\ \ %\\d%\\+)%.%#, \%E\ \ %\\d%\\+)%.%#,
\%C\ \ \ \ \ %m, \%C\ \ \ \ \ %m,
\%C%\\s%#,
\%-G%.%# \%-G%.%#
let &cpo = s:cpo_save let &cpo = s:cpo_save

View File

@ -1,7 +1,8 @@
" Vim compiler file " Vim compiler file
" Compiler: reStructuredText Documentation Format " Compiler: sphinx >= 1.0.8, http://www.sphinx-doc.org
" Maintainer: Nikolai Weibull <now@bitwi.se> " Description: reStructuredText Documentation Format
" Latest Revision: 2006-04-19 " Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2017-03-31
if exists("current_compiler") if exists("current_compiler")
finish finish
@ -11,12 +12,18 @@ let current_compiler = "rst"
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo&vim set cpo&vim
setlocal errorformat= if exists(":CompilerSet") != 2
\%f:%l:\ (%tEBUG/0)\ %m, command -nargs=* CompilerSet setlocal <args>
\%f:%l:\ (%tNFO/1)\ %m, endif
\%f:%l:\ (%tARNING/2)\ %m,
\%f:%l:\ (%tRROR/3)\ %m, CompilerSet errorformat=
\%f:%l:\ (%tEVERE/3)\ %m, \%f\\:%l:\ %tEBUG:\ %m,
\%f\\:%l:\ %tNFO:\ %m,
\%f\\:%l:\ %tARNING:\ %m,
\%f\\:%l:\ %tRROR:\ %m,
\%f\\:%l:\ %tEVERE:\ %m,
\%f\\:%s:\ %tARNING:\ %m,
\%f\\:%s:\ %tRROR:\ %m,
\%D%*\\a[%*\\d]:\ Entering\ directory\ `%f', \%D%*\\a[%*\\d]:\ Entering\ directory\ `%f',
\%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f', \%X%*\\a[%*\\d]:\ Leaving\ directory\ `%f',
\%DMaking\ %*\\a\ in\ %f \%DMaking\ %*\\a\ in\ %f

View File

@ -17,6 +17,8 @@ let s:cpo_save = &cpo
set cpo-=C set cpo-=C
CompilerSet makeprg=testrb CompilerSet makeprg=testrb
" CompilerSet makeprg=ruby\ -Itest
" CompilerSet makeprg=m
CompilerSet errorformat=\%W\ %\\+%\\d%\\+)\ Failure:, CompilerSet errorformat=\%W\ %\\+%\\d%\\+)\ Failure:,
\%C%m\ [%f:%l]:, \%C%m\ [%f:%l]:,

View File

@ -0,0 +1,46 @@
" Vim compiler file
" Compiler: Rust Compiler
" Maintainer: Chris Morgan <me@chrismorgan.info>
" Latest Revision: 2013 Jul 12
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if exists("current_compiler")
finish
endif
let current_compiler = "rustc"
let s:cpo_save = &cpo
set cpo&vim
if exists(":CompilerSet") != 2
command -nargs=* CompilerSet setlocal <args>
endif
if exists("g:rustc_makeprg_no_percent") && g:rustc_makeprg_no_percent != 0
CompilerSet makeprg=rustc
else
CompilerSet makeprg=rustc\ \%
endif
" Old errorformat (before nightly 2016/08/10)
CompilerSet errorformat=
\%f:%l:%c:\ %t%*[^:]:\ %m,
\%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m,
\%-G%f:%l\ %s,
\%-G%*[\ ]^,
\%-G%*[\ ]^%*[~],
\%-G%*[\ ]...
" New errorformat (after nightly 2016/08/10)
CompilerSet errorformat+=
\%-G,
\%-Gerror:\ aborting\ %.%#,
\%-Gerror:\ Could\ not\ compile\ %.%#,
\%Eerror:\ %m,
\%Eerror[E%n]:\ %m,
\%Wwarning:\ %m,
\%Inote:\ %m,
\%C\ %#-->\ %f:%l:%c
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@ -1,7 +1,7 @@
" Vim compiler file " Vim compiler file
" Compiler: Sass " Compiler: Sass
" Maintainer: Tim Pope <vimNOSPAM@tpope.org> " Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2013 May 30 " Last Change: 2016 Aug 29
if exists("current_compiler") if exists("current_compiler")
finish finish
@ -15,7 +15,7 @@ endif
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo-=C set cpo-=C
CompilerSet makeprg=sass\ -c CompilerSet makeprg=sass
CompilerSet errorformat= CompilerSet errorformat=
\%f:%l:%m\ (Sass::Syntax%trror), \%f:%l:%m\ (Sass::Syntax%trror),

View File

@ -1,4 +1,4 @@
*api.txt* {Nvim} *api.txt* Nvim
NVIM REFERENCE MANUAL by Thiago de Arruda NVIM REFERENCE MANUAL by Thiago de Arruda
@ -7,10 +7,11 @@
Nvim API *API* *api* Nvim API *API* *api*
Nvim exposes a powerful API that can be used by plugins and external processes Nvim exposes a powerful API that can be used by plugins and external processes
via |msgpack-rpc|, Lua and VimL (|eval-api|). via |RPC|, |Lua| and VimL (|eval-api|).
Nvim can also be embedded in C applications as libnvim, so the application Applications can also embed libnvim to work with the C API directly.
can control the embedded instance by calling the C API directly.
Type |gO| to see the table of contents.
============================================================================== ==============================================================================
API Types *api-types* API Types *api-types*
@ -47,6 +48,7 @@ version.api_compatible API is backwards-compatible with this level
version.api_prerelease Declares the current API level as unstable > version.api_prerelease Declares the current API level as unstable >
(version.api_prerelease && fn.since == version.api_level) (version.api_prerelease && fn.since == version.api_level)
functions API function signatures functions API function signatures
ui_events UI event signatures |ui|
{fn}.since API level where function {fn} was introduced {fn}.since API level where function {fn} was introduced
{fn}.deprecated_since API level where function {fn} was deprecated {fn}.deprecated_since API level where function {fn} was deprecated
types Custom handle types defined by Nvim types Custom handle types defined by Nvim
@ -54,6 +56,28 @@ error_types Possible error types returned by API functions
External programs ("clients") can use the metadata to discover the |rpc-api|. External programs ("clients") can use the metadata to discover the |rpc-api|.
==============================================================================
API contract *api-contract*
The API is made of functions and events. Clients call functions like those
described at |api-global|, and may "attach" in order to receive rich events,
described at |rpc-remote-ui|.
As Nvim develops, its API may change only according the following "contract":
- New functions and events may be added.
- Any such extensions are OPTIONAL: old clients may ignore them.
- Function signatures will NOT CHANGE (after release).
- Functions introduced in the development (unreleased) version MAY CHANGE.
(Clients can dynamically check `api_prerelease`, etc. |api-metadata|)
- Event parameters will not be removed or reordered (after release).
- Events may be EXTENDED: new parameters may be added.
- New items may be ADDED to map/list parameters/results of functions and
events.
- Any such new items are OPTIONAL: old clients may ignore them.
- Existing items will not be removed (after release).
- Deprecated functions will not be removed until Nvim version 2.0
============================================================================== ==============================================================================
Buffer highlighting *api-highlights* Buffer highlighting *api-highlights*
@ -111,6 +135,26 @@ nvim_command({command}) *nvim_command()*
Parameters:~ Parameters:~
{command} Ex-command string {command} Ex-command string
nvim_get_hl_by_name({name}, {rgb}) *nvim_get_hl_by_name()*
Gets a highlight definition by name.
Parameters:~
{name} Highlight group name
{rgb} Export RGB colors
Return:~
Highlight definition map
nvim_get_hl_by_id({hl_id}, {rgb}) *nvim_get_hl_by_id()*
Gets a highlight definition by id. |hlID()|
Parameters:~
{hl_id} Highlight id as returned by |hlID()|
{rgb} Export RGB colors
Return:~
Highlight definition map
nvim_feedkeys({keys}, {mode}, {escape_csi}) *nvim_feedkeys()* nvim_feedkeys({keys}, {mode}, {escape_csi}) *nvim_feedkeys()*
Passes input keys to Nvim. On VimL error: Does not fail, but Passes input keys to Nvim. On VimL error: Does not fail, but
updates v:errmsg. updates v:errmsg.
@ -127,7 +171,11 @@ nvim_input({keys}) *nvim_input()*
Unlike `nvim_feedkeys`, this uses a lower-level input buffer Unlike `nvim_feedkeys`, this uses a lower-level input buffer
and the call is not deferred. This is the most reliable way to and the call is not deferred. This is the most reliable way to
emulate real user input. send real user input.
Note:
|keycodes| like <CR> are translated, so "<" is special. To
input a literal "<", send <LT>.
Attributes:~ Attributes:~
{async} {async}
@ -141,7 +189,16 @@ nvim_input({keys}) *nvim_input()*
*nvim_replace_termcodes()* *nvim_replace_termcodes()*
nvim_replace_termcodes({str}, {from_part}, {do_lt}, {special}) nvim_replace_termcodes({str}, {from_part}, {do_lt}, {special})
Replaces any terminal codes with the internal representation Replaces terminal codes and |keycodes| (<CR>, <Esc>, ...) in a
string with the internal representation.
Parameters:~
{str} String to be converted.
{from_part} Legacy Vim parameter. Usually true.
{do_lt} Also translate <lt>. Ignored if `special` is
false.
{special} Replace |keycodes|, e.g. <CR> becomes a "\n"
char.
nvim_command_output({str}) *nvim_command_output()* nvim_command_output({str}) *nvim_command_output()*
TODO: Documentation TODO: Documentation
@ -158,8 +215,10 @@ nvim_eval({expr}) *nvim_eval()*
Evaluation result or expanded object Evaluation result or expanded object
nvim_call_function({fname}, {args}) *nvim_call_function()* nvim_call_function({fname}, {args}) *nvim_call_function()*
Calls a VimL function with the given arguments. On VimL error: Calls a VimL function with the given arguments
Returns a generic error; v:errmsg is not updated.
On VimL error: Returns a generic error; v:errmsg is not
updated.
Parameters:~ Parameters:~
{fname} Function to call {fname} Function to call
@ -168,7 +227,21 @@ nvim_call_function({fname}, {args}) *nvim_call_function()*
Return:~ Return:~
Result of the function call Result of the function call
nvim_strwidth({str}) *nvim_strwidth()* nvim_execute_lua({code}, {args}) *nvim_execute_lua()*
Execute lua code. Parameters (if any) are available as `...`
inside the chunk. The chunk can return a value.
Only statements are executed. To evaluate an expression,
prefix it with `return`: return my_function(...)
Parameters:~
{code} lua code to execute
{args} Arguments to the code
Return:~
Return value of lua code if present or NIL.
nvim_strwidth({text}) *nvim_strwidth()*
Calculates the number of display cells occupied by `text`. Calculates the number of display cells occupied by `text`.
<Tab> counts as one cell. <Tab> counts as one cell.
@ -247,7 +320,7 @@ nvim_get_option({name}) *nvim_get_option()*
{name} Option name {name} Option name
Return:~ Return:~
Option value Option value (global)
nvim_set_option({name}, {value}) *nvim_set_option()* nvim_set_option({name}, {value}) *nvim_set_option()*
Sets an option value Sets an option value
@ -257,20 +330,24 @@ nvim_set_option({name}, {value}) *nvim_set_option()*
{value} New option value {value} New option value
nvim_out_write({str}) *nvim_out_write()* nvim_out_write({str}) *nvim_out_write()*
Writes a message to vim output buffer Writes a message to the Vim output buffer. Does not append
"\n", the message is buffered (won't display) until a linefeed
is written.
Parameters:~ Parameters:~
{str} Message {str} Message
nvim_err_write({str}) *nvim_err_write()* nvim_err_write({str}) *nvim_err_write()*
Writes a message to vim error buffer Writes a message to the Vim error buffer. Does not append
"\n", the message is buffered (won't display) until a linefeed
is written.
Parameters:~ Parameters:~
{str} Message {str} Message
nvim_err_writeln({str}) *nvim_err_writeln()* nvim_err_writeln({str}) *nvim_err_writeln()*
Writes a message to vim error buffer. Appends a linefeed to Writes a message to the Vim error buffer. Appends "\n", so the
ensure all contents are written. buffer is flushed (and displayed).
Parameters:~ Parameters:~
{str} Message {str} Message
@ -291,7 +368,7 @@ nvim_set_current_buf({buffer}) *nvim_set_current_buf()*
Sets the current buffer Sets the current buffer
Parameters:~ Parameters:~
{id} Buffer handle {buffer} Buffer handle
nvim_list_wins() *nvim_list_wins()* nvim_list_wins() *nvim_list_wins()*
Gets the current list of window handles Gets the current list of window handles
@ -309,7 +386,7 @@ nvim_set_current_win({window}) *nvim_set_current_win()*
Sets the current window Sets the current window
Parameters:~ Parameters:~
{handle} Window handle {window} Window handle
nvim_list_tabpages() *nvim_list_tabpages()* nvim_list_tabpages() *nvim_list_tabpages()*
Gets the current list of tabpage handles Gets the current list of tabpage handles
@ -327,7 +404,7 @@ nvim_set_current_tabpage({tabpage}) *nvim_set_current_tabpage()*
Sets the current tabpage Sets the current tabpage
Parameters:~ Parameters:~
{handle} Tabpage handle {tabpage} Tabpage handle
nvim_subscribe({event}) *nvim_subscribe()* nvim_subscribe({event}) *nvim_subscribe()*
Subscribes to event broadcasts Subscribes to event broadcasts
@ -347,6 +424,27 @@ nvim_get_color_by_name({name}) *nvim_get_color_by_name()*
nvim_get_color_map() *nvim_get_color_map()* nvim_get_color_map() *nvim_get_color_map()*
TODO: Documentation TODO: Documentation
nvim_get_mode() *nvim_get_mode()*
Gets the current mode. |mode()| "blocking" is true if Nvim is
waiting for input.
Return:~
Dictionary { "mode": String, "blocking": Boolean }
Attributes:~
{async}
nvim_get_keymap({mode}) *nvim_get_keymap()*
Gets a list of dictionaries describing global (non-buffer)
mappings. The "buffer" key in the returned dictionary is
always zero.
Parameters:~
{mode} Mode short-name ("n", "i", "v", ...)
Return:~
Array of maparg()-like dictionaries describing mappings
nvim_get_api_info() *nvim_get_api_info()* nvim_get_api_info() *nvim_get_api_info()*
TODO: Documentation TODO: Documentation
@ -379,6 +477,54 @@ nvim_call_atomic({calls}) *nvim_call_atomic()*
error ocurred, the values from all preceding calls will error ocurred, the values from all preceding calls will
still be returned. still be returned.
nvim__id({obj}) *nvim__id()*
Returns object given as argument
This API function is used for testing. One should not rely on
its presence in plugins.
Parameters:~
{obj} Object to return.
Return:~
its argument.
nvim__id_array({arr}) *nvim__id_array()*
Returns array given as argument
This API function is used for testing. One should not rely on
its presence in plugins.
Parameters:~
{arr} Array to return.
Return:~
its argument.
nvim__id_dictionary({dct}) *nvim__id_dictionary()*
Returns dictionary given as argument
This API function is used for testing. One should not rely on
its presence in plugins.
Parameters:~
{dct} Dictionary to return.
Return:~
its argument.
nvim__id_float({flt}) *nvim__id_float()*
Returns floating-point value given as argument
This API function is used for testing. One should not rely on
its presence in plugins.
Parameters:~
{flt} Value to return.
Return:~
its argument.
============================================================================== ==============================================================================
Buffer Functions *api-buffer* Buffer Functions *api-buffer*
@ -457,6 +603,18 @@ nvim_buf_get_changedtick({buffer}) *nvim_buf_get_changedtick()*
Return:~ Return:~
b:changedtickvalue. b:changedtickvalue.
nvim_buf_get_keymap({buffer}, {mode}) *nvim_buf_get_keymap()*
Gets a list of dictionaries describing buffer-local mappings.
The "buffer" key in the returned dictionary reflects the
buffer handle where the mapping is present.
Parameters:~
{mode} Mode short-name ("n", "i", "v", ...)
{buffer} Buffer handle
Return:~
Array of maparg()-like dictionaries describing mappings
nvim_buf_set_var({buffer}, {name}, {value}) *nvim_buf_set_var()* nvim_buf_set_var({buffer}, {name}, {value}) *nvim_buf_set_var()*
Sets a buffer-scoped (b:) variable Sets a buffer-scoped (b:) variable
@ -491,15 +649,6 @@ nvim_buf_set_option({buffer}, {name}, {value}) *nvim_buf_set_option()*
{name} Option name {name} Option name
{value} Option value {value} Option value
nvim_buf_get_number({buffer}) *nvim_buf_get_number()*
Gets the buffer number
Parameters:~
{buffer} Buffer handle
Return:~
Buffer number
nvim_buf_get_name({buffer}) *nvim_buf_get_name()* nvim_buf_get_name({buffer}) *nvim_buf_get_name()*
Gets the full file name for the buffer Gets the full file name for the buffer
@ -541,24 +690,24 @@ nvim_buf_add_highlight({buffer}, {src_id}, {hl_group}, {line},
{col_start}, {col_end}) {col_start}, {col_end})
Adds a highlight to buffer. Adds a highlight to buffer.
This can be used for plugins which dynamically generate Useful for plugins that dynamically generate highlights to a
highlights to a buffer (like a semantic highlighter or buffer (like a semantic highlighter or linter). The function
linter). The function adds a single highlight to a buffer. adds a single highlight to a buffer. Unlike matchaddpos()
Unlike matchaddpos() highlights follow changes to line highlights follow changes to line numbering (as lines are
numbering (as lines are inserted/removed above the highlighted inserted/removed above the highlighted line), like signs and
line), like signs and marks do. marks do.
"src_id" is useful for batch deletion/updating of a set of `src_id` is useful for batch deletion/updating of a set of
highlights. When called with src_id = 0, an unique source id highlights. When called with `src_id = 0`, an unique source id
is generated and returned. Succesive calls can pass in it as is generated and returned. Successive calls can pass that
"src_id" to add new highlights to the same source group. All `src_id` to associate new highlights with the same source
highlights in the same group can then be cleared with group. All highlights in the same group can be cleared with
nvim_buf_clear_highlight. If the highlight never will be `nvim_buf_clear_highlight`. If the highlight never will be
manually deleted pass in -1 for "src_id". manually deleted, pass `src_id = -1`.
If "hl_group" is the empty string no highlight is added, but a If `hl_group` is the empty string no highlight is added, but a
new src_id is still returned. This is useful for an external new `src_id` is still returned. This is useful for an external
plugin to synchrounously request an unique src_id at plugin to synchrounously request an unique `src_id` at
initialization, and later asynchronously add and clear initialization, and later asynchronously add and clear
highlights in response to buffer changes. highlights in response to buffer changes.
@ -567,7 +716,7 @@ nvim_buf_add_highlight({buffer}, {src_id}, {hl_group}, {line},
{src_id} Source group to use or 0 to use a new group, {src_id} Source group to use or 0 to use a new group,
or -1 for ungrouped highlight or -1 for ungrouped highlight
{hl_group} Name of the highlight group to use {hl_group} Name of the highlight group to use
{line} Line to highlight {line} Line to highlight (zero-indexed)
{col_start} Start of range of columns to highlight {col_start} Start of range of columns to highlight
{col_end} End of range of columns to highlight, or -1 {col_end} End of range of columns to highlight, or -1
to highlight to end of line to highlight to end of line
@ -819,4 +968,4 @@ nvim_ui_try_resize({width}, {height}) *nvim_ui_try_resize()*
nvim_ui_set_option({name}, {value}) *nvim_ui_set_option()* nvim_ui_set_option({name}, {value}) *nvim_ui_set_option()*
TODO: Documentation TODO: Documentation
vim:tw=78:ts=8:ft=help:norl: vim:tw=78:ts=8:ft=help:norl:

View File

@ -1,4 +1,4 @@
*arabic.txt* For Vim version 7.4. Last change: 2010 Nov 13 *arabic.txt* Nvim
VIM REFERENCE MANUAL by Nadim Shaikli VIM REFERENCE MANUAL by Nadim Shaikli
@ -36,7 +36,7 @@ the user interface remains the standard Vi interface.
Highlights Highlights
---------- ----------
o Editing left-to-right files as in the original VIM hasn't changed. o Editing left-to-right files as in the original Vim hasn't changed.
o Viewing and editing files in right-to-left windows. File o Viewing and editing files in right-to-left windows. File
orientation is per window, so it is possible to view the same orientation is per window, so it is possible to view the same
@ -46,7 +46,7 @@ o No special terminal with right-to-left capabilities is required.
The right-to-left changes are completely hardware independent. The right-to-left changes are completely hardware independent.
Only Arabic fonts are necessary. Only Arabic fonts are necessary.
o Compatible with the original VIM. Almost all features work in o Compatible with the original Vim. Almost all features work in
right-to-left mode (there are liable to be bugs). right-to-left mode (there are liable to be bugs).
o Changing keyboard mapping and reverse insert modes using a single o Changing keyboard mapping and reverse insert modes using a single
@ -60,14 +60,14 @@ o While in Arabic mode, numbers are entered from left to right. Upon
o Arabic keymapping on the command line in reverse insert mode. o Arabic keymapping on the command line in reverse insert mode.
o Proper Bidirectional functionality is possible given VIM is o Proper Bidirectional functionality is possible given Vim is
started within a Bidi capable terminal emulator. started within a Bidi capable terminal emulator.
Arabic Fonts *arabicfonts* Arabic Fonts *arabicfonts*
------------ ------------
VIM requires monospaced fonts of which there are many out there. Vim requires monospaced fonts of which there are many out there.
Arabic requires ISO-8859-6 as well as Presentation Form-B fonts Arabic requires ISO-8859-6 as well as Presentation Form-B fonts
(without Form-B, Arabic will _NOT_ be usable). It is highly (without Form-B, Arabic will _NOT_ be usable). It is highly
recommended that users search for so-called 'ISO-10646-1' fonts. recommended that users search for so-called 'ISO-10646-1' fonts.
@ -90,13 +90,13 @@ o Installation of fonts for X Window systems (Unix/Linux)
Usage Usage
----- -----
Prior to the actual usage of Arabic within VIM, a number of settings Prior to the actual usage of Arabic within Vim, a number of settings
need to be accounted for and invoked. need to be accounted for and invoked.
o Setting the Arabic fonts o Setting the Arabic fonts
+ For VIM GUI set the 'guifont' to your_ARABIC_FONT. This is done + For Vim GUI set the 'guifont' to your_ARABIC_FONT. This is done
by entering the following command in the VIM window. by entering the following command in the Vim window.
> >
:set guifont=your_ARABIC_FONT :set guifont=your_ARABIC_FONT
< <
@ -109,7 +109,7 @@ o Setting the Arabic fonts
you can include ':set guifont=your_ARABIC_FONT' to your vimrc you can include ':set guifont=your_ARABIC_FONT' to your vimrc
file. file.
+ Under the X Window environment, you can also start VIM with + Under the X Window environment, you can also start Vim with
'-fn your_ARABIC_FONT' option. '-fn your_ARABIC_FONT' option.
o Setting the appropriate character Encoding o Setting the appropriate character Encoding
@ -131,11 +131,11 @@ o Setting the appropriate character Encoding
o Enable Arabic settings [short-cut] o Enable Arabic settings [short-cut]
In order to simplify and streamline things, you can either invoke In order to simplify and streamline things, you can either invoke
VIM with the command-line option, Vim with the command-line option,
% vim -A my_utf8_arabic_file ... % vim -A my_utf8_arabic_file ...
or enable 'arabic' via the following command within VIM or enable 'arabic' via the following command within Vim
> >
:set arabic :set arabic
< <
@ -196,7 +196,7 @@ o Enable Arabic settings [short-cut]
+ Arabic deletion of a combined pair character + Arabic deletion of a combined pair character
By default VIM has the 'delcombine' option disabled. This option By default Vim has the 'delcombine' option disabled. This option
allows the deletion of ALEF in a LAM_ALEF (LAA) combined character allows the deletion of ALEF in a LAM_ALEF (LAA) combined character
and still retain the LAM (i.e. it reverts to treating the combined and still retain the LAM (i.e. it reverts to treating the combined
character as its natural two characters form -- this also pertains character as its natural two characters form -- this also pertains
@ -255,7 +255,7 @@ o Enable Arabic settings [short-cut]
Keymap/Keyboard *arabickeymap* Keymap/Keyboard *arabickeymap*
--------------- ---------------
The character/letter encoding used in VIM is the standard UTF-8. The character/letter encoding used in Vim is the standard UTF-8.
It is widely discouraged that any other encoding be used or even It is widely discouraged that any other encoding be used or even
attempted. attempted.
@ -288,7 +288,7 @@ o Keyboard
Restrictions Restrictions
------------ ------------
o VIM in its GUI form does not currently support Bi-directionality o Vim in its GUI form does not currently support Bi-directionality
(i.e. the ability to see both Arabic and Latin intermixed within (i.e. the ability to see both Arabic and Latin intermixed within
the same line). the same line).

Some files were not shown because too many files have changed in this diff Show More