Merge 'upstream/master' into pr-win-erw7
This commit is contained in:
commit
c1015121ec
|
@ -8,6 +8,7 @@ IndentCaseLabels: true
|
|||
BreakBeforeBraces: Linux
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AlignTrailingComments: true
|
||||
SpacesBeforeTrailingComments: 2
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
|
@ -15,4 +16,5 @@ AllowShortIfStatementsOnASingleLine: false
|
|||
AllowShortLoopsOnASingleLine: false
|
||||
BinPackParameters: false
|
||||
BreakBeforeBinaryOperators: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
ContinuationIndentWidth: 4
|
29
.travis.yml
29
.travis.yml
|
@ -1,5 +1,5 @@
|
|||
dist: trusty
|
||||
sudo: false
|
||||
dist: xenial
|
||||
|
||||
language: c
|
||||
|
||||
env:
|
||||
|
@ -25,7 +25,7 @@ env:
|
|||
-DBUSTED_OUTPUT_TYPE=nvim
|
||||
-DDEPS_PREFIX=$DEPS_BUILD_DIR/usr
|
||||
-DMIN_LOG_LEVEL=3"
|
||||
- DEPS_CMAKE_FLAGS="-DDEPS_DOWNLOAD_DIR:PATH=$DEPS_DOWNLOAD_DIR"
|
||||
- DEPS_CMAKE_FLAGS="-DDEPS_DOWNLOAD_DIR:PATH=$DEPS_DOWNLOAD_DIR -DUSE_BUNDLED_GPERF=OFF"
|
||||
# Additional CMake flags for 32-bit builds.
|
||||
- CMAKE_FLAGS_32BIT="-DCMAKE_SYSTEM_LIBRARY_PATH=/lib32:/usr/lib32:/usr/local/lib32
|
||||
-DCMAKE_IGNORE_PATH=/lib:/usr/lib:/usr/local/lib
|
||||
|
@ -34,6 +34,7 @@ env:
|
|||
- ASAN_OPTIONS="detect_leaks=1:check_initialization_order=1:log_path=$LOG_DIR/asan"
|
||||
- TSAN_OPTIONS="log_path=$LOG_DIR/tsan"
|
||||
- UBSAN_OPTIONS="print_stacktrace=1 log_path=$LOG_DIR/ubsan"
|
||||
- ASAN_SYMBOLIZE=asan_symbolize
|
||||
# Environment variables for Valgrind.
|
||||
- VALGRIND_LOG="$LOG_DIR/valgrind-%p.log"
|
||||
# If this file exists, the cache is valid (compile was successful).
|
||||
|
@ -50,12 +51,12 @@ jobs:
|
|||
include:
|
||||
- stage: normal builds
|
||||
os: linux
|
||||
compiler: clang
|
||||
compiler: clang-4.0
|
||||
# Use Lua so that ASAN can test our embedded Lua support. 8fec4d53d0f6
|
||||
env: >
|
||||
CLANG_SANITIZER=ASAN_UBSAN
|
||||
# Use Lua so that ASAN can test our embedded Lua support. 8fec4d53d0f6
|
||||
CMAKE_FLAGS="$CMAKE_FLAGS -DPREFER_LUA=ON"
|
||||
sudo: true
|
||||
ASAN_SYMBOLIZE=asan_symbolize-4.0
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: >
|
||||
|
@ -96,29 +97,35 @@ before_cache: ci/before_cache.sh
|
|||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- apport
|
||||
- autoconf
|
||||
- automake
|
||||
- apport
|
||||
- build-essential
|
||||
- clang
|
||||
- clang-4.0
|
||||
- cmake
|
||||
- cscope
|
||||
- g++-multilib
|
||||
- gcc-multilib
|
||||
- gdb
|
||||
- gperf
|
||||
- language-pack-tr
|
||||
- libc6-dev-i386
|
||||
- libtool
|
||||
- libtool-bin
|
||||
- locales
|
||||
- ninja-build
|
||||
- pkg-config
|
||||
- unzip
|
||||
- valgrind
|
||||
- xclip
|
||||
homebrew:
|
||||
update: true
|
||||
packages:
|
||||
- ccache
|
||||
- ninja
|
||||
|
||||
branches:
|
||||
except:
|
||||
- nightly
|
||||
only:
|
||||
- master
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
|
|
|
@ -6,7 +6,10 @@ cmake_minimum_required(VERSION 2.8.12)
|
|||
project(nvim C)
|
||||
|
||||
if(POLICY CMP0059)
|
||||
cmake_policy(SET CMP0059 OLD) # Needed until cmake 2.8.12. #4389
|
||||
# Needed for use of DEFINITIONS variable, which is used to collect the
|
||||
# compilation flags for reporting in "nvim --version"
|
||||
# https://github.com/neovim/neovim/pull/8558#issuecomment-398033140
|
||||
cmake_policy(SET CMP0059 OLD)
|
||||
endif()
|
||||
|
||||
# Point CMake at any custom modules we may ship
|
||||
|
@ -386,7 +389,7 @@ include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS})
|
|||
option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF)
|
||||
|
||||
if(PREFER_LUA)
|
||||
find_package(Lua REQUIRED)
|
||||
find_package(Lua 5.1 REQUIRED)
|
||||
set(LUA_PREFERRED_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
|
||||
set(LUA_PREFERRED_LIBRARIES ${LUA_LIBRARIES})
|
||||
# Passive (not REQUIRED): if LUAJIT_FOUND is not set, nvim-test is skipped.
|
||||
|
@ -407,6 +410,7 @@ main(void)
|
|||
return MSGPACK_OBJECT_FLOAT32;
|
||||
}
|
||||
" MSGPACK_HAS_FLOAT32)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
if(MSGPACK_HAS_FLOAT32)
|
||||
add_definitions(-DNVIM_MSGPACK_HAS_FLOAT32)
|
||||
endif()
|
||||
|
@ -428,11 +432,13 @@ if(FEAT_TUI)
|
|||
return unibi_num_from_var(unibi_var_from_num(0));
|
||||
}
|
||||
" UNIBI_HAS_VAR_FROM)
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
if(UNIBI_HAS_VAR_FROM)
|
||||
add_definitions(-DNVIM_UNIBI_HAS_VAR_FROM)
|
||||
endif()
|
||||
|
||||
find_package(LibTermkey REQUIRED)
|
||||
find_package(LibTermkey 0.18 REQUIRED)
|
||||
include_directories(SYSTEM ${LIBTERMKEY_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
|
@ -440,7 +446,7 @@ find_package(LibVterm REQUIRED)
|
|||
include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS})
|
||||
|
||||
if(WIN32)
|
||||
find_package(Winpty REQUIRED)
|
||||
find_package(Winpty 0.4.3 REQUIRED)
|
||||
include_directories(SYSTEM ${WINPTY_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
|
@ -700,7 +706,7 @@ if(LUACHECK_PRG)
|
|||
-P ${PROJECT_SOURCE_DIR}/cmake/RunLuacheck.cmake)
|
||||
|
||||
add_custom_target(
|
||||
blobcodelint
|
||||
lintbuiltinlua
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-DLUACHECK_PRG=${LUACHECK_PRG}
|
||||
|
@ -709,10 +715,21 @@ if(LUACHECK_PRG)
|
|||
-DREAD_GLOBALS=vim
|
||||
-P ${PROJECT_SOURCE_DIR}/cmake/RunLuacheck.cmake
|
||||
)
|
||||
add_custom_target(
|
||||
lintruntimelua
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-DLUACHECK_PRG=${LUACHECK_PRG}
|
||||
-DLUAFILES_DIR=${CMAKE_CURRENT_SOURCE_DIR}/runtime/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
|
||||
DEPENDS lintruntimelua
|
||||
DEPENDS lintbuiltinlua
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -103,6 +103,10 @@ endif
|
|||
helptags: | nvim
|
||||
+$(BUILD_CMD) -C build helptags
|
||||
|
||||
# Builds help HTML _and_ checks for invalid help tags.
|
||||
helphtml: | nvim helptags
|
||||
+$(BUILD_CMD) -C build doc_html
|
||||
|
||||
functionaltest: | nvim
|
||||
+$(BUILD_CMD) -C build functionaltest
|
||||
|
||||
|
|
|
@ -59,7 +59,10 @@ To list all targets:
|
|||
|
||||
cmake --build build --target help
|
||||
|
||||
To skip "bundled" (`third-party/*`) dependencies, define `USE_BUNDLED=NO`.
|
||||
To skip "bundled" dependencies (`third-party/*`) define `USE_BUNDLED=NO`:
|
||||
|
||||
sudo apt install gperf libluajit-5.1-dev libunibilium-dev libmsgpack-dev libtermkey-dev libvterm-dev libjemalloc-dev
|
||||
make USE_BUNDLED=NO
|
||||
|
||||
See the [Building Neovim](https://github.com/neovim/neovim/wiki/Building-Neovim) wiki page for details.
|
||||
|
||||
|
@ -83,7 +86,7 @@ Project layout
|
|||
├─ ci/ build automation
|
||||
├─ cmake/ build scripts
|
||||
├─ runtime/ user plugins/docs
|
||||
├─ src/ application source code (see src/nvim/README.md)
|
||||
├─ src/nvim/ application source code (see src/nvim/README.md)
|
||||
│ ├─ api/ API subsystem
|
||||
│ ├─ eval/ VimL subsystem
|
||||
│ ├─ event/ event-loop subsystem
|
||||
|
|
|
@ -7,10 +7,6 @@ if [[ "${CI_TARGET}" == lint ]]; then
|
|||
exit
|
||||
fi
|
||||
|
||||
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
|
||||
>/dev/null brew update
|
||||
fi
|
||||
|
||||
echo 'python info:'
|
||||
(
|
||||
2>&1 python --version || true
|
||||
|
|
11
ci/build.ps1
11
ci/build.ps1
|
@ -50,6 +50,9 @@ if ($compiler -eq 'MINGW') {
|
|||
# Add MinGW to the PATH
|
||||
$env:PATH = "C:\msys64\mingw$bits\bin;$env:PATH"
|
||||
|
||||
# Avoid pacman "warning" which causes non-zero return code. https://github.com/open62541/open62541/issues/2068
|
||||
& C:\msys64\usr\bin\mkdir -p /var/cache/pacman/pkg
|
||||
|
||||
# Build third-party dependencies
|
||||
C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Su" ; exitIfFailed
|
||||
C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm --needed -S $mingwPackages" ; exitIfFailed
|
||||
|
@ -65,14 +68,14 @@ elseif ($compiler -eq 'MSVC') {
|
|||
}
|
||||
|
||||
# Setup python (use AppVeyor system python)
|
||||
C:\Python27\python.exe -m pip install neovim ; exitIfFailed
|
||||
C:\Python35\python.exe -m pip install neovim ; exitIfFailed
|
||||
C:\Python27\python.exe -m pip install pynvim ; exitIfFailed
|
||||
C:\Python35\python.exe -m pip install pynvim ; exitIfFailed
|
||||
# Disambiguate python3
|
||||
move c:\Python35\python.exe c:\Python35\python3.exe
|
||||
$env:PATH = "C:\Python35;C:\Python27;$env:PATH"
|
||||
# Sanity check
|
||||
python -c "import neovim; print(str(neovim))" ; exitIfFailed
|
||||
python3 -c "import neovim; print(str(neovim))" ; exitIfFailed
|
||||
python -c "import pynvim; print(str(pynvim))" ; exitIfFailed
|
||||
python3 -c "import pynvim; print(str(pynvim))" ; exitIfFailed
|
||||
|
||||
$env:PATH = "C:\Ruby24\bin;$env:PATH"
|
||||
gem.cmd install neovim
|
||||
|
|
|
@ -83,7 +83,7 @@ valgrind_check() {
|
|||
|
||||
asan_check() {
|
||||
if test "${CLANG_SANITIZER}" = "ASAN_UBSAN" ; then
|
||||
check_logs "${1}" "*san.*" | asan_symbolize
|
||||
check_logs "${1}" "*san.*" | $ASAN_SYMBOLIZE
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,6 @@ if [[ "${CI_TARGET}" == lint ]]; then
|
|||
fi
|
||||
|
||||
if [[ "${TRAVIS_OS_NAME}" == osx ]]; then
|
||||
brew install ninja
|
||||
brew install gettext
|
||||
brew reinstall -s libtool
|
||||
brew install ccache
|
||||
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
fi
|
||||
|
||||
|
@ -26,11 +22,11 @@ if ! [ "${TRAVIS_OS_NAME}" = osx ] ; then
|
|||
# Use default CC to avoid compilation problems when installing Python modules.
|
||||
echo "Install neovim module for Python 2."
|
||||
CC=cc python2.7 -m pip -q install --user --upgrade neovim
|
||||
|
||||
echo "Install neovim RubyGem."
|
||||
gem install --no-document --version ">= 0.2.0" neovim
|
||||
fi
|
||||
|
||||
echo "Install neovim RubyGem."
|
||||
gem install --no-document --version ">= 0.8.0" neovim
|
||||
|
||||
echo "Install neovim npm package"
|
||||
npm install -g neovim
|
||||
npm link neovim
|
||||
|
|
|
@ -38,7 +38,10 @@ set(ENV{SYSTEM_NAME} ${SYSTEM_NAME})
|
|||
execute_process(
|
||||
COMMAND ${BUSTED_PRG} ${TEST_TAG} ${TEST_FILTER} -v -o ${BUSTED_OUTPUT_TYPE}
|
||||
--lua=${LUA_PRG} --lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua
|
||||
--lpath=${BUILD_DIR}/?.lua --lpath=?.lua ${TEST_PATH}
|
||||
--lpath=${BUILD_DIR}/?.lua
|
||||
--lpath=${WORKING_DIR}/runtime/lua/?.lua
|
||||
--lpath=?.lua
|
||||
${TEST_PATH}
|
||||
WORKING_DIRECTORY ${WORKING_DIR}
|
||||
ERROR_VARIABLE err
|
||||
RESULT_VARIABLE res
|
||||
|
|
|
@ -13,7 +13,9 @@ coverage:
|
|||
|
||||
status:
|
||||
project: yes
|
||||
patch: yes
|
||||
patch:
|
||||
default:
|
||||
threshold: 1
|
||||
changes: no
|
||||
|
||||
parsers:
|
||||
|
|
37
man/nvim.1
37
man/nvim.1
|
@ -20,10 +20,21 @@
|
|||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a text editor based on Vim.
|
||||
Commands in this program start with colon
|
||||
Start
|
||||
.Nm
|
||||
followed by any number of options and/or files:
|
||||
.Pp
|
||||
.Dl nvim [options] [file ...]
|
||||
.Pp
|
||||
Commands in
|
||||
.Nm
|
||||
begin with colon
|
||||
.Pq Sq \&: .
|
||||
Use the :help command to get help, for example ":help quickref"
|
||||
is a condensed overview of almost all commands.
|
||||
Type ":help subject" to get help on a specific subject.
|
||||
Use <Tab> and CTRL-D to complete subjects (":help cmdline\-completion").
|
||||
.Pp
|
||||
The "quickref" help section is a condensed reference of editor features:
|
||||
.Dl :help quickref
|
||||
.Pp
|
||||
If you are new to Vim/Nvim, start with the 30-minute tutorial:
|
||||
.Dl :Tutor
|
||||
|
@ -34,28 +45,25 @@ After installing/updating Nvim, it's a good idea to run the self-check:
|
|||
.Bl -tag -width Fl
|
||||
.It Ar file ...
|
||||
File(s) to edit.
|
||||
If none are specified, open an empty buffer.
|
||||
If multiple files are specified, open one buffer for each file.
|
||||
Opens one buffer per file.
|
||||
To switch between buffers, use the
|
||||
.Ic :next
|
||||
and
|
||||
.Ic :previous
|
||||
commands.
|
||||
.It Fl
|
||||
Read text from standard input until
|
||||
Reads text from standard input until
|
||||
.Dv EOF ,
|
||||
then open a buffer with that text.
|
||||
then opens a buffer with that text.
|
||||
User input is read from standard error, which should be a terminal.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width Fl
|
||||
.It Fl t Ar tag
|
||||
The file to edit and the initial cursor position depends on a
|
||||
tag, a sort of goto label.
|
||||
Finds
|
||||
.Ar tag
|
||||
is looked up in the tags file, the associated file becomes the current
|
||||
in the tags file, the associated file becomes the current
|
||||
file and the associated command is executed.
|
||||
If
|
||||
.Ar tag
|
||||
is a function name, the file containing that function is opened
|
||||
with the cursor positioned at the start of the function.
|
||||
Cursor is positioned at the tag location in the file.
|
||||
.Ic ":help tag-commands"
|
||||
.It Fl q Op Ar errorfile
|
||||
QuickFix mode.
|
||||
|
@ -69,7 +77,6 @@ Further errors can be jumped to with the
|
|||
.Ic :cnext
|
||||
command.
|
||||
.Ic ":help quickfix"
|
||||
.It There are a number of other options:
|
||||
.It Fl -
|
||||
End of options.
|
||||
Remaining arguments are treated as literal file names, including filenames starting with hyphen
|
||||
|
|
|
@ -68,9 +68,9 @@ foreach(DF ${DOCFILES})
|
|||
endforeach()
|
||||
|
||||
add_custom_target(helptags
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${GENERATED_RUNTIME_DIR}/doc/*
|
||||
COMMAND ${CMAKE_COMMAND} -E remove doc/*
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${PROJECT_SOURCE_DIR}/runtime/doc ${GENERATED_RUNTIME_DIR}/doc
|
||||
${PROJECT_SOURCE_DIR}/runtime/doc doc
|
||||
COMMAND "${PROJECT_BINARY_DIR}/bin/nvim"
|
||||
-u NONE -i NONE -e --headless -c "helptags ++t doc" -c quit
|
||||
DEPENDS
|
||||
|
@ -87,7 +87,7 @@ add_custom_command(OUTPUT ${GENERATED_HELP_TAGS}
|
|||
add_custom_target(doc_html
|
||||
COMMAND make html
|
||||
DEPENDS
|
||||
${GENERATED_HELP_TAGS}
|
||||
helptags
|
||||
WORKING_DIRECTORY "${GENERATED_RUNTIME_DIR}/doc"
|
||||
)
|
||||
|
||||
|
|
|
@ -152,10 +152,10 @@ function! s:check_clipboard() abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
" Get the latest Neovim Python client version from PyPI.
|
||||
" Get the latest Neovim Python client (pynvim) version from PyPI.
|
||||
function! s:latest_pypi_version() abort
|
||||
let pypi_version = 'unable to get pypi response'
|
||||
let pypi_response = s:download('https://pypi.python.org/pypi/neovim/json')
|
||||
let pypi_response = s:download('https://pypi.python.org/pypi/pynvim/json')
|
||||
if !empty(pypi_response)
|
||||
try
|
||||
let pypi_data = json_decode(pypi_response)
|
||||
|
@ -192,9 +192,9 @@ function! s:version_info(python) abort
|
|||
let nvim_path = s:trim(s:system([
|
||||
\ a:python, '-c',
|
||||
\ 'import sys; sys.path.remove(""); ' .
|
||||
\ 'import neovim; print(neovim.__file__)']))
|
||||
\ 'import pynvim; print(pynvim.__file__)']))
|
||||
if s:shell_error || empty(nvim_path)
|
||||
return [python_version, 'unable to load neovim Python module', pypi_version,
|
||||
return [python_version, 'unable to load pynvim Python module', pypi_version,
|
||||
\ nvim_path]
|
||||
endif
|
||||
|
||||
|
@ -206,13 +206,13 @@ function! s:version_info(python) abort
|
|||
return a == b ? 0 : a > b ? 1 : -1
|
||||
endfunction
|
||||
|
||||
" Try to get neovim.VERSION (added in 0.1.11dev).
|
||||
" Try to get pynvim.VERSION (added in 0.1.11dev).
|
||||
let nvim_version = s:system([a:python, '-c',
|
||||
\ 'from neovim import VERSION as v; '.
|
||||
\ 'from pynvim import VERSION as v; '.
|
||||
\ 'print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))'],
|
||||
\ '', 1, 1)
|
||||
if empty(nvim_version)
|
||||
let nvim_version = 'unable to find neovim Python module version'
|
||||
let nvim_version = 'unable to find pynvim Python module version'
|
||||
let base = fnamemodify(nvim_path, ':h')
|
||||
let metas = glob(base.'-*/METADATA', 1, 1)
|
||||
\ + glob(base.'-*/PKG-INFO', 1, 1)
|
||||
|
@ -293,7 +293,7 @@ function! s:check_python(version) abort
|
|||
|
||||
let [pyname, pythonx_errs] = provider#pythonx#Detect(a:version)
|
||||
if empty(pyname)
|
||||
call health#report_warn('No Python interpreter was found with the neovim '
|
||||
call health#report_warn('No Python interpreter was found with the pynvim '
|
||||
\ . 'module. Using the first available for diagnostics.')
|
||||
elseif exists('g:'.host_prog_var)
|
||||
let python_bin = pyname
|
||||
|
@ -352,7 +352,7 @@ function! s:check_python(version) abort
|
|||
call health#report_warn('pyenv is not set up optimally.', [
|
||||
\ printf('Create a virtualenv specifically '
|
||||
\ . 'for Neovim using pyenv, and set `g:%s`. This will avoid '
|
||||
\ . 'the need to install the Neovim Python module in each '
|
||||
\ . 'the need to install the pynvim module in each '
|
||||
\ . 'version/virtualenv.', host_prog_var)
|
||||
\ ])
|
||||
elseif !empty(venv)
|
||||
|
@ -366,7 +366,7 @@ function! s:check_python(version) abort
|
|||
call health#report_warn('Your virtualenv is not set up optimally.', [
|
||||
\ printf('Create a virtualenv specifically '
|
||||
\ . 'for Neovim and use `g:%s`. This will avoid '
|
||||
\ . 'the need to install Neovim''s Python module in each '
|
||||
\ . 'the need to install the pynvim module in each '
|
||||
\ . 'virtualenv.', host_prog_var)
|
||||
\ ])
|
||||
endif
|
||||
|
@ -400,6 +400,8 @@ function! s:check_python(version) abort
|
|||
endfor
|
||||
endif
|
||||
|
||||
let pip = 'pip' . (a:version == 2 ? '' : '3')
|
||||
|
||||
if !empty(python_bin)
|
||||
let [pyversion, current, latest, status] = s:version_info(python_bin)
|
||||
if a:version != str2nr(pyversion)
|
||||
|
@ -410,28 +412,35 @@ function! s:check_python(version) abort
|
|||
call health#report_warn('Python 3.3+ is recommended.')
|
||||
endif
|
||||
|
||||
call health#report_info('Python'.a:version.' version: ' . pyversion)
|
||||
call health#report_info('Python version: ' . pyversion)
|
||||
if s:is_bad_response(status)
|
||||
call health#report_info(printf('%s-neovim version: %s (%s)', pyname, current, status))
|
||||
call health#report_info(printf('pynvim version: %s (%s)', current, status))
|
||||
else
|
||||
call health#report_info(printf('%s-neovim version: %s', pyname, current))
|
||||
call health#report_info(printf('pynvim version: %s', current))
|
||||
let [module_found, _msg] = provider#pythonx#CheckForModule(python_bin,
|
||||
\ 'neovim', a:version)
|
||||
if !module_found
|
||||
call health#report_error('Importing "neovim" failed.',
|
||||
\ "Reinstall \"pynvim\" and optionally \"neovim\" packages.\n" .
|
||||
\ pip ." uninstall pynvim neovim\n" .
|
||||
\ pip ." install pynvim\n" .
|
||||
\ pip ." install neovim # only if needed by third-party software")
|
||||
endif
|
||||
endif
|
||||
|
||||
if s:is_bad_response(current)
|
||||
call health#report_error(
|
||||
\ "Neovim Python client is not installed.\nError: ".current,
|
||||
\ ['Run in shell: pip' . a:version . ' install neovim'])
|
||||
\ "pynvim is not installed.\nError: ".current,
|
||||
\ ['Run in shell: '. pip .' install pynvim'])
|
||||
endif
|
||||
|
||||
if s:is_bad_response(latest)
|
||||
call health#report_warn('Could not contact PyPI to get latest version.')
|
||||
call health#report_error('HTTP request failed: '.latest)
|
||||
elseif s:is_bad_response(status)
|
||||
call health#report_warn(printf('Latest %s-neovim is NOT installed: %s',
|
||||
\ pyname, latest))
|
||||
call health#report_warn(printf('Latest pynvim is NOT installed: %s', latest))
|
||||
elseif !s:is_bad_response(current)
|
||||
call health#report_ok(printf('Latest %s-neovim is installed: %s',
|
||||
\ pyname, latest))
|
||||
call health#report_ok(printf('Latest pynvim is installed.'))
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ function! provider#clipboard#Executable() abort
|
|||
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)
|
||||
|
@ -71,18 +72,24 @@ function! provider#clipboard#Executable() abort
|
|||
let s:paste['*'] = s:paste['+']
|
||||
let s:cache_enabled = 0
|
||||
return 'pbcopy'
|
||||
elseif exists('$DISPLAY') && executable('xsel') && s:cmd_ok('xsel -o -b')
|
||||
let s:copy['+'] = 'xsel --nodetach -i -b'
|
||||
let s:paste['+'] = 'xsel -o -b'
|
||||
let s:copy['*'] = 'xsel --nodetach -i -p'
|
||||
let s:paste['*'] = 'xsel -o -p'
|
||||
return 'xsel'
|
||||
elseif exists('$WAYLAND_DISPLAY') && executable('wl-copy') && executable('wl-paste')
|
||||
let s:copy['+'] = 'wl-copy --foreground'
|
||||
let s:paste['+'] = 'wl-paste --no-newline'
|
||||
let s:copy['*'] = 'wl-copy --foreground --primary'
|
||||
let s:paste['*'] = 'wl-paste --no-newline --primary'
|
||||
return 'wl-copy'
|
||||
elseif exists('$DISPLAY') && executable('xclip')
|
||||
let s:copy['+'] = 'xclip -quiet -i -selection clipboard'
|
||||
let s:paste['+'] = 'xclip -o -selection clipboard'
|
||||
let s:copy['*'] = 'xclip -quiet -i -selection primary'
|
||||
let s:paste['*'] = 'xclip -o -selection primary'
|
||||
return 'xclip'
|
||||
elseif exists('$DISPLAY') && executable('xsel') && s:cmd_ok('xsel -o -b')
|
||||
let s:copy['+'] = 'xsel --nodetach -i -b'
|
||||
let s:paste['+'] = 'xsel -o -b'
|
||||
let s:copy['*'] = 'xsel --nodetach -i -p'
|
||||
let s:paste['*'] = 'xsel -o -p'
|
||||
return 'xsel'
|
||||
elseif executable('lemonade')
|
||||
let s:copy['+'] = 'lemonade copy'
|
||||
let s:paste['+'] = 'lemonade paste'
|
||||
|
@ -95,9 +102,9 @@ function! provider#clipboard#Executable() abort
|
|||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'doitclient'
|
||||
elseif executable('win32yank')
|
||||
let s:copy['+'] = 'win32yank -i --crlf'
|
||||
let s:paste['+'] = 'win32yank -o --lf'
|
||||
elseif executable('win32yank.exe')
|
||||
let s:copy['+'] = 'win32yank.exe -i --crlf'
|
||||
let s:paste['+'] = 'win32yank.exe -o --lf'
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'win32yank'
|
||||
|
@ -121,7 +128,9 @@ if empty(provider#clipboard#Executable())
|
|||
endif
|
||||
|
||||
function! s:clipboard.get(reg) abort
|
||||
if s:selections[a:reg].owner > 0
|
||||
if type(s:paste[a:reg]) == v:t_func
|
||||
return s:paste[a:reg]()
|
||||
elseif s:selections[a:reg].owner > 0
|
||||
return s:selections[a:reg].data
|
||||
end
|
||||
return s:try_cmd(s:paste[a:reg])
|
||||
|
@ -135,6 +144,12 @@ function! s:clipboard.set(lines, regtype, reg) abort
|
|||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
if type(s:copy[a:reg]) == v:t_func
|
||||
call s:copy[a:reg](a:lines, a:regtype)
|
||||
return 0
|
||||
end
|
||||
|
||||
if s:cache_enabled == 0
|
||||
call s:try_cmd(s:copy[a:reg], a:lines)
|
||||
return 0
|
||||
|
|
|
@ -49,7 +49,7 @@ endfunction
|
|||
|
||||
function! provider#node#Detect() abort
|
||||
if exists('g:node_host_prog')
|
||||
return g:node_host_prog
|
||||
return expand(g:node_host_prog)
|
||||
endif
|
||||
if !s:is_minimum_version(v:null, 6, 0)
|
||||
return ''
|
||||
|
|
|
@ -10,7 +10,7 @@ function! provider#pythonx#Require(host) abort
|
|||
|
||||
" Python host arguments
|
||||
let prog = (ver == '2' ? provider#python#Prog() : provider#python3#Prog())
|
||||
let args = [prog, '-c', 'import sys; sys.path.remove(""); import neovim; neovim.start_host()']
|
||||
let args = [prog, '-c', 'import sys; sys.path.remove(""); import pynvim; pynvim.start_host()']
|
||||
|
||||
" Collect registered Python plugins into args
|
||||
let python_plugins = remote#host#PluginsForHost(a:host.name)
|
||||
|
@ -24,13 +24,13 @@ endfunction
|
|||
function! provider#pythonx#Detect(major_ver) abort
|
||||
if a:major_ver == 2
|
||||
if exists('g:python_host_prog')
|
||||
return [g:python_host_prog, '']
|
||||
return [expand(g:python_host_prog), '']
|
||||
else
|
||||
let progs = ['python2', 'python2.7', 'python2.6', 'python']
|
||||
endif
|
||||
else
|
||||
if exists('g:python3_host_prog')
|
||||
return [g:python3_host_prog, '']
|
||||
return [expand(g:python3_host_prog), '']
|
||||
else
|
||||
let progs = ['python3', 'python3.7', 'python3.6', 'python3.5',
|
||||
\ 'python3.4', 'python3.3', 'python']
|
||||
|
@ -40,7 +40,7 @@ function! provider#pythonx#Detect(major_ver) abort
|
|||
let errors = []
|
||||
|
||||
for prog in progs
|
||||
let [result, err] = s:check_interpreter(prog, a:major_ver)
|
||||
let [result, err] = provider#pythonx#CheckForModule(prog, 'pynvim', a:major_ver)
|
||||
if result
|
||||
return [prog, err]
|
||||
endif
|
||||
|
@ -54,46 +54,53 @@ function! provider#pythonx#Detect(major_ver) abort
|
|||
\ . ":\n" . join(errors, "\n")]
|
||||
endfunction
|
||||
|
||||
function! s:check_interpreter(prog, major_ver) abort
|
||||
" Returns array: [prog_exitcode, prog_version]
|
||||
function! s:import_module(prog, module) abort
|
||||
let prog_version = system([a:prog, '-c' , printf(
|
||||
\ 'import sys; ' .
|
||||
\ 'sys.path.remove(""); ' .
|
||||
\ 'sys.stdout.write(str(sys.version_info[0]) + "." + str(sys.version_info[1])); ' .
|
||||
\ 'import pkgutil; ' .
|
||||
\ 'exit(2*int(pkgutil.get_loader("%s") is None))',
|
||||
\ a:module)])
|
||||
return [v:shell_error, prog_version]
|
||||
endfunction
|
||||
|
||||
" Returns array: [was_success, error_message]
|
||||
function! provider#pythonx#CheckForModule(prog, module, major_version) abort
|
||||
let prog_path = exepath(a:prog)
|
||||
if prog_path ==# ''
|
||||
return [0, a:prog . ' not found in search path or not executable.']
|
||||
endif
|
||||
|
||||
let min_version = (a:major_ver == 2) ? '2.6' : '3.3'
|
||||
let min_version = (a:major_version == 2) ? '2.6' : '3.3'
|
||||
|
||||
" Try to load neovim module, and output Python version.
|
||||
" Return codes:
|
||||
" 0 Neovim module can be loaded.
|
||||
" 2 Neovim module cannot be loaded.
|
||||
" Try to load pynvim module, and output Python version.
|
||||
" Exit codes:
|
||||
" 0 pynvim module can be loaded.
|
||||
" 2 pynvim module cannot be loaded.
|
||||
" Otherwise something else went wrong (e.g. 1 or 127).
|
||||
let prog_ver = system([ a:prog , '-c' ,
|
||||
\ 'import sys; ' .
|
||||
\ 'sys.path.remove(""); ' .
|
||||
\ 'sys.stdout.write(str(sys.version_info[0]) + "." + str(sys.version_info[1])); ' .
|
||||
\ 'import pkgutil; ' .
|
||||
\ 'exit(2*int(pkgutil.get_loader("neovim") is None))'
|
||||
\ ])
|
||||
let [prog_exitcode, prog_version] = s:import_module(a:prog, 'pynvim')
|
||||
|
||||
if v:shell_error == 2 || v:shell_error == 0
|
||||
if prog_exitcode == 2 || prog_exitcode == 0
|
||||
" Check version only for expected return codes.
|
||||
if prog_ver !~ '^' . a:major_ver
|
||||
return [0, prog_path . ' is Python ' . prog_ver . ' and cannot provide Python '
|
||||
\ . a:major_ver . '.']
|
||||
elseif prog_ver =~ '^' . a:major_ver && prog_ver < min_version
|
||||
return [0, prog_path . ' is Python ' . prog_ver . ' and cannot provide Python >= '
|
||||
if prog_version !~ '^' . a:major_version
|
||||
return [0, prog_path . ' is Python ' . prog_version . ' and cannot provide Python '
|
||||
\ . a:major_version . '.']
|
||||
elseif prog_version =~ '^' . a:major_version && prog_version < min_version
|
||||
return [0, prog_path . ' is Python ' . prog_version . ' and cannot provide Python >= '
|
||||
\ . min_version . '.']
|
||||
endif
|
||||
endif
|
||||
|
||||
if v:shell_error == 2
|
||||
return [0, prog_path.' does not have the "neovim" module. :help provider-python']
|
||||
elseif v:shell_error == 127
|
||||
if prog_exitcode == 2
|
||||
return [0, prog_path.' does not have the "pynvim" module. :help provider-python']
|
||||
elseif prog_exitcode == 127
|
||||
" This can happen with pyenv's shims.
|
||||
return [0, prog_path . ' does not exist: ' . prog_ver]
|
||||
elseif v:shell_error
|
||||
return [0, prog_path . ' does not exist: ' . prog_version]
|
||||
elseif prog_exitcode
|
||||
return [0, 'Checking ' . prog_path . ' caused an unknown error. '
|
||||
\ . '(' . v:shell_error . ', output: ' . prog_ver . ')'
|
||||
\ . '(' . prog_exitcode . ', output: ' . prog_version . ')'
|
||||
\ . ' Report this at https://github.com/neovim/neovim']
|
||||
endif
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ endfunction
|
|||
|
||||
function! s:detect()
|
||||
if exists("g:ruby_host_prog")
|
||||
return g:ruby_host_prog
|
||||
return expand(g:ruby_host_prog)
|
||||
elseif has('win32')
|
||||
return exepath('neovim-ruby-host.bat')
|
||||
else
|
||||
|
|
|
@ -153,15 +153,14 @@ fun! tar#Browse(tarfile)
|
|||
let tarfile=substitute(system("cygpath -u ".shellescape(tarfile,0)),'\n$','','e')
|
||||
endif
|
||||
|
||||
let gzip_command = s:get_gzip_command(tarfile)
|
||||
|
||||
let curlast= line("$")
|
||||
if tarfile =~# '\.\(gz\|tgz\)$'
|
||||
let gzip_command = s:get_gzip_command(tarfile)
|
||||
" call Decho("1: exe silent r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ")
|
||||
exe "sil! r! " . gzip_command . " -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
elseif tarfile =~# '\.lrp'
|
||||
" call Decho("2: exe silent r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - ")
|
||||
exe "sil! r! cat -- ".shellescape(tarfile,1)."|" . gzip_command . " -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
exe "sil! r! cat -- ".shellescape(tarfile,1)."|gzip -d -c -|".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
elseif tarfile =~# '\.\(bz2\|tbz\|tb2\)$'
|
||||
" call Decho("3: exe silent r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - ")
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
|
@ -291,17 +290,16 @@ fun! tar#Read(fname,mode)
|
|||
let tar_secure= " "
|
||||
endif
|
||||
|
||||
let gzip_command = s:get_gzip_command(tarfile)
|
||||
|
||||
if tarfile =~# '\.bz2$'
|
||||
" call Decho("7: exe silent r! bzip2 -d -c ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp)
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
elseif tarfile =~# '\.\(gz\|tgz\)$'
|
||||
let gzip_command = s:get_gzip_command(tarfile)
|
||||
" call Decho("5: exe silent r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd.' -'.g:tar_readoptions.' - '.tar_secure.shellescape(fname,1))
|
||||
exe "sil! r! " . gzip_command . " -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
elseif tarfile =~# '\.lrp$'
|
||||
" call Decho("6: exe silent r! cat ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp)
|
||||
exe "sil! r! cat -- ".shellescape(tarfile,1)." | " . gzip_command . " -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
elseif tarfile =~# '\.lzma$'
|
||||
" call Decho("7: exe silent r! lzma -d -c ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp)
|
||||
exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
|
@ -589,8 +587,9 @@ fun! tar#Vimuntar(...)
|
|||
|
||||
" if necessary, decompress the tarball; then, extract it
|
||||
if tartail =~ '\.tgz'
|
||||
if executable("bzip2")
|
||||
silent exe "!bzip2 -d ".shellescape(tartail)
|
||||
let gzip_command = s:get_gzip_command(tarfile)
|
||||
if executable(gzip_command)
|
||||
silent exe "!" . gzip_command . " -d ".shellescape(tartail)
|
||||
elseif executable("gunzip")
|
||||
silent exe "!gunzip ".shellescape(tartail)
|
||||
elseif executable("gzip")
|
||||
|
@ -630,11 +629,24 @@ fun! tar#Vimuntar(...)
|
|||
endfun
|
||||
|
||||
func s:get_gzip_command(file)
|
||||
if a:file =~# 'z$' && executable('bzip2')
|
||||
" Some .tgz files are actually compressed with bzip2. Since bzip2 can
|
||||
" handle the format from gzip, use it if the command exists.
|
||||
" Try using the "file" command to get the actual compression type, since
|
||||
" there is no standard way for the naming: ".tgz", ".tbz", ".txz", etc.
|
||||
" If the "file" command doesn't work fall back to just using the file name.
|
||||
if a:file =~# 'z$'
|
||||
let filetype = system('file ' . a:file)
|
||||
if filetype =~ 'bzip2 compressed' && executable('bzip2')
|
||||
return 'bzip2'
|
||||
endif
|
||||
if filetype =~ 'XZ compressed' && executable('xz')
|
||||
return 'xz'
|
||||
endif
|
||||
endif
|
||||
if a:file =~# 'bz2$'
|
||||
return 'bzip2'
|
||||
endif
|
||||
if a:file =~# 'xz$'
|
||||
return 'xz'
|
||||
endif
|
||||
return 'gzip'
|
||||
endfunc
|
||||
|
||||
|
|
|
@ -79,6 +79,19 @@ As Nvim evolves the API may change in compliance with this CONTRACT:
|
|||
- Existing items will not be removed (after release).
|
||||
- Deprecated functions will not be removed until Nvim version 2.0
|
||||
|
||||
==============================================================================
|
||||
Global events *api-global-events*
|
||||
|
||||
When a client invokes an API request as an async notification, it is not
|
||||
possible for Nvim to send an error response. Instead, in case of error, the
|
||||
following notification will be sent to the client:
|
||||
|
||||
*nvim_error_event*
|
||||
nvim_error_event[{type}, {message}]
|
||||
|
||||
{type} is a numeric id as defined by `api_info().error_types`, and {message} is
|
||||
a string with the error message.
|
||||
|
||||
==============================================================================
|
||||
Buffer update events *api-buffer-updates*
|
||||
|
||||
|
@ -97,7 +110,7 @@ nvim_buf_lines_event[{buf}, {changedtick}, {firstline}, {lastline}, {linedata},
|
|||
|
||||
When {changedtick} is |v:null| this means the screen lines (display) changed
|
||||
but not the buffer contents. {linedata} contains the changed screen lines.
|
||||
This happens when |inccommand| shows a buffer preview.
|
||||
This happens when 'inccommand' shows a buffer preview.
|
||||
|
||||
Properties:~
|
||||
{buf} API buffer handle (buffer number)
|
||||
|
@ -138,7 +151,7 @@ nvim_buf_changedtick_event[{buf}, {changedtick}] *nvim_buf_changedtick_event*
|
|||
nvim_buf_detach_event[{buf}] *nvim_buf_detach_event*
|
||||
|
||||
When buffer is detached (i.e. updates are disabled). Triggered explicitly by
|
||||
|nvim_buf_detach| or implicitly in these cases:
|
||||
|nvim_buf_detach()| or implicitly in these cases:
|
||||
- Buffer was |abandon|ed and 'hidden' is not set.
|
||||
- Buffer was reloaded, e.g. with |:edit| or an external change triggered
|
||||
|:checktime| or 'autoread'.
|
||||
|
@ -206,7 +219,7 @@ Example using the Nvim python-client:
|
|||
buf.clear_highlight(src)
|
||||
<
|
||||
If the highlights don't need to be deleted or updated, just pass -1 as
|
||||
src_id (this is the default in python). Use |nvim_buf_clear_highlight()| to
|
||||
src_id (this is the default in python). Use |nvim_buf_clear_namespace()| to
|
||||
clear highlights from a specific source, in a specific line range or the
|
||||
entire buffer by passing in the line range 0, -1 (the latter is the default in
|
||||
python as used above).
|
||||
|
@ -218,7 +231,7 @@ An example of calling the api from vimscript: >
|
|||
call nvim_buf_add_highlight(0, src, "Identifier", 0, 5, -1)
|
||||
|
||||
" later
|
||||
call nvim_buf_clear_highlight(0, src, 0, -1)
|
||||
call nvim_buf_clear_namespace(0, src, 0, -1)
|
||||
>
|
||||
==============================================================================
|
||||
Global Functions *api-global*
|
||||
|
@ -478,6 +491,9 @@ nvim_err_writeln({str}) *nvim_err_writeln()*
|
|||
nvim_list_bufs() *nvim_list_bufs()*
|
||||
Gets the current list of buffer handles
|
||||
|
||||
Includes unlisted (unloaded/deleted) buffers, like `:ls!`. Use
|
||||
|nvim_buf_is_loaded()| to check if a buffer is loaded.
|
||||
|
||||
Return: ~
|
||||
List of buffer handles
|
||||
|
||||
|
@ -529,6 +545,30 @@ nvim_set_current_tabpage({tabpage}) *nvim_set_current_tabpage()*
|
|||
Parameters: ~
|
||||
{tabpage} Tabpage handle
|
||||
|
||||
nvim_create_namespace({name}) *nvim_create_namespace()*
|
||||
create a new namespace, or get one with an exisiting name
|
||||
|
||||
Namespaces are currently used for buffer highlighting and
|
||||
virtual text, see |nvim_buf_add_highlight| and
|
||||
|nvim_buf_set_virtual_text|.
|
||||
|
||||
Namespaces can have a name of be anonymous. If `name` is a
|
||||
non-empty string, and a namespace already exists with that
|
||||
name,the existing namespace id is returned. If an empty string
|
||||
is used, a new anonymous namespace is returned.
|
||||
|
||||
Parameters: ~
|
||||
{name} Name of the namespace or empty string
|
||||
|
||||
Return: ~
|
||||
the namespace id
|
||||
|
||||
nvim_get_namespaces() *nvim_get_namespaces()*
|
||||
Get existing named namespaces
|
||||
|
||||
Return: ~
|
||||
dict that maps from names to namespace ids.
|
||||
|
||||
nvim_subscribe({event}) *nvim_subscribe()*
|
||||
Subscribes to event broadcasts
|
||||
|
||||
|
@ -638,7 +678,7 @@ nvim_set_client_info({name}, {version}, {type}, {methods},
|
|||
Clients might define their own keys, but the
|
||||
following are suggested: "website" Website
|
||||
of client (for instance github repository)
|
||||
"license" Informal descripton of the
|
||||
"license" Informal description of the
|
||||
license, such as "Apache 2", "GPLv3" or
|
||||
"MIT" "logo" URI or path to image,
|
||||
preferably small logo or icon. .png or .svg
|
||||
|
@ -862,8 +902,7 @@ nvim_buf_line_count({buffer}) *nvim_buf_line_count()*
|
|||
{buffer} Buffer handle
|
||||
|
||||
Return: ~
|
||||
Line count, or `0` if the buffer has been unloaded (see
|
||||
|api-buffer|).
|
||||
Line count, or 0 for unloaded buffer. |api-buffer|
|
||||
|
||||
nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()*
|
||||
Activate updates from this buffer to the current channel.
|
||||
|
@ -912,8 +951,7 @@ nvim_buf_get_lines({buffer}, {start}, {end}, {strict_indexing})
|
|||
error.
|
||||
|
||||
Return: ~
|
||||
Array of lines. If the buffer has been unloaded then an
|
||||
empty array will be returned instead. (See |api-buffer|.)
|
||||
Array of lines, or empty array for unloaded buffer.
|
||||
|
||||
*nvim_buf_set_lines()*
|
||||
nvim_buf_set_lines({buffer}, {start}, {end}, {strict_indexing},
|
||||
|
@ -940,6 +978,25 @@ nvim_buf_set_lines({buffer}, {start}, {end}, {strict_indexing},
|
|||
error.
|
||||
{replacement} Array of lines to use as replacement
|
||||
|
||||
nvim_buf_get_offset({buffer}, {index}) *nvim_buf_get_offset()*
|
||||
Returns the byte offset for a line.
|
||||
|
||||
Line 1 (index=0) has offset 0. UTF-8 bytes are counted. EOL is
|
||||
one byte. 'fileformat' and 'fileencoding' are ignored. The
|
||||
line index just after the last line gives the total byte-count
|
||||
of the buffer. A final EOL byte is counted if it would be
|
||||
written, see 'eol'.
|
||||
|
||||
Unlike |line2byte()|, throws error for out-of-bounds indexing.
|
||||
Returns -1 for unloaded buffer.
|
||||
|
||||
Parameters: ~
|
||||
{buffer} Buffer handle
|
||||
{index} Line index
|
||||
|
||||
Return: ~
|
||||
Integer byte offset, or -1 for unloaded buffer.
|
||||
|
||||
nvim_buf_get_var({buffer}, {name}) *nvim_buf_get_var()*
|
||||
Gets a buffer-scoped (b:) variable.
|
||||
|
||||
|
@ -1065,35 +1122,36 @@ nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()*
|
|||
(row, col) tuple
|
||||
|
||||
*nvim_buf_add_highlight()*
|
||||
nvim_buf_add_highlight({buffer}, {src_id}, {hl_group}, {line},
|
||||
nvim_buf_add_highlight({buffer}, {ns_id}, {hl_group}, {line},
|
||||
{col_start}, {col_end})
|
||||
Adds a highlight to buffer.
|
||||
|
||||
Useful for plugins that dynamically generate highlights to a
|
||||
buffer (like a semantic highlighter or linter). The function
|
||||
adds a single highlight to a buffer. Unlike matchaddpos()
|
||||
adds a single highlight to a buffer. Unlike |matchaddpos()|
|
||||
highlights follow changes to line numbering (as lines are
|
||||
inserted/removed above the highlighted line), like signs and
|
||||
marks do.
|
||||
|
||||
`src_id` is useful for batch deletion/updating of a set of
|
||||
highlights. When called with `src_id = 0`, an unique source id
|
||||
is generated and returned. Successive calls can pass that
|
||||
`src_id` to associate new highlights with the same source
|
||||
group. All highlights in the same group can be cleared with
|
||||
`nvim_buf_clear_highlight`. If the highlight never will be
|
||||
manually deleted, pass `src_id = -1`.
|
||||
Namespaces are used for batch deletion/updating of a set of
|
||||
highlights. To create a namespace, use |nvim_create_namespace|
|
||||
which returns a namespace id. Pass it in to this function as
|
||||
`ns_id` to add highlights to the namespace. All highlights in
|
||||
the same namespace can then be cleared with single call to
|
||||
|nvim_buf_clear_namespace|. If the highlight never will be
|
||||
deleted by an API call, pass `ns_id = -1`.
|
||||
|
||||
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
|
||||
plugin to synchrounously request an unique `src_id` at
|
||||
initialization, and later asynchronously add and clear
|
||||
highlights in response to buffer changes.
|
||||
As a shorthand, `ns_id = 0` can be used to create a new
|
||||
namespace for the highlight, the allocated id is then
|
||||
returned. If `hl_group` is the empty string no highlight is
|
||||
added, but a new `ns_id` is still returned. This is supported
|
||||
for backwards compatibility, new code should use
|
||||
|nvim_create_namespace| to create a new empty namespace.
|
||||
|
||||
Parameters: ~
|
||||
{buffer} Buffer handle
|
||||
{src_id} Source group to use or 0 to use a new group,
|
||||
or -1 for ungrouped highlight
|
||||
{ns_id} namespace to use or -1 for ungrouped
|
||||
highlight
|
||||
{hl_group} Name of the highlight group to use
|
||||
{line} Line to highlight (zero-indexed)
|
||||
{col_start} Start of (byte-indexed) column range to
|
||||
|
@ -1102,39 +1160,50 @@ nvim_buf_add_highlight({buffer}, {src_id}, {hl_group}, {line},
|
|||
highlight, or -1 to highlight to end of line
|
||||
|
||||
Return: ~
|
||||
The src_id that was used
|
||||
The ns_id that was used
|
||||
|
||||
*nvim_buf_clear_highlight()*
|
||||
nvim_buf_clear_highlight({buffer}, {src_id}, {line_start}, {line_end})
|
||||
Clears highlights from a given source group and a range of
|
||||
lines
|
||||
*nvim_buf_clear_namespace()*
|
||||
nvim_buf_clear_namespace({buffer}, {ns_id}, {line_start}, {line_end})
|
||||
Clears namespaced objects, highlights and virtual text, from a
|
||||
line range
|
||||
|
||||
To clear a source group in the entire buffer, pass in 0 and -1
|
||||
To clear the namespace in the entire buffer, pass in 0 and -1
|
||||
to line_start and line_end respectively.
|
||||
|
||||
Parameters: ~
|
||||
{buffer} Buffer handle
|
||||
{src_id} Highlight source group to clear, or -1 to
|
||||
clear all.
|
||||
{ns_id} Namespace to clear, or -1 to clear all
|
||||
namespaces.
|
||||
{line_start} Start of range of lines to clear
|
||||
{line_end} End of range of lines to clear (exclusive)
|
||||
or -1 to clear to end of file.
|
||||
or -1 to clear to end of buffer.
|
||||
|
||||
*nvim_buf_set_virtual_text()*
|
||||
nvim_buf_set_virtual_text({buffer}, {src_id}, {line}, {chunks},
|
||||
{opts})
|
||||
nvim_buf_set_virtual_text({buffer}, {ns_id}, {line}, {chunks}, {opts})
|
||||
Set the virtual text (annotation) for a buffer line.
|
||||
|
||||
By default (and currently the only option) the text will be
|
||||
placed after the buffer text. Virtual text will never cause
|
||||
reflow, rather virtual text will be truncated at the end of
|
||||
the screen line. The virtual text will begin after one cell to
|
||||
the right of the ordinary text, this will contain the |lcs-
|
||||
eol| char if set, otherwise just be a space.
|
||||
the screen line. The virtual text will begin one cell (|lcs-
|
||||
eol| or space) after the ordinary text.
|
||||
|
||||
Namespaces are used to support batch deletion/updating of
|
||||
virtual text. To create a namespace, use
|
||||
|nvim_create_namespace|. Virtual text is cleared using
|
||||
|nvim_buf_clear_namespace|. The same `ns_id` can be used for
|
||||
both virtual text and highlights added by
|
||||
|nvim_buf_add_highlight|, both can then be cleared with a
|
||||
single call to |nvim_buf_clear_namespace|. If the virtual text
|
||||
never will be cleared by an API call, pass `ns_id = -1`.
|
||||
|
||||
As a shorthand, `ns_id = 0` can be used to create a new
|
||||
namespace for the virtual text, the allocated id is then
|
||||
returned.
|
||||
|
||||
Parameters: ~
|
||||
{buffer} Buffer handle
|
||||
{src_id} Source group to use or 0 to use a new group, or
|
||||
{ns_id} Namespace to use or 0 to create a namespace, or
|
||||
-1 for a ungrouped annotation
|
||||
{line} Line to annotate with virtual text (zero-
|
||||
indexed)
|
||||
|
@ -1145,7 +1214,7 @@ nvim_buf_set_virtual_text({buffer}, {src_id}, {line}, {chunks},
|
|||
{opts} Optional parameters. Currently not used.
|
||||
|
||||
Return: ~
|
||||
The src_id that was used
|
||||
The ns_id that was used
|
||||
|
||||
|
||||
==============================================================================
|
||||
|
@ -1160,6 +1229,13 @@ nvim_win_get_buf({window}) *nvim_win_get_buf()*
|
|||
Return: ~
|
||||
Buffer handle
|
||||
|
||||
nvim_win_set_buf({window}, {buffer}) *nvim_win_set_buf()*
|
||||
Sets the current buffer in a window, without side-effects
|
||||
|
||||
Parameters: ~
|
||||
{window} Window handle
|
||||
{buffer} Buffer handle
|
||||
|
||||
nvim_win_get_cursor({window}) *nvim_win_get_cursor()*
|
||||
Gets the cursor position in the window
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ Name triggered by ~
|
|||
|VimEnter| after doing all the startup stuff
|
||||
|GUIEnter| after starting the GUI successfully
|
||||
|GUIFailed| after starting the GUI failed
|
||||
|TermResponse| after the terminal response to |t_RV| is received
|
||||
|TermResponse| after the terminal response to t_RV is received
|
||||
|QuitPre| when using `:quit`, before deciding whether to exit
|
||||
|ExitPre| when using a command that may make Vim exit
|
||||
|VimLeavePre| before exiting Nvim, before writing the shada file
|
||||
|
@ -521,25 +521,24 @@ CmdUndefined When a user command is used but it isn't
|
|||
command is defined. An alternative is to
|
||||
always define the user command and have it
|
||||
invoke an autoloaded function. See |autoload|.
|
||||
*CmdlineChanged*
|
||||
CmdlineChanged After a change was made to the text in the
|
||||
command line. Be careful not to mess up
|
||||
the command line, it may cause Vim to lock up.
|
||||
*CmdlineChanged*
|
||||
CmdlineChanged After a change was made to the text inside
|
||||
command line. Be careful not to mess up the
|
||||
command line, it may cause Vim to lock up.
|
||||
<afile> is set to the |cmdline-char|.
|
||||
*CmdlineEnter*
|
||||
CmdlineEnter After moving the cursor to the command line,
|
||||
where the user can type a command or search
|
||||
string.
|
||||
<afile> is set to a single character,
|
||||
indicating the type of command-line.
|
||||
|cmdline-char|
|
||||
CmdlineEnter After entering the command-line (including
|
||||
non-interactive use of ":" in a mapping: use
|
||||
|<Cmd>| instead to avoid this).
|
||||
<afile> is set to the |cmdline-char|.
|
||||
Sets these |v:event| keys:
|
||||
cmdlevel
|
||||
cmdtype
|
||||
*CmdlineLeave*
|
||||
CmdlineLeave Before leaving the command line.
|
||||
<afile> is set to a single character,
|
||||
indicating the type of command-line.
|
||||
|cmdline-char|
|
||||
CmdlineLeave Before leaving the command-line (including
|
||||
non-interactive use of ":" in a mapping: use
|
||||
|<Cmd>| instead to avoid this).
|
||||
<afile> is set to the |cmdline-char|.
|
||||
Sets these |v:event| keys:
|
||||
abort (mutable)
|
||||
cmdlevel
|
||||
|
@ -630,6 +629,11 @@ CursorMoved After the cursor was moved in Normal or Visual
|
|||
CursorMovedI After the cursor was moved in Insert mode.
|
||||
Not triggered when the popup menu is visible.
|
||||
Otherwise the same as CursorMoved.
|
||||
*DiffUpdated*
|
||||
DiffUpdated After diffs have been updated. Depending on
|
||||
what kind of diff is being used (internal or
|
||||
external) this can be triggered on every
|
||||
change or when doing |:diffupdate|.
|
||||
*DirChanged*
|
||||
DirChanged After the |current-directory| was changed.
|
||||
Sets these |v:event| keys:
|
||||
|
@ -989,7 +993,7 @@ TermClose When a |terminal| job ends.
|
|||
TermOpen When a |terminal| job is starting. Can be
|
||||
used to configure the terminal buffer.
|
||||
*TermResponse*
|
||||
TermResponse After the response to |t_RV| is received from
|
||||
TermResponse After the response to t_RV is received from
|
||||
the terminal. The value of |v:termresponse|
|
||||
can be used to do things depending on the
|
||||
terminal version. Note that this event may be
|
||||
|
|
|
@ -212,7 +212,7 @@ CTRL-\ e {expr} *c_CTRL-\_e*
|
|||
|
||||
*c_CTRL-Y*
|
||||
CTRL-Y When there is a modeless selection, copy the selection into
|
||||
the clipboard. |modeless-selection|
|
||||
the clipboard.
|
||||
If there is no selection CTRL-Y is inserted as a character.
|
||||
|
||||
CTRL-M or CTRL-J *c_CTRL-M* *c_CTRL-J* *c_<NL>* *c_<CR>* *c_CR*
|
||||
|
|
|
@ -162,12 +162,8 @@ In WinDbg: choose Open Crash Dump on the File menu. Follow the instructions in
|
|||
*get-ms-debuggers*
|
||||
3.5 Obtaining Microsoft Debugging Tools ~
|
||||
|
||||
The Debugging Tools for Windows (including WinDbg) can be downloaded from
|
||||
http://www.microsoft.com/whdc/devtools/debugging/default.mspx
|
||||
This includes the WinDbg debugger.
|
||||
|
||||
Visual C++ 2005 Express Edition can be downloaded for free from:
|
||||
http://msdn.microsoft.com/vstudio/express/visualC/default.aspx
|
||||
Visual Studio 2017 Community Edition can be downloaded for free from:
|
||||
https://visualstudio.microsoft.com/downloads/
|
||||
|
||||
=========================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
|
|
@ -37,15 +37,17 @@ Functions ~
|
|||
*file_readable()* Obsolete name for |filereadable()|.
|
||||
*highlight_exists()* Obsolete name for |hlexists()|.
|
||||
*highlightID()* Obsolete name for |hlID()|.
|
||||
*inputdialog()* Use |input()| instead.
|
||||
*jobclose()* Obsolete name for |chanclose()|
|
||||
*jobsend()* Obsolete name for |chansend()|
|
||||
*last_buffer_nr()* Obsolete name for bufnr("$").
|
||||
|
||||
Modifiers ~
|
||||
*cpo-<*
|
||||
*:menu-<special>*
|
||||
*:menu-special* <> notation is always enabled. |cpo-<|
|
||||
*:menu-special* <> notation is always enabled.
|
||||
*:map-<special>*
|
||||
*:map-special* <> notation is always enabled. |cpo-<|
|
||||
*:map-special* <> notation is always enabled.
|
||||
|
||||
Normal commands ~
|
||||
*]f*
|
||||
|
|
|
@ -6,19 +6,20 @@
|
|||
|
||||
Development of Nvim *development*
|
||||
|
||||
Nvim is open source software. Everybody is encouraged to contribute.
|
||||
https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md
|
||||
This reference describes design constraints and guidelines, for developing
|
||||
Nvim applications or Nvim itself.
|
||||
Architecture and internal concepts are covered in src/nvim/README.md
|
||||
|
||||
See src/nvim/README.md for an overview of the source code.
|
||||
Nvim is free and open source. Everybody is encouraged to contribute.
|
||||
https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
Design goals *design-goals*
|
||||
|
||||
Most important things come first (roughly).
|
||||
|
||||
Note that some items conflict; this is intentional. A balance must be found.
|
||||
Most important things come first (roughly). Some items conflict; this is
|
||||
intentional. A balance must be found.
|
||||
|
||||
|
||||
NVIM IS... IMPROVED *design-improved*
|
||||
|
@ -81,41 +82,6 @@ include the kitchen sink... but it's good for plumbing."
|
|||
Developer guidelines *dev*
|
||||
|
||||
|
||||
JARGON *dev-jargon*
|
||||
|
||||
API client ~
|
||||
All external UIs and remote plugins (as opposed to regular Vim plugins) are
|
||||
"clients" in general; but we call something an "API client" if its purpose is
|
||||
to abstract or wrap the RPC API for the convenience of other applications
|
||||
(just like a REST client or SDK such as boto3 for AWS: you can speak AWS REST
|
||||
using an HTTP client like curl, but boto3 wraps that in a convenient python
|
||||
interface). For example, the Nvim lua-client is an API client:
|
||||
https://github.com/neovim/lua-client
|
||||
|
||||
Host ~
|
||||
A plugin "host" is both a client (of the Nvim API) and a server (of an
|
||||
external platform, e.g. python). It is a remote plugin that hosts other
|
||||
plugins.
|
||||
|
||||
Remote plugin ~
|
||||
Arbitrary code registered via |:UpdateRemotePlugins|, that runs in a separate
|
||||
process and communicates with Nvim via the |api|.
|
||||
|
||||
Window ~
|
||||
The word "window" is commonly used for several things: A window on the screen,
|
||||
the xterm window, a window inside Vim to view a buffer.
|
||||
To avoid confusion, other items that are sometimes called window have been
|
||||
given another name. Here is an overview of the related items:
|
||||
|
||||
screen The whole display.
|
||||
shell The Vim application. This can cover the whole screen (e.g.,
|
||||
when running in a console) or part of it (xterm or GUI).
|
||||
window View on a buffer. There can be several windows in Vim,
|
||||
together with the command line, menubar, toolbar, etc. they
|
||||
fit in the shell.
|
||||
frame Windows are kept in a tree of frames. Each frame contains
|
||||
a column, row, or window ("leaf" frame).
|
||||
|
||||
PROVIDERS *dev-provider*
|
||||
|
||||
A goal of Nvim is to allow extension of the editor without special knowledge
|
||||
|
@ -215,6 +181,8 @@ Standard Features ~
|
|||
- Clients should call |nvim_set_client_info()| after connecting, so users and
|
||||
plugins can detect the client by handling the |ChanInfo| event. This
|
||||
avoids the need for special variables or other client hints.
|
||||
- Clients should handle |nvim_error_event| notifications, which will be sent
|
||||
if an async request to nvim was rejected or caused an error.
|
||||
|
||||
Package Naming ~
|
||||
|
||||
|
|
|
@ -27,7 +27,9 @@ The second and following arguments may also be a directory name. Vim will
|
|||
then append the file name of the first argument to the directory name to find
|
||||
the file.
|
||||
|
||||
This only works when a standard "diff" command is available. See 'diffexpr'.
|
||||
By default an internal diff library will be used. When 'diffopt' or
|
||||
'diffexpr' has been set an external "diff" command will be used. This only
|
||||
works when such a diff program is available.
|
||||
|
||||
Diffs are local to the current tab page |tab-page|. You can't see diffs with
|
||||
a window in another tab page. This does make it possible to have several
|
||||
|
@ -332,8 +334,9 @@ between file1 and file2: >
|
|||
|
||||
The ">" is replaced with the value of 'shellredir'.
|
||||
|
||||
The output of "diff" must be a normal "ed" style diff. Do NOT use a context
|
||||
diff. This example explains the format that Vim expects: >
|
||||
The output of "diff" must be a normal "ed" style diff or a unified diff. Do
|
||||
NOT use a context diff. This example explains the format that Vim expects for
|
||||
the "ed" style diff: >
|
||||
|
||||
1a2
|
||||
> bbb
|
||||
|
|
|
@ -2137,8 +2137,6 @@ index({list}, {expr} [, {start} [, {ic}]])
|
|||
Number index in {list} where {expr} appears
|
||||
input({prompt} [, {text} [, {completion}]])
|
||||
String get input from the user
|
||||
inputdialog({prompt} [, {text} [, {completion}]])
|
||||
String like input() but in a GUI dialog
|
||||
inputlist({textlist}) Number let the user pick from a choice list
|
||||
inputrestore() Number restore typeahead
|
||||
inputsave() Number save and clear typeahead
|
||||
|
@ -2925,7 +2923,7 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
|
|||
made. It returns the number of the choice. For the first
|
||||
choice this is 1.
|
||||
|
||||
{msg} is displayed in a |dialog| with {choices} as the
|
||||
{msg} is displayed in a dialog with {choices} as the
|
||||
alternatives. When {choices} is missing or empty, "&OK" is
|
||||
used (and translated).
|
||||
{msg} is a String, use '\n' to include a newline. Only on
|
||||
|
@ -3381,9 +3379,7 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
|
|||
|
||||
If {list} is given and it is |TRUE|, a List will be returned.
|
||||
Otherwise the result is a String and when there are several
|
||||
matches, they are separated by <NL> characters. [Note: in
|
||||
version 5.0 a space was used, which caused problems when a
|
||||
file name contains a space]
|
||||
matches, they are separated by <NL> characters.
|
||||
|
||||
If the expansion fails, the result is an empty string. A name
|
||||
for a non-existing file is not included, unless {expr} does
|
||||
|
@ -3444,7 +3440,7 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
|
|||
all "README" files in the current directory and below: >
|
||||
:echo expand("**/README")
|
||||
<
|
||||
Expand() can also be used to expand variables and environment
|
||||
expand() can also be used to expand variables and environment
|
||||
variables that are only known in a shell. But this can be
|
||||
slow, because a shell may be used to do the expansion. See
|
||||
|expr-env-expand|.
|
||||
|
@ -4915,20 +4911,6 @@ input({opts})
|
|||
: call inputrestore()
|
||||
:endfunction
|
||||
|
||||
inputdialog({prompt} [, {text} [, {cancelreturn}]]) *inputdialog()*
|
||||
inputdialog({opts})
|
||||
Like |input()|, but when the GUI is running and text dialogs
|
||||
are supported, a dialog window pops up to input the text.
|
||||
Example: >
|
||||
:let n = inputdialog("value for shiftwidth", shiftwidth())
|
||||
:if n != ""
|
||||
: let &sw = n
|
||||
:endif
|
||||
< When the dialog is cancelled {cancelreturn} is returned. When
|
||||
omitted an empty string is returned.
|
||||
Hitting <Enter> works like pressing the OK button. Hitting
|
||||
<Esc> works like pressing the Cancel button.
|
||||
|
||||
inputlist({textlist}) *inputlist()*
|
||||
{textlist} must be a |List| of strings. This |List| is
|
||||
displayed, one string per line. The user will be prompted to
|
||||
|
@ -8560,7 +8542,7 @@ tag_old_static Compiled with support for old static tags
|
|||
|tag-old-static|.
|
||||
tag_any_white Compiled with support for any white characters in tags
|
||||
files |tag-any-white|.
|
||||
termresponse Compiled with support for |t_RV| and |v:termresponse|.
|
||||
termresponse Compiled with support for t_RV and |v:termresponse|.
|
||||
textobjects Compiled with support for |text-objects|.
|
||||
timers Compiled with |timer_start()| support.
|
||||
title Compiled with window title support |'title'|.
|
||||
|
|
|
@ -150,6 +150,7 @@ GUI ~
|
|||
|
||||
Interfaces ~
|
||||
|if_cscop.txt| using Cscope with Vim
|
||||
|if_lua.txt| Lua interface
|
||||
|if_pyth.txt| Python interface
|
||||
|if_ruby.txt| Ruby interface
|
||||
|sign.txt| debugging signs
|
||||
|
@ -160,6 +161,9 @@ Versions ~
|
|||
*standard-plugin-list*
|
||||
Standard plugins ~
|
||||
|pi_gzip.txt| Reading and writing compressed files
|
||||
|pi_health.txt| Healthcheck framework
|
||||
|pi_matchit.txt| Extended "%" matching
|
||||
|pi_msgpack.txt| msgpack utilities
|
||||
|pi_netrw.txt| Reading and writing files over a network
|
||||
|pi_paren.txt| Highlight matching parens
|
||||
|pi_spec.txt| Filetype plugin to work with rpm spec files
|
||||
|
|
|
@ -229,8 +229,7 @@ shared between command calls. All Lua default libraries are available. In
|
|||
addition, Lua "print" function has its output redirected to the Nvim message
|
||||
area, with arguments separated by a white space instead of a tab.
|
||||
|
||||
Lua uses the "vim" module (see |lua-vim|) to issue commands to Nvim
|
||||
and manage buffers (|lua-buffer|) and windows (|lua-window|). However,
|
||||
Lua uses the "vim" module (see |lua-vim|) to issue commands to Nvim. However,
|
||||
procedures that alter buffer content, open new buffers, and change cursor
|
||||
position are restricted when the command is executed in the |sandbox|.
|
||||
|
||||
|
@ -261,7 +260,7 @@ vim.stricmp(a, b) *lua-vim.stricmp*
|
|||
greater then b or a is lesser then b respectively.
|
||||
|
||||
vim.type_idx *lua-vim.type_idx*
|
||||
Type index for use in |lua-special-tables|. Specifying one of the
|
||||
Type index for use in |lua-special-tbl|. Specifying one of the
|
||||
values from |lua-vim.types| allows typing the empty table (it is
|
||||
unclear whether empty lua table represents empty list or empty array)
|
||||
and forcing integral numbers to be |Float|. See |lua-special-tbl| for
|
||||
|
|
|
@ -1472,7 +1472,6 @@ tag command action ~
|
|||
|:sfind| :sf[ind] split current window and edit file in 'path'
|
||||
|:sfirst| :sfir[st] split window and go to first file in the
|
||||
argument list
|
||||
|:simalt| :sim[alt] Win32 GUI: simulate Windows ALT key
|
||||
|:sign| :sig[n] manipulate signs
|
||||
|:silent| :sil[ent] run a command silently
|
||||
|:sleep| :sl[eep] do nothing for a few seconds
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
*intro.txt* Nvim
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
NVIM REFERENCE MANUAL
|
||||
|
||||
|
||||
Introduction to Vim *ref* *reference*
|
||||
|
@ -9,7 +9,7 @@ Introduction to Vim *ref* *reference*
|
|||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
1. Introduction *intro*
|
||||
Introduction *intro*
|
||||
|
||||
Vim stands for Vi IMproved. It used to be Vi IMitation, but there are so many
|
||||
improvements that a name change was appropriate. Vim is a text editor which
|
||||
|
@ -28,8 +28,8 @@ is not located in the default place. You can jump to subjects like with tags:
|
|||
Use CTRL-] to jump to a subject under the cursor, use CTRL-T to jump back.
|
||||
|
||||
*pronounce*
|
||||
Vim is pronounced as one word, like Jim, not vi-ai-em. It's written with a
|
||||
capital, since it's a name, again like Jim.
|
||||
Vim is pronounced as one word, like Jim. Nvim is pronounced as N-vim, or,
|
||||
continuing with the Jim simile, N-Jim, which sounds like Ninja.
|
||||
|
||||
This manual is a reference for all the Vim commands and options. This is not
|
||||
an introduction to the use of Vi or Vim, it gets a bit complicated here and
|
||||
|
@ -37,134 +37,67 @@ there. For beginners, there is a hands-on |tutor|. To learn using Vim, read
|
|||
the user manual |usr_toc.txt|.
|
||||
|
||||
*book*
|
||||
There are many books on Vi that contain a section for beginners. There are
|
||||
two books I can recommend:
|
||||
There are many books on Vi and Vim. We recommend these books:
|
||||
|
||||
"Practical Vim" by Drew Neil
|
||||
"Modern Vim" by Drew Neil
|
||||
https://vimcasts.org/publications/
|
||||
|
||||
"Practical Vim" is a popular because of its focus on quickly learning common
|
||||
editing tasks with Vim. "Modern Vim" explores new features introduced by Nvim
|
||||
and Vim 8.
|
||||
|
||||
"Vim - Vi Improved" by Steve Oualline
|
||||
|
||||
This is the very first book completely dedicated to Vim. It is very good for
|
||||
beginners. The most often used commands are explained with pictures and
|
||||
examples. The less often used commands are also explained, the more advanced
|
||||
features are summarized. There is a comprehensive index and a quick
|
||||
reference. Parts of this book have been included in the user manual
|
||||
|frombook|.
|
||||
Published by New Riders Publishing. ISBN: 0735710015
|
||||
This is the first book dedicated to Vim. Parts of it were included in the
|
||||
user manual. |frombook| ISBN: 0735710015
|
||||
For more information try one of these:
|
||||
http://iccf-holland.org/click5.html
|
||||
http://www.vim.org/iccf/click5.html
|
||||
|
||||
"Learning the Vi editor" by Linda Lamb and Arnold Robbins
|
||||
|
||||
This is a book about Vi that includes a chapter on Vim (in the sixth edition).
|
||||
The first steps in Vi are explained very well. The commands that Vim adds are
|
||||
only briefly mentioned. There is also a German translation.
|
||||
Published by O'Reilly. ISBN: 1-56592-426-6.
|
||||
https://iccf-holland.org/click5.html
|
||||
https://www.vim.org/iccf/click5.html
|
||||
|
||||
==============================================================================
|
||||
2. Vim on the internet *internet*
|
||||
Nvim on the interwebs *internet*
|
||||
|
||||
*www* *WWW* *faq* *FAQ* *distribution* *download*
|
||||
The Vim pages contain the most recent information about Vim. They also
|
||||
contain links to the most recent version of Vim. The FAQ is a list of
|
||||
Frequently Asked Questions. Read this if you have problems.
|
||||
|
||||
Vim home page: http://www.vim.org/
|
||||
Vim FAQ: http://vimdoc.sf.net/
|
||||
Downloading: ftp://ftp.vim.org/pub/vim/MIRRORS
|
||||
|
||||
|
||||
Usenet News group where Vim is discussed: *news* *usenet*
|
||||
comp.editors
|
||||
This group is also for other editors. If you write about Vim, don't forget to
|
||||
mention that.
|
||||
|
||||
*mail-list* *maillist*
|
||||
There are several mailing lists for Vim:
|
||||
<vim@vim.org> *vim-use* *vim_use*
|
||||
For discussions about using existing versions of Vim: Useful mappings,
|
||||
questions, answers, where to get a specific version, etc. There are
|
||||
quite a few people watching this list and answering questions, also
|
||||
for beginners. Don't hesitate to ask your question here.
|
||||
<vim-dev@vim.org> *vim-dev* *vim_dev* *vimdev*
|
||||
For discussions about changing Vim: New features, porting, patches,
|
||||
beta-test versions, etc.
|
||||
<vim-announce@vim.org> *vim-announce* *vim_announce*
|
||||
Announcements about new versions of Vim; also for beta-test versions
|
||||
and ports to different systems. This is a read-only list.
|
||||
<vim-mac@vim.org> *vim-mac* *vim_mac*
|
||||
For discussions about using and improving the Macintosh version of
|
||||
Vim.
|
||||
|
||||
See http://www.vim.org/maillist.php for the latest information.
|
||||
|
||||
NOTE:
|
||||
- You can only send messages to these lists if you have subscribed!
|
||||
- You need to send the messages from the same location as where you subscribed
|
||||
from (to avoid spam mail).
|
||||
- Maximum message size is 40000 characters.
|
||||
|
||||
*subscribe-maillist*
|
||||
If you want to join, send a message to
|
||||
<vim-subscribe@vim.org>
|
||||
Make sure that your "From:" address is correct. Then the list server will
|
||||
give you help on how to subscribe.
|
||||
|
||||
*maillist-archive*
|
||||
For more information and archives look on the Vim maillist page:
|
||||
http://www.vim.org/maillist.php
|
||||
Nvim home page: https://neovim.io/
|
||||
Nvim FAQ: https://github.com/neovim/neovim/wiki/FAQ
|
||||
Downloads: https://github.com/neovim/neovim/releases
|
||||
Vim FAQ: https://vimhelp.appspot.com/vim_faq.txt.html
|
||||
Vim home page: https://www.vim.org/
|
||||
|
||||
|
||||
Bug reports: *bugs* *bug-reports* *bugreport.vim*
|
||||
|
||||
Report bugs on GitHub: https://github.com/neovim/neovim/issues
|
||||
|
||||
Please be brief; all the time that is spent on answering mail is subtracted
|
||||
from the time that is spent on improving Vim! Always give a reproducible
|
||||
example and try to find out which settings or other things trigger the bug.
|
||||
Be brief, yet complete. Always give a reproducible example and try to find
|
||||
out which settings or other things trigger the bug.
|
||||
|
||||
Preferably start Vim with: >
|
||||
vim --clean -u reproduce.vim
|
||||
Where reproduce.vim is a script that reproduces the problem. Try different
|
||||
machines, if relevant (is this an MS-Windows specific bug perhaps?).
|
||||
|
||||
Send me patches if you can!
|
||||
|
||||
It will help to include information about the version of Vim you are using and
|
||||
your setup. You can get the information with this command: >
|
||||
:so $VIMRUNTIME/bugreport.vim
|
||||
This will create a file "bugreport.txt" in the current directory, with a lot
|
||||
of information of your environment. Before sending this out, check if it
|
||||
doesn't contain any confidential information!
|
||||
|
||||
If Vim crashes, please try to find out where. You can find help on this here:
|
||||
|debug.txt|.
|
||||
|
||||
In case of doubt or when you wonder if the problem has already been fixed but
|
||||
you can't find a fix for it, become a member of the vim-dev maillist and ask
|
||||
your question there. |maillist|
|
||||
|
||||
*year-2000* *Y2K*
|
||||
Since Vim internally doesn't use dates for editing, there is no year 2000
|
||||
problem to worry about. Vim does use the time in the form of seconds since
|
||||
January 1st 1970. It is used for a time-stamp check of the edited file and
|
||||
the swap file, which is not critical and should only cause warning messages.
|
||||
|
||||
There might be a year 2038 problem, when the seconds don't fit in a 32 bit int
|
||||
anymore. This depends on the compiler, libraries and operating system.
|
||||
Specifically, time_t and the ctime() function are used. And the time_t is
|
||||
stored in four bytes in the swap file. But that's only used for printing a
|
||||
file date/time for recovery, it will never affect normal editing.
|
||||
|
||||
The Vim strftime() function directly uses the strftime() system function.
|
||||
localtime() uses the time() system function. getftime() uses the time
|
||||
returned by the stat() system function. If your system libraries are year
|
||||
2000 compliant, Vim is too.
|
||||
|
||||
The user may create scripts for Vim that use external commands. These might
|
||||
introduce Y2K problems, but those are not really part of Vim itself.
|
||||
If Nvim crashes, try to get a backtrace. See |debug.txt|.
|
||||
|
||||
==============================================================================
|
||||
3. Credits *credits* *author* *Bram* *Moolenaar*
|
||||
Sponsor Vim/Nvim development *sponsor* *register*
|
||||
|
||||
Fixing bugs and adding new features takes a lot of time and effort. To show
|
||||
your appreciation for the work and motivate Bram and others to continue
|
||||
working on Vim please send a donation.
|
||||
|
||||
Since Bram is back to a paid job the money will now be used to help children
|
||||
in Uganda. See |uganda|. But at the same time donations increase Bram's
|
||||
motivation to keep working on Vim!
|
||||
|
||||
For the most recent information about sponsoring look on the Vim web site:
|
||||
|
||||
https://www.vim.org/sponsor/
|
||||
|
||||
|
||||
Neovim development is funded separately from Vim:
|
||||
|
||||
https://neovim.io/#sponsor
|
||||
|
||||
==============================================================================
|
||||
Credits *credits* *author* *Bram* *Moolenaar*
|
||||
|
||||
Most of Vim was written by Bram Moolenaar <Bram@vim.org>.
|
||||
|
||||
|
@ -273,7 +206,7 @@ Elvis Another Vi clone, made by Steve Kirkendall. Very compact but isn't
|
|||
freely available.
|
||||
|
||||
==============================================================================
|
||||
4. Notation *notation*
|
||||
Notation *notation*
|
||||
|
||||
When syntax highlighting is used to read this, text that is not typed
|
||||
literally is often highlighted with the Special group. These are items in [],
|
||||
|
@ -494,7 +427,7 @@ examples and use them directly. Or type them literally, including the '<' and
|
|||
":autocmd"!
|
||||
|
||||
==============================================================================
|
||||
5. Modes, introduction *vim-modes-intro* *vim-modes*
|
||||
Modes, introduction *vim-modes-intro* *vim-modes*
|
||||
|
||||
Vim has seven BASIC modes:
|
||||
|
||||
|
@ -579,7 +512,7 @@ Insert Select mode Entered when starting Select mode from Insert mode.
|
|||
is shown at the bottom of the window.
|
||||
|
||||
==============================================================================
|
||||
6. Switching from mode to mode *mode-switching*
|
||||
Switching from mode to mode *mode-switching*
|
||||
|
||||
If for any reason you do not know which mode you are in, you can always get
|
||||
back to Normal mode by typing <Esc> twice. This doesn't work for Ex mode
|
||||
|
@ -650,7 +583,7 @@ Q or gQ Switch to Ex mode. This is like typing ":" commands
|
|||
Use the ":vi" command |:visual| to exit this mode.
|
||||
|
||||
==============================================================================
|
||||
7. The window contents *window-contents*
|
||||
The window contents *window-contents*
|
||||
|
||||
In Normal mode and Insert/Replace mode the screen window will show the current
|
||||
contents of the buffer: What You See Is What You Get. There are two
|
||||
|
@ -769,18 +702,15 @@ window. You may make the window as small as you like, but if it gets too
|
|||
small not a single line will fit in it. Make it at least 40 characters wide
|
||||
to be able to read most messages on the last line.
|
||||
|
||||
On most Unix systems, resizing the window is recognized and handled correctly
|
||||
by Vim.
|
||||
|
||||
==============================================================================
|
||||
8. Definitions *definitions*
|
||||
Definitions *definitions* *jargon*
|
||||
|
||||
buffer Contains lines of text, usually read from a file.
|
||||
screen The whole area that Vim uses to work in. This can be
|
||||
a terminal emulator window. Also called "the Vim
|
||||
window".
|
||||
buffer Contains lines of text, usually from a file.
|
||||
screen The whole area that Nvim uses to display things.
|
||||
window A view on a buffer. There can be multiple windows for
|
||||
one buffer.
|
||||
frame Windows are kept in a tree of frames. Each frame
|
||||
contains a column, row, or window ("leaf" frame).
|
||||
|
||||
A screen contains one or more windows, separated by status lines and with the
|
||||
command line at the bottom.
|
||||
|
@ -813,7 +743,7 @@ A difference is made between four types of lines:
|
|||
lines with wrapping, line breaks, etc. applied. They
|
||||
can only be as long as the width of the window allows,
|
||||
longer lines are wrapped or truncated.
|
||||
screen lines The lines of the screen that Vim uses. Consists of
|
||||
screen lines The lines of the screen that Nvim uses. Consists of
|
||||
the window lines of all windows, with status lines
|
||||
and the command line added. They can only be as long
|
||||
as the width of the screen allows. When the command
|
||||
|
@ -837,5 +767,27 @@ buffer lines logical lines window lines screen lines ~
|
|||
5. ddd 13. (command line)
|
||||
6. ~
|
||||
|
||||
|
||||
API client ~
|
||||
All external UIs and remote plugins (as opposed to regular Vim plugins) are
|
||||
"clients" in general; but we call something an "API client" if its purpose is
|
||||
to abstract or wrap the RPC API for the convenience of other applications
|
||||
(just like a REST client or SDK such as boto3 for AWS: you can speak AWS REST
|
||||
using an HTTP client like curl, but boto3 wraps that in a convenient python
|
||||
interface). For example, the Nvim lua-client is an API client:
|
||||
https://github.com/neovim/lua-client
|
||||
|
||||
|
||||
Host ~
|
||||
A plugin "host" is both a client (of the Nvim API) and a server (of an
|
||||
external platform, e.g. python). It is a remote plugin that hosts other
|
||||
plugins.
|
||||
|
||||
|
||||
Remote plugin ~
|
||||
Arbitrary code registered via |:UpdateRemotePlugins|, that runs in a separate
|
||||
process and communicates with Nvim via the |api|.
|
||||
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
|
|
@ -286,6 +286,9 @@ current mode (instead of always going to normal-mode). Visual-mode is
|
|||
preserved, so tricks with |gv| are not needed. Commands can be invoked
|
||||
directly in cmdline-mode (which otherwise would require timer hacks).
|
||||
|
||||
Because <Cmd> avoids mode-changes (unlike ":") it does not trigger
|
||||
|CmdlineEnter| and |CmdlineLeave| events. This helps performance.
|
||||
|
||||
Unlike <expr> mappings, there are no special restrictions on the <Cmd>
|
||||
command: it is executed as if an (unrestricted) |autocmd| was invoked or an
|
||||
async event event was processed.
|
||||
|
|
|
@ -514,15 +514,6 @@ command. The script can then again read another script. This can continue
|
|||
for about 14 levels. When more nesting is done, Vim assumes that there is a
|
||||
recursive loop somewhere and stops with this error message.
|
||||
|
||||
*E319* >
|
||||
The command is not available in this version
|
||||
|
||||
You have used a command that is not present in the version of Vim you are
|
||||
using. When compiling Vim, many different features can be enabled or
|
||||
disabled. This depends on how big Vim has chosen to be and the operating
|
||||
system. See |+feature-list| for when which feature is available. The
|
||||
|:version| command shows which feature Vim was compiled with.
|
||||
|
||||
*E300* >
|
||||
Swap file already exists (symlink attack?)
|
||||
|
||||
|
|
|
@ -703,47 +703,24 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
been set.
|
||||
|
||||
*'background'* *'bg'*
|
||||
'background' 'bg' string (default "dark" or "light", see below)
|
||||
'background' 'bg' string (default "dark")
|
||||
global
|
||||
When set to "dark", Vim will try to use colors that look good on a
|
||||
dark background. When set to "light", Vim will try to use colors that
|
||||
look good on a light background. Any other value is illegal.
|
||||
Vim tries to set the default value according to the terminal used.
|
||||
This will not always be correct.
|
||||
Setting this option does not change the background color, it tells Vim
|
||||
what the background color looks like. For changing the background
|
||||
color, see |:hi-normal|.
|
||||
When set to "dark" or "light", Nvim will adjust the default color
|
||||
groups for a dark or light background, respectively.
|
||||
|
||||
When 'background' is set Vim will adjust the default color groups for
|
||||
the new value. But the colors used for syntax highlighting will not
|
||||
change. *g:colors_name*
|
||||
This option does NOT change the background color, it tells Nvim what
|
||||
the "inherited" (terminal/GUI) background looks like.
|
||||
See |:hi-normal| if you want to set the background color explicitly.
|
||||
*g:colors_name*
|
||||
When a color scheme is loaded (the "g:colors_name" variable is set)
|
||||
setting 'background' will cause the color scheme to be reloaded. If
|
||||
the color scheme adjusts to the value of 'background' this will work.
|
||||
However, if the color scheme sets 'background' itself the effect may
|
||||
be undone. First delete the "g:colors_name" variable when needed.
|
||||
|
||||
When setting 'background' to the default value with: >
|
||||
:set background&
|
||||
< Vim will guess the value. In the GUI this should work correctly,
|
||||
in other cases Vim might not be able to guess the right value.
|
||||
|
||||
When starting the GUI, the default value for 'background' will be
|
||||
"light". When the value is not set in the gvimrc, and Vim detects
|
||||
that the background is actually quite dark, 'background' is set to
|
||||
"dark". But this happens only AFTER the gvimrc file has been read
|
||||
(because the window needs to be opened to find the actual background
|
||||
color). To get around this, force the GUI window to be opened by
|
||||
putting a ":gui" command in the gvimrc file, before where the value
|
||||
of 'background' is used (e.g., before ":syntax on").
|
||||
|
||||
For Windows the default is "dark". "dark" should be used if $COLORFGBG
|
||||
suggests a dark background (not yet implemented). Otherwise the default
|
||||
is "light".
|
||||
|
||||
Normally this option would be set in the vimrc file. Possibly
|
||||
depending on the terminal name. Example: >
|
||||
:if $TERM == "xterm"
|
||||
:if $TERM ==# "xterm"
|
||||
: set background=dark
|
||||
:endif
|
||||
< When this option is set, the default settings for the highlight groups
|
||||
|
@ -1485,7 +1462,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
global
|
||||
When 'confirm' is on, certain operations that would normally
|
||||
fail because of unsaved changes to a buffer, e.g. ":q" and ":e",
|
||||
instead raise a |dialog| asking if you wish to save the current
|
||||
instead raise a dialog asking if you wish to save the current
|
||||
file(s). You can still use a ! to unconditionally |abandon| a buffer.
|
||||
If 'confirm' is off you can still activate confirmation for one
|
||||
command only (this is most useful in mappings) with the |:confirm|
|
||||
|
@ -1882,13 +1859,13 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
*'dex'* *'diffexpr'*
|
||||
'diffexpr' 'dex' string (default "")
|
||||
global
|
||||
Expression which is evaluated to obtain an ed-style diff file from two
|
||||
versions of a file. See |diff-diffexpr|.
|
||||
Expression which is evaluated to obtain a diff file (either ed-style
|
||||
or unified-style) from two versions of a file. See |diff-diffexpr|.
|
||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||
security reasons.
|
||||
|
||||
*'dip'* *'diffopt'*
|
||||
'diffopt' 'dip' string (default "filler")
|
||||
'diffopt' 'dip' string (default "internal,filler")
|
||||
global
|
||||
Option settings for diff mode. It can consist of the following items.
|
||||
All are optional. Items must be separated by a comma.
|
||||
|
@ -1948,11 +1925,31 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
|
||||
starting diff mode. Without this 2 is used.
|
||||
|
||||
Examples: >
|
||||
internal Use the internal diff library. This is
|
||||
ignored when 'diffexpr' is set. *E960*
|
||||
When running out of memory when writing a
|
||||
buffer this item will be ignored for diffs
|
||||
involving that buffer. Set the 'verbose'
|
||||
option to see when this happens.
|
||||
|
||||
:set diffopt=filler,context:4
|
||||
indent-heuristic
|
||||
Use the indent heuristic for the internal
|
||||
diff library.
|
||||
|
||||
algorithm:{text} Use the specified diff algorithm with the
|
||||
internal diff engine. Currently supported
|
||||
algorithms are:
|
||||
myers the default algorithm
|
||||
minimal spend extra time to generate the
|
||||
smallest possible diff
|
||||
patience patience diff algorithm
|
||||
histogram histogram diff algorithm
|
||||
|
||||
Examples: >
|
||||
:set diffopt=internal,filler,context:4
|
||||
:set diffopt=
|
||||
:set diffopt=filler,foldcolumn:3
|
||||
:set diffopt=internal,filler,foldcolumn:3
|
||||
:set diffopt-=internal " do NOT use the internal diff parser
|
||||
<
|
||||
*'digraph'* *'dg'* *'nodigraph'* *'nodg'*
|
||||
'digraph' 'dg' boolean (default off)
|
||||
|
@ -2803,8 +2800,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
:set guifont=*
|
||||
< will bring up a font requester, where you can pick the font you want.
|
||||
|
||||
The font name depends on the GUI used. See |setting-guifont| for a
|
||||
way to set 'guifont' for various systems.
|
||||
The font name depends on the GUI used.
|
||||
|
||||
For Mac OSX you can use something like this: >
|
||||
:set guifont=Monaco:h10
|
||||
|
@ -6586,8 +6582,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
menu. This conflicts with the use of the ALT key for mappings and
|
||||
entering special characters. This option tells what to do:
|
||||
no Don't use ALT keys for menus. ALT key combinations can be
|
||||
mapped, but there is no automatic handling. This can then be
|
||||
done with the |:simalt| command.
|
||||
mapped, but there is no automatic handling.
|
||||
yes ALT key handling is done by the windowing system. ALT key
|
||||
combinations cannot be mapped.
|
||||
menu Using ALT in combination with a character that is a menu
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
*pi_msgpack.txt* Nvim
|
||||
*pi_msgpack.txt* msgpack utilities
|
||||
|
||||
Author: Nikolay Pavlov <kp-pav@yandex.ru>
|
||||
Copyright: (c) 2015 by Nikolay Pavlov
|
||||
|
|
|
@ -4,14 +4,21 @@
|
|||
NVIM REFERENCE MANUAL by Thiago de Arruda
|
||||
|
||||
|
||||
Providers *provider*
|
||||
Providers *provider*
|
||||
|
||||
Nvim delegates some features to dynamic "providers".
|
||||
Nvim delegates some features to dynamic "providers". This document describes
|
||||
the providers and how to install them.
|
||||
*E319*
|
||||
Use of a feature requiring a missing provider is an error: >
|
||||
|
||||
E319: No "foo" provider found. Run ":checkhealth provider"
|
||||
|
||||
Run the |:checkhealth| command, and review the sections below.
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
Python integration *provider-python*
|
||||
Python integration *provider-python*
|
||||
|
||||
Nvim supports Python |remote-plugin|s and the Vim legacy |python2| and
|
||||
|python3| interfaces (which are implemented as remote-plugins).
|
||||
|
@ -19,23 +26,23 @@ Note: Only the Vim 7.3 API is supported; bindeval (Vim 7.4) is not.
|
|||
|
||||
PYTHON QUICKSTART ~
|
||||
|
||||
Install the "neovim" Python package:
|
||||
Install the "pynvim" Python package:
|
||||
|
||||
- Run |:checkhealth| to see if you already have the package (some package
|
||||
managers install the "neovim" Python package with Nvim itself).
|
||||
managers install the "pynvim" Python package with Nvim itself).
|
||||
|
||||
- For Python 2 plugins, make sure Python 2.7 is available in your $PATH, then
|
||||
install the package systemwide: >
|
||||
sudo pip2 install --upgrade neovim
|
||||
sudo pip2 install --upgrade pynvim
|
||||
< or for the current user: >
|
||||
pip2 install --user --upgrade neovim
|
||||
pip2 install --user --upgrade pynvim
|
||||
< If "pip2" is missing, try "pip".
|
||||
|
||||
- For Python 3 plugins, make sure Python 3.4+ is available in your $PATH, then
|
||||
install the package systemwide: >
|
||||
sudo pip3 install --upgrade neovim
|
||||
sudo pip3 install --upgrade pynvim
|
||||
< or for the current user: >
|
||||
pip3 install --user --upgrade neovim
|
||||
pip3 install --user --upgrade pynvim
|
||||
< If "pip3" is missing, try "pip".
|
||||
|
||||
- The `--upgrade` flag ensures you have the latest version even if a previous
|
||||
|
@ -64,14 +71,14 @@ PYTHON VIRTUALENVS ~
|
|||
|
||||
If you plan to use per-project virtualenvs often, you should assign one
|
||||
virtualenv for Neovim and hard-code the interpreter path via
|
||||
|g:python3_host_prog| (or |g:python_host_prog|) so that the "neovim" package
|
||||
|g:python3_host_prog| (or |g:python_host_prog|) so that the "pynvim" package
|
||||
is not required for each virtualenv.
|
||||
|
||||
Example using pyenv: >
|
||||
pyenv install 3.4.4
|
||||
pyenv virtualenv 3.4.4 py3nvim
|
||||
pyenv activate py3nvim
|
||||
pip install neovim
|
||||
pip install pynvim
|
||||
pyenv which python # Note the path
|
||||
The last command reports the interpreter path, add it to your init.vim: >
|
||||
let g:python3_host_prog = '/path/to/py3nvim/bin/python'
|
||||
|
@ -150,16 +157,19 @@ The presence of a working clipboard tool implicitly enables the '+' and '*'
|
|||
registers. Nvim looks for these clipboard tools, in order of priority:
|
||||
|
||||
- |g:clipboard|
|
||||
- pbcopy/pbpaste (macOS)
|
||||
- xsel (if $DISPLAY is set)
|
||||
- pbcopy, pbpaste (macOS)
|
||||
- wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
|
||||
- xclip (if $DISPLAY is set)
|
||||
- xsel (if $DISPLAY is set)
|
||||
- lemonade (for SSH) https://github.com/pocke/lemonade
|
||||
- doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
|
||||
- win32yank (Windows)
|
||||
- tmux (if $TMUX is set)
|
||||
|
||||
*g:clipboard*
|
||||
To configure a custom clipboard tool, set `g:clipboard` to a dictionary: >
|
||||
To configure a custom clipboard tool, set g:clipboard to a dictionary.
|
||||
For example this configuration integrates the tmux clipboard: >
|
||||
|
||||
let g:clipboard = {
|
||||
\ 'name': 'myClipboard',
|
||||
\ 'copy': {
|
||||
|
@ -173,9 +183,28 @@ To configure a custom clipboard tool, set `g:clipboard` to a dictionary: >
|
|||
\ 'cache_enabled': 1,
|
||||
\ }
|
||||
|
||||
If `cache_enabled` is |TRUE| then when a selection is copied, Nvim will cache
|
||||
If "cache_enabled" is |TRUE| then when a selection is copied Nvim will cache
|
||||
the selection until the copy command process dies. When pasting, if the copy
|
||||
process has not died, the cached selection is applied.
|
||||
process has not died the cached selection is applied.
|
||||
|
||||
g:clipboard can also use functions (see |lambda|) instead of strings.
|
||||
For example this configuration uses the g:foo variable as a fake clipboard: >
|
||||
|
||||
let g:clipboard = {
|
||||
\ 'name': 'myClipboard',
|
||||
\ 'copy': {
|
||||
\ '+': {lines, regtype -> extend(g:, {'foo': [lines, regtype]}) },
|
||||
\ '*': {lines, regtype -> extend(g:, {'foo': [lines, regtype]}) },
|
||||
\ },
|
||||
\ 'paste': {
|
||||
\ '+': {-> get(g:, 'foo', [])},
|
||||
\ '*': {-> get(g:, 'foo', [])},
|
||||
\ },
|
||||
\ }
|
||||
|
||||
The "copy" function stores a list of lines and the register type. The "paste"
|
||||
function returns the clipboard as a `[lines, regtype]` list, where `lines` is
|
||||
a list of lines and `regtype` is a register type conforming to |setreg()|.
|
||||
|
||||
==============================================================================
|
||||
X11 selection mechanism *clipboard-x11* *x11-selection*
|
||||
|
|
|
@ -167,11 +167,6 @@ a client and send strings to other instances of Vim on the same X11 display.
|
|||
When an X11 GUI Vim (gvim) is started, it will try to register a send-server
|
||||
name on the 'VimRegistry' property on the root window.
|
||||
|
||||
A non GUI Vim with access to the X11 display (|xterm-clipboard| enabled), can
|
||||
also act as a command server if a server name is explicitly given with the
|
||||
--servername argument, or when Vim was build with the |+autoservername|
|
||||
feature.
|
||||
|
||||
An empty --servername argument will cause the command server to be disabled.
|
||||
|
||||
To send commands to a Vim server from another application, read the source
|
||||
|
|
|
@ -42,15 +42,15 @@ what a Python plugin looks like. This plugin exports a command, a function, and
|
|||
an autocmd. The plugin is called 'Limit', and all it does is limit the number
|
||||
of requests made to it. Here's the plugin source code:
|
||||
>
|
||||
import neovim
|
||||
import pynvim
|
||||
|
||||
@neovim.plugin
|
||||
@pynvim.plugin
|
||||
class Limit(object):
|
||||
def __init__(self, vim):
|
||||
self.vim = vim
|
||||
self.calls = 0
|
||||
|
||||
@neovim.command('Cmd', range='', nargs='*', sync=True)
|
||||
@pynvim.command('Cmd', range='', nargs='*', sync=True)
|
||||
def command_handler(self, args, range):
|
||||
self._increment_calls()
|
||||
self.vim.current.line = (
|
||||
|
@ -58,14 +58,14 @@ of requests made to it. Here's the plugin source code:
|
|||
args,
|
||||
range))
|
||||
|
||||
@neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")',
|
||||
@pynvim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")',
|
||||
sync=True)
|
||||
def autocmd_handler(self, filename):
|
||||
self._increment_calls()
|
||||
self.vim.current.line = (
|
||||
'Autocmd: Called %s times, file: %s' % (self.calls, filename))
|
||||
|
||||
@neovim.function('Func')
|
||||
@pynvim.function('Func')
|
||||
def function_handler(self, args):
|
||||
self._increment_calls()
|
||||
self.vim.current.line = (
|
||||
|
|
|
@ -305,6 +305,9 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
|||
first sourced. The number is used for the script ID
|
||||
|<SID>|.
|
||||
|
||||
:scr[iptnames][!] {scriptId} *:script*
|
||||
Edit script {scriptId}. Suggested name is ":script".
|
||||
|
||||
*:fini* *:finish* *E168*
|
||||
:fini[sh] Stop sourcing a script. Can only be used in a Vim
|
||||
script file. This is a quick way to skip the rest of
|
||||
|
|
|
@ -79,7 +79,6 @@ DEFINING A SIGN. *:sign-define* *E255* *E160* *E612*
|
|||
will cause redraw problems.
|
||||
toolkit supports ~
|
||||
Win32 .bmp, .ico, .cur
|
||||
pixmap (.xpm) |+xpm_w32|
|
||||
|
||||
linehl={group}
|
||||
Highlighting group used for the whole line the sign is placed
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
*sponsor.txt* Nvim
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
|
||||
|
||||
|
||||
SPONSOR VIM DEVELOPMENT *sponsor*
|
||||
|
||||
Fixing bugs and adding new features takes a lot of time and effort. To show
|
||||
your appreciation for the work and motivate Bram and others to continue
|
||||
working on Vim please send a donation.
|
||||
|
||||
Since Bram is back to a paid job the money will now be used to help children
|
||||
in Uganda. See |uganda|. But at the same time donations increase Bram's
|
||||
motivation to keep working on Vim!
|
||||
|
||||
For the most recent information about sponsoring look on the Vim web site:
|
||||
|
||||
http://www.vim.org/sponsor/
|
||||
|
||||
More explanations can be found in the |sponsor-faq|.
|
||||
|
||||
|
||||
REGISTERED VIM USER *register*
|
||||
|
||||
You can become a registered Vim user by sending at least 10 euro. This works
|
||||
similar to sponsoring Vim, see |sponsor| above. Registration was made
|
||||
possible for the situation where your boss or bookkeeper may be willing to
|
||||
register software, but does not like the terms "sponsoring" and "donation".
|
||||
|
||||
More explanations can be found in the |register-faq|.
|
||||
|
||||
|
||||
VOTE FOR FEATURES *vote-for-features*
|
||||
|
||||
To give registered Vim users and sponsors an advantage over lurkers they can
|
||||
vote for the items Bram should work on. How does this voting work?
|
||||
|
||||
1. You send at least 10 euro. See below for ways to transfer money
|
||||
|send-money|.
|
||||
|
||||
2. You will be e-mailed a registration key. Enter this key on your account
|
||||
page on the Vim website. You can easily create an account if you don't
|
||||
have one yet.
|
||||
|
||||
3. You can enter your votes on the voting page. There is a link to that page
|
||||
on your account page after entering a registration key. Your votes will
|
||||
be counted for two years.
|
||||
|
||||
4. The voting results appear on the results page, which is visible for
|
||||
everybody: http://www.vim.org/sponsor/vote_results.php
|
||||
|
||||
Additionally, once you have sent 100 euro or more in total, your name appears
|
||||
in the "Vim hall of honour": http://www.vim.org/sponsor/hall_of_honour.php
|
||||
But only if you enable this on your account page.
|
||||
|
||||
|
||||
HOW TO SEND MONEY *send-money*
|
||||
|
||||
Credit card Through PayPal, see the PayPal site for information:
|
||||
https://www.paypal.com/en_US/mrb/pal=XAC62PML3GF8Q
|
||||
The e-mail address for sending sponsorship money is:
|
||||
donate@vim.org
|
||||
The e-mail address for Vim registration is:
|
||||
register@vim.org
|
||||
Using Euro is preferred, other currencies are also accepted.
|
||||
In Euro countries a bank transfer is preferred, this has lower
|
||||
costs.
|
||||
|
||||
Other methods See |iccf-donations|.
|
||||
Include "Vim sponsor" or "Vim registration" in the comment of
|
||||
your money transfer. Send me an e-mail that mentions the
|
||||
amount you transferred if you want to vote for features and
|
||||
show others you are a registered Vim user or sponsor.
|
||||
|
||||
Cash Small amounts can be sent with ordinary mail. Put something
|
||||
around the money, so that it's not noticeable from the
|
||||
outside. Mention your e-mail address if you want to vote for
|
||||
features and show others you are a registered Vim user or
|
||||
sponsor.
|
||||
|
||||
You can use this permanent address:
|
||||
Bram Moolenaar
|
||||
Finsterruetihof 1
|
||||
8134 Adliswil
|
||||
Switzerland
|
||||
|
||||
|
||||
|
||||
QUESTIONS AND ANSWERS *sponsor-faq* *register-faq*
|
||||
|
||||
Why should I give money?
|
||||
|
||||
If you do not show your appreciation for Vim then Bram will be less motivated
|
||||
to fix bugs and add new features. He will do something else instead.
|
||||
|
||||
|
||||
How much money should I send?
|
||||
|
||||
That is up to you. The more you give, the more children will be helped.
|
||||
An indication for individuals that use Vim at home: 10 Euro per year. For
|
||||
professional use: 30 Euro per year per person. Send at least 10 euro to be
|
||||
able to vote for features.
|
||||
|
||||
|
||||
What do I get in return?
|
||||
|
||||
Each registered Vim user and sponsor who donates at least 10 euro will be able
|
||||
to vote for new features. These votes will give priority to the work on Vim.
|
||||
The votes are valid for two years. The more money you send the more your
|
||||
votes count |votes-counted|.
|
||||
|
||||
If you send 100 Euro or more in total you will be mentioned on the "Vim hall
|
||||
of honour" page on the Vim web site. But only if you enable this on your
|
||||
account page. You can also select whether the amount will be visible.
|
||||
|
||||
|
||||
How do I become a Vim sponsor or registered Vim user?
|
||||
|
||||
Send money, as explained above |send-money| and include your e-mail address.
|
||||
When the money has been received you will receive a unique registration key.
|
||||
This key can be used on the Vim website to activate voting on your Vim
|
||||
account. You will then get an extra page where you can vote for features and
|
||||
choose whether others will be able to see that you donated. There is a link
|
||||
to this page on your "My Account" page.
|
||||
|
||||
|
||||
What is the difference between sponsoring and registering?
|
||||
|
||||
It has a different name. Use the term "registration" if your boss doesn't
|
||||
like "sponsoring" or "donation". The benefits are the same.
|
||||
|
||||
|
||||
How can I send money?
|
||||
|
||||
See |send-money|. Check the web site for the most recent information:
|
||||
http://www.vim.org/sponsor/
|
||||
|
||||
|
||||
Why don't you use the SourceForge donation system?
|
||||
|
||||
SourceForge takes 5% of the donations for themselves. If you want to support
|
||||
SourceForge you can send money to them directly.
|
||||
|
||||
|
||||
I cannot afford to send money, may I still use Vim?
|
||||
|
||||
Yes.
|
||||
|
||||
|
||||
I did not register Vim, can I use all available features?
|
||||
|
||||
Yes.
|
||||
|
||||
|
||||
I noticed a bug, do I need to register before I can report it?
|
||||
|
||||
No, suggestions for improving Vim can always be given. For improvements use
|
||||
the developer |maillist|, for reporting bugs see |bugs|.
|
||||
|
||||
|
||||
How are my votes counted? *votes-counted*
|
||||
|
||||
You may vote when you send 10 euro or more. You can enter up to ten votes.
|
||||
You can select the same item several times to give it more points. You can
|
||||
also enter three counter votes, these count as negative points.
|
||||
|
||||
When you send 30 euro or more the points are doubled. Above 100 euro they
|
||||
count four times, above 300 euro they count six times, above 1000 euro ten
|
||||
times.
|
||||
|
||||
|
||||
Can I change my votes?
|
||||
|
||||
You can change your votes any time you like, up to two years after you
|
||||
sent money. The points will be counted right away.
|
||||
|
||||
|
||||
Can I add an item to vote on?
|
||||
|
||||
Not directly. You can suggest items to vote on to Bram. He will consider
|
||||
fitting your item into the list.
|
||||
|
||||
|
||||
How about Charityware?
|
||||
|
||||
Currently the Vim donations go to |uganda| anyway. Thus it doesn't matter if
|
||||
you sponsor Vim or ICCF. Except that Vim sponsoring will allow you to vote
|
||||
for features.
|
||||
|
||||
|
||||
I donated $$$, now please add feature XYZ!
|
||||
|
||||
There is no direct relation between your donation and the work Bram does.
|
||||
Otherwise you would be paying for work and we would have to pay tax over the
|
||||
donation. If you want to hire Bram for specific work, contact him directly,
|
||||
don't use the donation system.
|
||||
|
||||
|
||||
Are the donations tax deductible?
|
||||
|
||||
That depends on your country. The donations to help the children in |Uganda|
|
||||
are tax deductible in Holland, Germany, Canada and in the USA. See the ICCF
|
||||
website http://iccf-holland.org/donate.html. You must send an e-mail to Bram
|
||||
to let him know that the donation is done because of the use of Vim.
|
||||
|
||||
|
||||
Can you send me a bill?
|
||||
|
||||
No, because there is no relation between the money you send and the work that
|
||||
is done. But a receipt is possible.
|
||||
|
||||
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
|
@ -410,20 +410,17 @@ accordingly. Vim proceeds in this order:
|
|||
|
||||
3. Execute Ex commands, from environment variables and/or files
|
||||
An environment variable is read as one Ex command line, where multiple
|
||||
commands must be separated with '|' or "<NL>".
|
||||
*init.vim* *vimrc* *exrc*
|
||||
A file that contains initialization commands is called a "vimrc" file.
|
||||
Each line in a vimrc file is executed as an Ex command line. It is
|
||||
sometimes also referred to as "exrc" file. They are the same type of
|
||||
file, but "exrc" is what Vi always used, "vimrc" is a Vim specific
|
||||
name, "init.vim" is Neovim specific location for vimrc file. Also see
|
||||
|vimrc-intro|.
|
||||
commands must be separated with '|' or <NL>.
|
||||
*config* *init.vim* *vimrc* *exrc*
|
||||
A file that contains initialization commands is generically called
|
||||
a "vimrc" or config file. Each line in a vimrc file is executed as an
|
||||
Ex command line. See also |vimrc-intro| and |base-directories|.
|
||||
|
||||
Places for your personal initializations (see |base-directories|):
|
||||
Unix $XDG_CONFIG_HOME/nvim/init.vim
|
||||
(default for $XDG_CONFIG_HOME is ~/.config)
|
||||
Windows $XDG_CONFIG_HOME/nvim/init.vim
|
||||
(default for $XDG_CONFIG_HOME is ~/AppData/Local)
|
||||
The Nvim config file is named "init.vim", located at:
|
||||
Unix ~/.config/nvim/init.vim
|
||||
Windows ~/AppData/Local/nvim/init.vim
|
||||
Or if |$XDG_CONFIG_HOME| is defined:
|
||||
$XDG_CONFIG_HOME/nvim/init.vim
|
||||
|
||||
RECOMMENDATION: Put all your Vim configuration stuff in the
|
||||
$HOME/.config/nvim/ directory. That makes it easy to copy it to
|
||||
|
@ -439,10 +436,11 @@ accordingly. Vim proceeds in this order:
|
|||
If Vim was started in Ex mode with the "-s" argument, all following
|
||||
initializations until 4. are skipped. Only the "-u" option is
|
||||
interpreted.
|
||||
*system-vimrc*
|
||||
a. For Unix, MS-Windows, and Macintosh, the system vimrc file is read for
|
||||
initializations. The path of this file is shown with the
|
||||
":version" command. Mostly it's "$VIM/vimrc".
|
||||
*system-vimrc* *sysinit.vim*
|
||||
a. The system vimrc file is read for initializations. If
|
||||
nvim/sysinit.vim file exists in one of $XDG_CONFIG_DIRS, it will be
|
||||
used. Otherwise, the system vimrc file is used. The path of this file
|
||||
is shown with the ":version" command. Mostly it's "$VIM/sysinit.vim".
|
||||
|
||||
*VIMINIT* *EXINIT* *$MYVIMRC*
|
||||
b. Four places are searched for initializations. The first that exists
|
||||
|
|
|
@ -167,7 +167,7 @@ the editor.
|
|||
mouse support is active. Some options like 'ambiwidth' have already
|
||||
taken effect on the grid, where appropriate empty cells are added,
|
||||
however a UI might still use such options when rendering raw text
|
||||
sent from Nvim, like for |ui-ext-cmdline|.
|
||||
sent from Nvim, like for |ui-cmdline|.
|
||||
|
||||
["mode_change", mode, mode_idx]
|
||||
The mode changed. The first parameter `mode` is a string representing
|
||||
|
@ -325,14 +325,14 @@ numerical highlight `id`:s to the actual attributes.
|
|||
+-------------------------+ src_top |
|
||||
| src (moved up) and dst | |
|
||||
|-------------------------| dst_bot |
|
||||
| src (cleared) | |
|
||||
| src (invalid) | |
|
||||
+=========================+ src_bot
|
||||
<
|
||||
If `rows` is less than zero, move a rectangle in the SR down, this can
|
||||
happen while scrolling up.
|
||||
>
|
||||
+=========================+ src_top
|
||||
| src (cleared) | |
|
||||
| src (invalid) | |
|
||||
|------------------------ | dst_top |
|
||||
| src (moved down) and dst| |
|
||||
+-------------------------+ src_bot |
|
||||
|
@ -348,6 +348,10 @@ numerical highlight `id`:s to the actual attributes.
|
|||
end-exclusive, which is consistent with API conventions, but different
|
||||
from `set_scroll_region` which was end-inclusive.
|
||||
|
||||
The scrolled-in area will be filled using |ui-event-grid_line| directly
|
||||
after the scroll event. The UI thus doesn't need to clear this area as
|
||||
part of handling the scroll event.
|
||||
|
||||
==============================================================================
|
||||
Legacy Grid Events (cell based) *ui-grid-old*
|
||||
|
||||
|
|
|
@ -68,9 +68,9 @@ For more info see |vimrc|.
|
|||
==============================================================================
|
||||
*01.3* Using the Vim tutor *tutor* *vimtutor*
|
||||
|
||||
Instead of reading the text (boring!) you can use the vimtutor to learn your
|
||||
first Vim commands. This is a 30 minute tutorial that teaches the most basic
|
||||
Vim functionality hands-on.
|
||||
Instead of reading the text (boring!) you can use :Tutor to learn your first
|
||||
Vim commands. This is a 30 minute tutorial that teaches the most basic Vim
|
||||
functionality hands-on.
|
||||
|
||||
To start the tutorial, execute >
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ Where can you find plugins?
|
|||
- Some come with Vim. You can find them in the directory $VIMRUNTIME/macros
|
||||
and its sub-directories and under $VIM/vimfiles/pack/dist/opt/.
|
||||
- Download from the net. There is a large collection on http://www.vim.org.
|
||||
- They are sometimes posted in a Vim |maillist|.
|
||||
- They are sometimes posted in a Vim maillist.
|
||||
- You could write one yourself, see |write-plugin|.
|
||||
|
||||
|
||||
|
|
|
@ -203,8 +203,7 @@ USING UNICODE IN A UNICODE TERMINAL
|
|||
|
||||
There are terminals that support Unicode directly. The standard xterm that
|
||||
comes with XFree86 is one of them. Let's use that as an example.
|
||||
First of all, the xterm must have been compiled with Unicode support. See
|
||||
|UTF8-xterm| how to check that and how to compile it when needed.
|
||||
First of all, the xterm must have been compiled with Unicode support.
|
||||
Start the xterm with the "-u8" argument. You might also need so specify a
|
||||
font. Example: >
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ T *+tag_binary* binary searching in tags file |tag-binary-search|
|
|||
N *+tag_old_static* old method for static tags |tag-old-static|
|
||||
m *+tag_any_white* any white space allowed in tags file |tag-any-white|
|
||||
B *+termguicolors* 24-bit color in xterm-compatible terminals support
|
||||
N *+termresponse* support for |t_RV| and |v:termresponse|
|
||||
N *+termresponse* support for t_RV and |v:termresponse|
|
||||
N *+textobjects* |text-objects| selection
|
||||
N *+timers* the |timer_start()| function
|
||||
N *+title* Setting the window 'title' and 'icon'
|
||||
|
@ -517,14 +517,9 @@ m *+xim* X input method |xim|
|
|||
:silent! /^begin
|
||||
:if v:errmsg != ""
|
||||
: ... pattern was not found
|
||||
< ":silent" will also avoid the hit-enter prompt. When
|
||||
using this for an external command, this may cause the
|
||||
screen to be messed up. Use |CTRL-L| to clean it up
|
||||
then.
|
||||
":silent menu ..." defines a menu that will not echo a
|
||||
Command-line command. The command will still produce
|
||||
messages though. Use ":silent" in the command itself
|
||||
to avoid that: ":silent menu .... :silent command".
|
||||
< ":silent" also skips the hit-enter prompt.
|
||||
Dialogs that prompt for user input (|confirm()|,
|
||||
'swapfile', …) are never silent.
|
||||
|
||||
*:uns* *:unsilent*
|
||||
:uns[ilent] {command} Execute {command} not silently. Only makes a
|
||||
|
|
|
@ -27,6 +27,7 @@ a complete and centralized reference of those differences.
|
|||
|
||||
- 'autoindent' is set by default
|
||||
- 'autoread' is set by default
|
||||
- 'background' always defaults to "dark"
|
||||
- 'backspace' defaults to "indent,eol,start"
|
||||
- 'backupdir' defaults to .,~/.local/share/nvim/backup (|xdg|)
|
||||
- 'belloff' defaults to "all"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require('vim.compat')
|
||||
|
||||
local buf_hls = {}
|
||||
|
||||
local function highlight_line(line, linenr)
|
||||
|
@ -10,9 +12,9 @@ local function highlight_line(line, linenr)
|
|||
local attr = NONE
|
||||
local byte = 0 -- byte offset
|
||||
|
||||
local function end_attr_hl(attr)
|
||||
local function end_attr_hl(attr_)
|
||||
for i, hl in ipairs(hls) do
|
||||
if hl.attr == attr and hl.final == -1 then
|
||||
if hl.attr == attr_ and hl.final == -1 then
|
||||
hl.final = byte
|
||||
hls[i] = hl
|
||||
end
|
||||
|
@ -106,7 +108,7 @@ local function highlight_line(line, linenr)
|
|||
-- the range 0x20 - 0x3f, then 'm'. (See ECMA-48, sections 5.4 & 8.3.117)
|
||||
local sgr = prev_char:match("^%[([\032-\063]*)m$")
|
||||
if sgr then
|
||||
local match = ''
|
||||
local match
|
||||
while sgr and #sgr > 0 do
|
||||
-- Match against SGR parameters, which may be separated by ';'
|
||||
match, sgr = sgr:match("^(%d*);?(.*)")
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
-- Lua 5.1 forward-compatibility layer.
|
||||
-- For background see https://github.com/neovim/neovim/pull/9280
|
||||
--
|
||||
-- Reference the lua-compat-5.2 project for hints:
|
||||
-- https://github.com/keplerproject/lua-compat-5.2/blob/c164c8f339b95451b572d6b4b4d11e944dc7169d/compat52/mstrict.lua
|
||||
-- https://github.com/keplerproject/lua-compat-5.2/blob/c164c8f339b95451b572d6b4b4d11e944dc7169d/tests/test.lua
|
||||
|
||||
local lua_version = _VERSION:sub(-3)
|
||||
|
||||
if lua_version >= "5.2" then
|
||||
unpack = table.unpack -- luacheck: ignore 121 143
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
" cfilter.vim: Plugin to filter entries from a quickfix/location list
|
||||
" Last Change: May 12, 2018
|
||||
" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
|
||||
" Version: 1.0
|
||||
"
|
||||
" Commands to filter the quickfix list:
|
||||
" :Cfilter[!] {pat}
|
||||
" Create a new quickfix list from entries matching {pat} in the current
|
||||
" quickfix list. Both the file name and the text of the entries are
|
||||
" matched against {pat}. If ! is supplied, then entries not matching
|
||||
" {pat} are used.
|
||||
" :Lfilter[!] {pat}
|
||||
" Same as :Cfilter but operates on the current location list.
|
||||
"
|
||||
if exists("loaded_cfilter")
|
||||
finish
|
||||
endif
|
||||
let loaded_cfilter = 1
|
||||
|
||||
func s:Qf_filter(qf, pat, bang)
|
||||
if a:qf
|
||||
let Xgetlist = function('getqflist')
|
||||
let Xsetlist = function('setqflist')
|
||||
let cmd = ':Cfilter' . a:bang
|
||||
else
|
||||
let Xgetlist = function('getloclist', [0])
|
||||
let Xsetlist = function('setloclist', [0])
|
||||
let cmd = ':Lfilter' . a:bang
|
||||
endif
|
||||
|
||||
if a:bang == '!'
|
||||
let cond = 'v:val.text !~# a:pat && bufname(v:val.bufnr) !~# a:pat'
|
||||
else
|
||||
let cond = 'v:val.text =~# a:pat || bufname(v:val.bufnr) =~# a:pat'
|
||||
endif
|
||||
|
||||
let items = filter(Xgetlist(), cond)
|
||||
let title = cmd . ' ' . a:pat
|
||||
call Xsetlist([], ' ', {'title' : title, 'items' : items})
|
||||
endfunc
|
||||
|
||||
com! -nargs=+ -bang Cfilter call s:Qf_filter(1, <q-args>, <q-bang>)
|
||||
com! -nargs=+ -bang Lfilter call s:Qf_filter(0, <q-args>, <q-bang>)
|
|
@ -1,19 +0,0 @@
|
|||
The plugin directory is for standard Vim plugin scripts.
|
||||
|
||||
All files here ending in .vim will be sourced by Vim when it starts up.
|
||||
Look in the file for hints on how it can be disabled without deleting it.
|
||||
|
||||
getscriptPlugin.vim get latest version of Vim scripts
|
||||
gzip.vim edit compressed files
|
||||
matchparen.vim highlight paren matching the one under the cursor
|
||||
netrwPlugin.vim edit files over a network and browse (remote) directories
|
||||
rrhelper.vim used for --remote-wait editing
|
||||
spellfile.vim download a spellfile when it's missing
|
||||
tarPlugin.vim edit (compressed) tar files
|
||||
tohtml.vim convert a file with syntax highlighting to HTML
|
||||
vimballPlugin.vim create and unpack .vba files
|
||||
zipPlugin.vim edit zip archives
|
||||
|
||||
Note: the explorer.vim plugin is no longer here, the netrw.vim plugin has
|
||||
taken over browsing directories (also for remote directories).
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
" matchit.vim: (global plugin) Extended "%" matching
|
||||
" Last Change: 2017 Sep 15
|
||||
" Last Change: 2018 Jul 3 by Christian Brabandt
|
||||
" Maintainer: Benji Fisher PhD <benji@member.AMS.org>
|
||||
" Version: 1.13.3, for Vim 6.3+
|
||||
" Fix from Tommy Allen included.
|
||||
|
@ -268,7 +268,7 @@ function! s:Match_wrapper(word, forward, mode) range
|
|||
" execute "normal!" . curcol . "l"
|
||||
" endif
|
||||
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
|
||||
let skip = "0"
|
||||
let skip = '0'
|
||||
else
|
||||
execute "if " . skip . "| let skip = '0' | endif"
|
||||
endif
|
||||
|
@ -708,10 +708,16 @@ fun! s:MultiMatch(spflag, mode)
|
|||
let openpat = substitute(openpat, ',', '\\|', 'g')
|
||||
let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
|
||||
let closepat = substitute(closepat, ',', '\\|', 'g')
|
||||
|
||||
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
|
||||
let skip = '0'
|
||||
else
|
||||
execute "if " . skip . "| let skip = '0' | endif"
|
||||
try
|
||||
execute "if " . skip . "| let skip = '0' | endif"
|
||||
catch /^Vim\%((\a\+)\)\=:E363/
|
||||
" We won't find anything, so skip searching, should keep Vim responsive.
|
||||
return {}
|
||||
endtry
|
||||
endif
|
||||
mark '
|
||||
let level = v:count1
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
" Vim plugin for showing matching parens
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2018 Jun 23
|
||||
" Last Change: 2018 Jul 3
|
||||
|
||||
" Exit quickly when:
|
||||
" - this plugin was already loaded (or disabled)
|
||||
|
@ -103,18 +103,28 @@ function! s:Highlight_Matching_Pair()
|
|||
call cursor(c_lnum, c_col - before)
|
||||
endif
|
||||
|
||||
" Build an expression that detects whether the current cursor position is in
|
||||
" certain syntax types (string, comment, etc.), for use as searchpairpos()'s
|
||||
" skip argument.
|
||||
" We match "escape" for special items, such as lispEscapeSpecial.
|
||||
let s_skip = '!empty(filter(map(synstack(line("."), col(".")), ''synIDattr(v:val, "name")''), ' .
|
||||
if !has("syntax") || !exists("g:syntax_on")
|
||||
let s_skip = "0"
|
||||
else
|
||||
" Build an expression that detects whether the current cursor position is
|
||||
" in certain syntax types (string, comment, etc.), for use as
|
||||
" searchpairpos()'s skip argument.
|
||||
" We match "escape" for special items, such as lispEscapeSpecial.
|
||||
let s_skip = '!empty(filter(map(synstack(line("."), col(".")), ''synIDattr(v:val, "name")''), ' .
|
||||
\ '''v:val =~? "string\\|character\\|singlequote\\|escape\\|comment"''))'
|
||||
" If executing the expression determines that the cursor is currently in
|
||||
" one of the syntax types, then we want searchpairpos() to find the pair
|
||||
" within those syntax types (i.e., not skip). Otherwise, the cursor is
|
||||
" outside of the syntax types and s_skip should keep its value so we skip any
|
||||
" matching pair inside the syntax types.
|
||||
execute 'if' s_skip '| let s_skip = 0 | endif'
|
||||
" If executing the expression determines that the cursor is currently in
|
||||
" one of the syntax types, then we want searchpairpos() to find the pair
|
||||
" within those syntax types (i.e., not skip). Otherwise, the cursor is
|
||||
" outside of the syntax types and s_skip should keep its value so we skip
|
||||
" any matching pair inside the syntax types.
|
||||
" Catch if this throws E363: pattern uses more memory than 'maxmempattern'.
|
||||
try
|
||||
execute 'if ' . s_skip . ' | let s_skip = "0" | endif'
|
||||
catch /^Vim\%((\a\+)\)\=:E363/
|
||||
" We won't find anything, so skip searching, should keep Vim responsive.
|
||||
return
|
||||
endtry
|
||||
endif
|
||||
|
||||
" Limit the search to lines visible in the window.
|
||||
let stoplinebottom = line('w$')
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
" Vim plugin with helper function(s) for --remote-wait
|
||||
" Maintainer: Flemming Madsen <fma@cci.dk>
|
||||
" Last Change: 2008 May 29
|
||||
|
||||
" Has this already been loaded?
|
||||
if exists("loaded_rrhelper") || !has("clientserver")
|
||||
finish
|
||||
endif
|
||||
let loaded_rrhelper = 1
|
||||
|
||||
" Setup answers for a --remote-wait client who will assume
|
||||
" a SetupRemoteReplies() function in the command server
|
||||
|
||||
function SetupRemoteReplies()
|
||||
let cnt = 0
|
||||
let max = argc()
|
||||
|
||||
let id = expand("<client>")
|
||||
if id == 0
|
||||
return
|
||||
endif
|
||||
while cnt < max
|
||||
" Handle same file from more clients and file being more than once
|
||||
" on the command line by encoding this stuff in the group name
|
||||
let uniqueGroup = "RemoteReply_".id."_".cnt
|
||||
|
||||
" Path separators are always forward slashes for the autocommand pattern.
|
||||
" Escape special characters with a backslash.
|
||||
let f = substitute(argv(cnt), '\\', '/', "g")
|
||||
if exists('*fnameescape')
|
||||
let f = fnameescape(f)
|
||||
else
|
||||
let f = escape(f, " \t\n*?[{`$\\%#'\"|!<")
|
||||
endif
|
||||
execute "augroup ".uniqueGroup
|
||||
execute "autocmd ".uniqueGroup." BufUnload ". f ." call DoRemoteReply('".id."', '".cnt."', '".uniqueGroup."', '". f ."')"
|
||||
let cnt = cnt + 1
|
||||
endwhile
|
||||
augroup END
|
||||
endfunc
|
||||
|
||||
function DoRemoteReply(id, cnt, group, file)
|
||||
call server2client(a:id, a:cnt)
|
||||
execute 'autocmd! '.a:group.' BufUnload '.a:file
|
||||
execute 'augroup! '.a:group
|
||||
endfunc
|
||||
|
||||
" vim: set sw=2 sts=2 :
|
|
@ -0,0 +1,68 @@
|
|||
" Test for URLs in help documents.
|
||||
"
|
||||
" Opens a new window with all found URLS followed by return code from curl
|
||||
" (anything other than 0 means unreachable)
|
||||
"
|
||||
" Written by Christian Brabandt.
|
||||
|
||||
func Test_check_URLs()
|
||||
if has("win32")
|
||||
echoerr "Doesn't work on MS-Windows"
|
||||
return
|
||||
endif
|
||||
if executable('curl')
|
||||
" Note: does not follow redirects!
|
||||
let s:command = 'curl --silent --fail --output /dev/null --head '
|
||||
elseif executable('wget')
|
||||
" Note: only allow a couple of redirects
|
||||
let s:command = 'wget --quiet -S --spider --max-redirect=2 --timeout=5 --tries=2 -O /dev/null '
|
||||
else
|
||||
echoerr 'Only works when "curl" or "wget" is available'
|
||||
return
|
||||
endif
|
||||
|
||||
let pat='\(https\?\|ftp\)://[^\t* ]\+'
|
||||
exe 'helpgrep' pat
|
||||
helpclose
|
||||
|
||||
let urls = map(getqflist(), 'v:val.text')
|
||||
" do not use submatch(1)!
|
||||
let urls = map(urls, {key, val -> matchstr(val, pat)})
|
||||
" remove examples like user@host (invalid urls)
|
||||
let urls = filter(urls, 'v:val !~ "@"')
|
||||
" Remove example URLs which are invalid
|
||||
let urls = filter(urls, {key, val -> val !~ '\<\(\(my\|some\)\?host\|machine\|hostname\|file\)\>'})
|
||||
new
|
||||
put =urls
|
||||
" remove some more invalid items
|
||||
" empty lines
|
||||
v/./d
|
||||
" remove # anchors
|
||||
%s/#.*$//e
|
||||
" remove trailing stuff (parenthesis, dot, comma, quotes), but only for HTTP
|
||||
" links
|
||||
g/^h/s#[.,)'"/>][:.]\?$##
|
||||
g#^[hf]t\?tp:/\(/\?\.*\)$#d
|
||||
silent! g/ftp://,$/d
|
||||
silent! g/=$/d
|
||||
let a = getline(1,'$')
|
||||
let a = uniq(sort(a))
|
||||
%d
|
||||
call setline(1, a)
|
||||
|
||||
" Do the testing.
|
||||
set nomore
|
||||
%s/.*/\=TestURL(submatch(0))/
|
||||
|
||||
" highlight the failures
|
||||
/.* \([0-9]*[1-9]\|[0-9]\{2,}\)$
|
||||
endfunc
|
||||
|
||||
func TestURL(url)
|
||||
" Relies on the return code to determine whether a page is valid
|
||||
echom printf("Testing URL: %d/%d %s", line('.'), line('$'), a:url)
|
||||
call system(s:command . shellescape(a:url))
|
||||
return printf("%s %d", a:url, v:shell_error)
|
||||
endfunc
|
||||
|
||||
call Test_check_URLs()
|
|
@ -0,0 +1,355 @@
|
|||
# Converts Vim/Nvim documentation to HTML.
|
||||
#
|
||||
# Adapted from https://github.com/c4rlo/vimhelp/
|
||||
# License: MIT
|
||||
#
|
||||
# Copyright (c) 2016 Carlo Teubner
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
import re, urllib.parse
|
||||
from itertools import chain
|
||||
|
||||
HEAD = """\
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset={encoding}"/>
|
||||
<title>Nvim: {filename}</title>
|
||||
"""
|
||||
|
||||
HEAD_END = '</head>\n<body>\n'
|
||||
|
||||
INTRO = """
|
||||
<h1>Nvim help files</h1>
|
||||
<p>HTML export of the <a href="https://neovim.io/">Nvim</a> help pages{vers-note}.
|
||||
Updated <a href="https://github.com/neovim/bot-ci" class="d">automatically</a> from the <a
|
||||
href="https://github.com/vim/vim/tree/master/runtime/doc" class="d">Nvim source repository</a>.
|
||||
Also includes the <a href="vim_faq.txt.html">Vim FAQ</a>, pulled from its
|
||||
<a href="https://github.com/chrisbra/vim_faq" class="d">source repository</a>.</p>
|
||||
"""
|
||||
|
||||
VERSION_NOTE = ", current as of Vim {version}"
|
||||
|
||||
SITENAVI_LINKS = """
|
||||
Quick links:
|
||||
<a href="/">help overview</a> ·
|
||||
<a href="quickref.txt.html">quick reference</a> ·
|
||||
<a href="usr_toc.txt.html">user manual toc</a> ·
|
||||
<a href="{helptxt}#reference_toc">reference manual toc</a> ·
|
||||
<a href="vim_faq.txt.html">faq</a>
|
||||
"""
|
||||
|
||||
SITENAVI_LINKS_PLAIN = SITENAVI_LINKS.format(helptxt='help.txt.html')
|
||||
SITENAVI_LINKS_WEB = SITENAVI_LINKS.format(helptxt='/')
|
||||
|
||||
SITENAVI_PLAIN = '<p>' + SITENAVI_LINKS_PLAIN + '</p>'
|
||||
SITENAVI_WEB = '<p>' + SITENAVI_LINKS_WEB + '</p>'
|
||||
|
||||
SITENAVI_SEARCH = '<table width="100%"><tbody><tr><td>' + SITENAVI_LINKS_WEB + \
|
||||
'</td><td style="text-align: right; max-width: 25vw"><div class="gcse-searchbox">' \
|
||||
'</div></td></tr></tbody></table><div class="gcse-searchresults"></div>'
|
||||
|
||||
TEXTSTART = """
|
||||
<div id="d1">
|
||||
<pre id="sp"> </pre>
|
||||
<div id="d2">
|
||||
<pre>
|
||||
"""
|
||||
|
||||
FOOTER = '</pre>'
|
||||
|
||||
FOOTER2 = """
|
||||
<p id="footer">This site is maintained by Carlo Teubner (<i>(my first name) dot (my last name) at gmail dot com</i>).</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
VIM_FAQ_LINE = '<a href="vim_faq.txt.html#vim_faq.txt" class="l">' \
|
||||
'vim_faq.txt</a> Frequently Asked Questions\n'
|
||||
|
||||
RE_TAGLINE = re.compile(r'(\S+)\s+(\S+)')
|
||||
|
||||
PAT_WORDCHAR = '[!#-)+-{}~\xC0-\xFF]'
|
||||
|
||||
PAT_HEADER = r'(^.*~$)'
|
||||
PAT_GRAPHIC = r'(^.* `$)'
|
||||
PAT_PIPEWORD = r'(?<!\\)\|([#-)!+-~]+)\|'
|
||||
PAT_STARWORD = r'\*([#-)!+-~]+)\*(?:(?=\s)|$)'
|
||||
PAT_COMMAND = r'`([^` ]+)`'
|
||||
PAT_OPTWORD = r"('(?:[a-z]{2,}|t_..)')"
|
||||
PAT_CTRL = r'(CTRL-(?:W_)?(?:\{char\}|<[A-Za-z]+?>|.)?)'
|
||||
PAT_SPECIAL = r'(<.+?>|\{.+?}|' \
|
||||
r'\[(?:range|line|count|offset|\+?cmd|[-+]?num|\+\+opt|' \
|
||||
r'arg|arguments|ident|addr|group)]|' \
|
||||
r'(?<=\s)\[[-a-z^A-Z0-9_]{2,}])'
|
||||
PAT_TITLE = r'(Vim version [0-9.a-z]+|VIM REFERENCE.*)'
|
||||
PAT_NOTE = r'((?<!' + PAT_WORDCHAR + r')(?:note|NOTE|Notes?):?' \
|
||||
r'(?!' + PAT_WORDCHAR + r'))'
|
||||
PAT_URL = r'((?:https?|ftp)://[^\'"<> \t]+[a-zA-Z0-9/])'
|
||||
PAT_WORD = r'((?<!' + PAT_WORDCHAR + r')' + PAT_WORDCHAR + r'+' \
|
||||
r'(?!' + PAT_WORDCHAR + r'))'
|
||||
|
||||
RE_LINKWORD = re.compile(
|
||||
PAT_OPTWORD + '|' +
|
||||
PAT_CTRL + '|' +
|
||||
PAT_SPECIAL)
|
||||
RE_TAGWORD = re.compile(
|
||||
PAT_HEADER + '|' +
|
||||
PAT_GRAPHIC + '|' +
|
||||
PAT_PIPEWORD + '|' +
|
||||
PAT_STARWORD + '|' +
|
||||
PAT_COMMAND + '|' +
|
||||
PAT_OPTWORD + '|' +
|
||||
PAT_CTRL + '|' +
|
||||
PAT_SPECIAL + '|' +
|
||||
PAT_TITLE + '|' +
|
||||
PAT_NOTE + '|' +
|
||||
PAT_URL + '|' +
|
||||
PAT_WORD)
|
||||
RE_NEWLINE = re.compile(r'[\r\n]')
|
||||
RE_HRULE = re.compile(r'[-=]{3,}.*[-=]{3,3}$')
|
||||
RE_EG_START = re.compile(r'(?:.* )?>$')
|
||||
RE_EG_END = re.compile(r'\S')
|
||||
RE_SECTION = re.compile(r'[-A-Z .][-A-Z0-9 .()]*(?=\s+\*)')
|
||||
RE_STARTAG = re.compile(r'\s\*([^ \t|]+)\*(?:\s|$)')
|
||||
RE_LOCAL_ADD = re.compile(r'LOCAL ADDITIONS:\s+\*local-additions\*$')
|
||||
|
||||
class Link(object):
|
||||
__slots__ = 'link_plain_same', 'link_pipe_same', \
|
||||
'link_plain_foreign', 'link_pipe_foreign', \
|
||||
'filename'
|
||||
|
||||
def __init__(self, link_plain_same, link_plain_foreign,
|
||||
link_pipe_same, link_pipe_foreign, filename):
|
||||
self.link_plain_same = link_plain_same
|
||||
self.link_plain_foreign = link_plain_foreign
|
||||
self.link_pipe_same = link_pipe_same
|
||||
self.link_pipe_foreign = link_pipe_foreign
|
||||
self.filename = filename
|
||||
|
||||
class VimH2H(object):
|
||||
def __init__(self, tags, version=None, is_web_version=True):
|
||||
self._urls = { }
|
||||
self._version = version
|
||||
self._is_web_version = is_web_version
|
||||
for line in RE_NEWLINE.split(tags):
|
||||
m = RE_TAGLINE.match(line)
|
||||
if m:
|
||||
tag, filename = m.group(1, 2)
|
||||
self.do_add_tag(filename, tag)
|
||||
|
||||
def add_tags(self, filename, contents):
|
||||
for match in RE_STARTAG.finditer(contents):
|
||||
tag = match.group(1).replace('\\', '\\\\').replace('/', '\\/')
|
||||
self.do_add_tag(str(filename), tag)
|
||||
|
||||
def do_add_tag(self, filename, tag):
|
||||
tag_quoted = urllib.parse.quote_plus(tag)
|
||||
def mkpart1(doc):
|
||||
return '<a href="' + doc + '#' + tag_quoted + '" class="'
|
||||
part1_same = mkpart1('')
|
||||
if self._is_web_version and filename == 'help.txt':
|
||||
doc = '/'
|
||||
else:
|
||||
doc = filename + '.html'
|
||||
part1_foreign = mkpart1(doc)
|
||||
part2 = '">' + html_escape[tag] + '</a>'
|
||||
def mklinks(cssclass):
|
||||
return (part1_same + cssclass + part2,
|
||||
part1_foreign + cssclass + part2)
|
||||
cssclass_plain = 'd'
|
||||
m = RE_LINKWORD.match(tag)
|
||||
if m:
|
||||
opt, ctrl, special = m.groups()
|
||||
if opt is not None: cssclass_plain = 'o'
|
||||
elif ctrl is not None: cssclass_plain = 'k'
|
||||
elif special is not None: cssclass_plain = 's'
|
||||
links_plain = mklinks(cssclass_plain)
|
||||
links_pipe = mklinks('l')
|
||||
self._urls[tag] = Link(
|
||||
links_plain[0], links_plain[1],
|
||||
links_pipe[0], links_pipe[1],
|
||||
filename)
|
||||
|
||||
def maplink(self, tag, curr_filename, css_class=None):
|
||||
links = self._urls.get(tag)
|
||||
if links is not None:
|
||||
if links.filename == curr_filename:
|
||||
if css_class == 'l': return links.link_pipe_same
|
||||
else: return links.link_plain_same
|
||||
else:
|
||||
if css_class == 'l': return links.link_pipe_foreign
|
||||
else: return links.link_plain_foreign
|
||||
elif css_class is not None:
|
||||
return '<span class="' + css_class + '">' + html_escape[tag] + \
|
||||
'</span>'
|
||||
else: return html_escape[tag]
|
||||
|
||||
def to_html(self, filename, contents, encoding):
|
||||
out = [ ]
|
||||
|
||||
inexample = 0
|
||||
filename = str(filename)
|
||||
is_help_txt = (filename == 'help.txt')
|
||||
faq_line = False
|
||||
for line in RE_NEWLINE.split(contents):
|
||||
line = line.rstrip('\r\n')
|
||||
line_tabs = line
|
||||
line = line.expandtabs()
|
||||
if RE_HRULE.match(line):
|
||||
out.extend(('<span class="h">', line, '</span>\n'))
|
||||
continue
|
||||
if inexample == 2:
|
||||
if RE_EG_END.match(line):
|
||||
inexample = 0
|
||||
if line[0] == '<': line = line[1:]
|
||||
else:
|
||||
out.extend(('<span class="e">', html_escape[line],
|
||||
'</span>\n'))
|
||||
continue
|
||||
if RE_EG_START.match(line_tabs):
|
||||
inexample = 1
|
||||
line = line[0:-1]
|
||||
if RE_SECTION.match(line_tabs):
|
||||
m = RE_SECTION.match(line)
|
||||
out.extend((r'<span class="c">', m.group(0), r'</span>'))
|
||||
line = line[m.end():]
|
||||
if is_help_txt and RE_LOCAL_ADD.match(line_tabs):
|
||||
faq_line = True
|
||||
lastpos = 0
|
||||
for match in RE_TAGWORD.finditer(line):
|
||||
pos = match.start()
|
||||
if pos > lastpos:
|
||||
out.append(html_escape[line[lastpos:pos]])
|
||||
lastpos = match.end()
|
||||
header, graphic, pipeword, starword, command, opt, ctrl, \
|
||||
special, title, note, url, word = match.groups()
|
||||
if pipeword is not None:
|
||||
out.append(self.maplink(pipeword, filename, 'l'))
|
||||
elif starword is not None:
|
||||
out.extend(('<a name="', urllib.parse.quote_plus(starword),
|
||||
'" class="t">', html_escape[starword], '</a>'))
|
||||
elif command is not None:
|
||||
out.extend(('<span class="e">', html_escape[command],
|
||||
'</span>'))
|
||||
elif opt is not None:
|
||||
out.append(self.maplink(opt, filename, 'o'))
|
||||
elif ctrl is not None:
|
||||
out.append(self.maplink(ctrl, filename, 'k'))
|
||||
elif special is not None:
|
||||
out.append(self.maplink(special, filename, 's'))
|
||||
elif title is not None:
|
||||
out.extend(('<span class="i">', html_escape[title],
|
||||
'</span>'))
|
||||
elif note is not None:
|
||||
out.extend(('<span class="n">', html_escape[note],
|
||||
'</span>'))
|
||||
elif header is not None:
|
||||
out.extend(('<span class="h">', html_escape[header[:-1]],
|
||||
'</span>'))
|
||||
elif graphic is not None:
|
||||
out.append(html_escape[graphic[:-2]])
|
||||
elif url is not None:
|
||||
out.extend(('<a class="u" href="', url, '">' +
|
||||
html_escape[url], '</a>'))
|
||||
elif word is not None:
|
||||
out.append(self.maplink(word, filename))
|
||||
if lastpos < len(line):
|
||||
out.append(html_escape[line[lastpos:]])
|
||||
out.append('\n')
|
||||
if inexample == 1: inexample = 2
|
||||
if faq_line:
|
||||
out.append(VIM_FAQ_LINE)
|
||||
faq_line = False
|
||||
|
||||
header = []
|
||||
header.append(HEAD.format(encoding=encoding, filename=filename))
|
||||
header.append(HEAD_END)
|
||||
if self._is_web_version and is_help_txt:
|
||||
vers_note = VERSION_NOTE.replace('{version}', self._version) \
|
||||
if self._version else ''
|
||||
header.append(INTRO.replace('{vers-note}', vers_note))
|
||||
if self._is_web_version:
|
||||
header.append(SITENAVI_SEARCH)
|
||||
sitenavi_footer = SITENAVI_WEB
|
||||
else:
|
||||
header.append(SITENAVI_PLAIN)
|
||||
sitenavi_footer = SITENAVI_PLAIN
|
||||
header.append(TEXTSTART)
|
||||
return ''.join(chain(header, out, (FOOTER, sitenavi_footer, FOOTER2)))
|
||||
|
||||
class HtmlEscCache(dict):
|
||||
def __missing__(self, key):
|
||||
r = key.replace('&', '&') \
|
||||
.replace('<', '<') \
|
||||
.replace('>', '>')
|
||||
self[key] = r
|
||||
return r
|
||||
|
||||
html_escape = HtmlEscCache()
|
||||
|
||||
|
||||
|
||||
import sys, os, os.path
|
||||
#import cProfile
|
||||
sys.path.append('.')
|
||||
|
||||
def slurp(filename):
|
||||
try:
|
||||
with open(filename, encoding='UTF-8') as f:
|
||||
return f.read(), 'UTF-8'
|
||||
except UnicodeError:
|
||||
# 'ISO-8859-1' ?
|
||||
with open(filename, encoding='latin-1') as f:
|
||||
return f.read(), 'latin-1'
|
||||
|
||||
def usage():
|
||||
return "usage: " + sys.argv[0] + " IN_DIR OUT_DIR [BASENAMES...]"
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3: sys.exit(usage())
|
||||
|
||||
in_dir = sys.argv[1]
|
||||
out_dir = sys.argv[2]
|
||||
basenames = sys.argv[3:]
|
||||
|
||||
print( "Processing tags...")
|
||||
h2h = VimH2H(slurp(os.path.join(in_dir, 'tags'))[0], is_web_version=False)
|
||||
|
||||
if len(basenames) == 0:
|
||||
basenames = os.listdir(in_dir)
|
||||
|
||||
for basename in basenames:
|
||||
if os.path.splitext(basename)[1] != '.txt' and basename != 'tags':
|
||||
print( "Ignoring " + basename)
|
||||
continue
|
||||
print( "Processing " + basename + "...")
|
||||
path = os.path.join(in_dir, basename)
|
||||
text, encoding = slurp(path)
|
||||
outpath = os.path.join(out_dir, basename + '.html')
|
||||
of = open(outpath, 'w')
|
||||
of.write(h2h.to_html(basename, text, encoding))
|
||||
of.close()
|
||||
|
||||
main()
|
||||
#cProfile.run('main()')
|
|
@ -62,8 +62,17 @@ delete_blacklisted
|
|||
# AppDir complete. Now package it as an AppImage.
|
||||
########################################################################
|
||||
|
||||
# No need for a fancy script. AppRun can just be a symlink to nvim.
|
||||
ln -s usr/bin/nvim AppRun
|
||||
# Appimage set the ARGV0 environment variable. This causes problems in zsh.
|
||||
# To prevent this, we use wrapper script to unset ARGV0 as AppRun.
|
||||
# See https://github.com/AppImage/AppImageKit/issues/852
|
||||
#
|
||||
cat << 'EOF' > AppRun
|
||||
#!/bin/bash
|
||||
|
||||
unset ARGV0
|
||||
exec "$(dirname "$(readlink -f "${0}")")/usr/bin/nvim" ${@+"$@"}
|
||||
EOF
|
||||
chmod 755 AppRun
|
||||
|
||||
cd "$APP_BUILD_DIR" # Get out of AppImage directory.
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ package.path = nvimsrcdir .. '/?.lua;' .. package.path
|
|||
local lld = {}
|
||||
local syn_fd = io.open(syntax_file, 'w')
|
||||
lld.line_length = 0
|
||||
local w = function(s)
|
||||
local function w(s)
|
||||
syn_fd:write(s)
|
||||
if s:find('\n') then
|
||||
lld.line_length = #(s:gsub('.*\n', ''))
|
||||
|
@ -27,7 +27,7 @@ local options = require('options')
|
|||
local auevents = require('auevents')
|
||||
local ex_cmds = require('ex_cmds')
|
||||
|
||||
local cmd_kw = function(prev_cmd, cmd)
|
||||
local function cmd_kw(prev_cmd, cmd)
|
||||
if not prev_cmd then
|
||||
return cmd:sub(1, 1) .. '[' .. cmd:sub(2) .. ']'
|
||||
else
|
||||
|
@ -43,6 +43,15 @@ local cmd_kw = function(prev_cmd, cmd)
|
|||
end
|
||||
end
|
||||
|
||||
-- Exclude these from the vimCommand keyword list, they are handled specially
|
||||
-- in syntax/vim.vim (vimAugroupKey, vimAutoCmd). #9327
|
||||
local function is_autocmd_cmd(cmd)
|
||||
return (cmd == 'augroup'
|
||||
or cmd == 'autocmd'
|
||||
or cmd == 'doautocmd'
|
||||
or cmd == 'doautoall')
|
||||
end
|
||||
|
||||
vimcmd_start = 'syn keyword vimCommand contained '
|
||||
w(vimcmd_start)
|
||||
local prev_cmd = nil
|
||||
|
@ -51,7 +60,7 @@ for _, cmd_desc in ipairs(ex_cmds) do
|
|||
w('\n' .. vimcmd_start)
|
||||
end
|
||||
local cmd = cmd_desc.command
|
||||
if cmd:match('%w') and cmd ~= 'z' then
|
||||
if cmd:match('%w') and cmd ~= 'z' and not is_autocmd_cmd(cmd) then
|
||||
w(' ' .. cmd_kw(prev_cmd, cmd))
|
||||
end
|
||||
prev_cmd = cmd
|
||||
|
|
|
@ -149,8 +149,8 @@ preprocess_patch() {
|
|||
local na_src='proto\|Make*\|gui_*\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv'
|
||||
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%(testdir/\)\@<!\%('${na_src}'\)@norm! d/\v(^diff)|%$
' +w +q "$file"
|
||||
|
||||
# Remove channel.txt, netbeans.txt, os_*.txt, term.txt, todo.txt, version*.txt, tags
|
||||
local na_doc='channel\.txt\|netbeans\.txt\|os_\w\+\.txt\|term\.txt\|todo\.txt\|version\d\.txt\|tags'
|
||||
# Remove unwanted Vim doc files.
|
||||
local na_doc='channel\.txt\|netbeans\.txt\|os_\w\+\.txt\|term\.txt\|todo\.txt\|version\d\.txt\|sponsor\.txt\|intro\.txt\|tags'
|
||||
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/doc/\<\%('${na_doc}'\)\>@norm! d/\v(^diff)|%$
' +w +q "$file"
|
||||
|
||||
# Remove "Last change ..." changes in doc files.
|
||||
|
@ -179,6 +179,16 @@ preprocess_patch() {
|
|||
# Rename path to matchit plugin.
|
||||
LC_ALL=C sed -e 's@\( [ab]/runtime\)/pack/dist/opt/matchit/\(plugin/matchit.vim\)@\1/\2@g' \
|
||||
"$file" > "$file".tmp && mv "$file".tmp "$file"
|
||||
LC_ALL=C sed -e 's@\( [ab]/runtime\)/pack/dist/opt/matchit/doc/\(matchit.txt\)@\1/doc/pi_\2@g' \
|
||||
"$file" > "$file".tmp && mv "$file".tmp "$file"
|
||||
|
||||
# Rename test_urls.vim to check_urls.vim
|
||||
LC_ALL=C sed -e 's@\( [ab]\)/runtime/doc/test\(_urls.vim\)@\1/scripts/check\2@g' \
|
||||
"$file" > "$file".tmp && mv "$file".tmp "$file"
|
||||
|
||||
# Rename path to check_colors.vim
|
||||
LC_ALL=C sed -e 's@\( [ab]/runtime\)/colors/\(tools/check_colors.vim\)@\1/\2@g' \
|
||||
"$file" > "$file".tmp && mv "$file".tmp "$file"
|
||||
}
|
||||
|
||||
get_vimpatch() {
|
||||
|
|
|
@ -79,6 +79,8 @@ file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
|
|||
|
||||
file(GLOB NVIM_SOURCES *.c)
|
||||
file(GLOB NVIM_HEADERS *.h)
|
||||
file(GLOB XDIFF_SOURCES xdiff/*.c)
|
||||
file(GLOB XDIFF_HEADERS xdiff/*.h)
|
||||
|
||||
foreach(subdir
|
||||
os
|
||||
|
@ -148,12 +150,13 @@ set(CONV_SOURCES
|
|||
syntax.c
|
||||
tag.c
|
||||
window.c)
|
||||
|
||||
foreach(sfile ${CONV_SOURCES})
|
||||
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${sfile}")
|
||||
message(FATAL_ERROR "${sfile} doesn't exist (it was added to CONV_SOURCES)")
|
||||
endif()
|
||||
endforeach()
|
||||
# xdiff: inlined external project, we don't maintain it. #9306
|
||||
list(APPEND CONV_SOURCES ${XDIFF_SOURCES})
|
||||
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(
|
||||
|
@ -404,7 +407,8 @@ if(POLICY CMP0069)
|
|||
endif()
|
||||
|
||||
add_executable(nvim ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
|
||||
${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_HEADERS})
|
||||
${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_HEADERS}
|
||||
${XDIFF_SOURCES} ${XDIFF_HEADERS})
|
||||
target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES})
|
||||
install_helper(TARGETS nvim)
|
||||
|
||||
|
@ -490,6 +494,7 @@ add_library(
|
|||
EXCLUDE_FROM_ALL
|
||||
${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
|
||||
${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
|
||||
${XDIFF_SOURCES} ${XDIFF_HEADERS}
|
||||
)
|
||||
set_property(TARGET libnvim APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS})
|
||||
|
@ -514,6 +519,7 @@ else()
|
|||
EXCLUDE_FROM_ALL
|
||||
${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
|
||||
${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
|
||||
${XDIFF_SOURCES} ${XDIFF_HEADERS}
|
||||
${UNIT_TEST_FIXTURES}
|
||||
)
|
||||
target_link_libraries(nvim-test ${NVIM_TEST_LINK_LIBRARIES})
|
||||
|
|
|
@ -51,8 +51,7 @@
|
|||
///
|
||||
/// @param buffer Buffer handle
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Line count, or \`0` if the buffer has been unloaded (see
|
||||
/// |api-buffer|).
|
||||
/// @return Line count, or 0 for unloaded buffer. |api-buffer|
|
||||
Integer nvim_buf_line_count(Buffer buffer, Error *err)
|
||||
FUNC_API_SINCE(1)
|
||||
{
|
||||
|
@ -227,8 +226,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
|
|||
/// @param end Last line index (exclusive)
|
||||
/// @param strict_indexing Whether out-of-bounds should be an error.
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Array of lines. If the buffer has been unloaded then an empty array
|
||||
/// will be returned instead. (See |api-buffer|.)
|
||||
/// @return Array of lines, or empty array for unloaded buffer.
|
||||
ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
|
||||
Buffer buffer,
|
||||
Integer start,
|
||||
|
@ -491,12 +489,12 @@ end:
|
|||
try_end(err);
|
||||
}
|
||||
|
||||
/// Return the byte offset for a line.
|
||||
//
|
||||
/// The first line returns 0. UTF-8 bytes are counted, and EOL counts as one
|
||||
/// byte. 'fileformat' and 'fileencoding' are ignored. Sending in the index
|
||||
/// just below the last line gives the total byte count for the entire buffer.
|
||||
/// A final EOL is included if it would be written, see 'eol'.
|
||||
/// Returns the byte offset for a line.
|
||||
///
|
||||
/// Line 1 (index=0) has offset 0. UTF-8 bytes are counted. EOL is one byte.
|
||||
/// 'fileformat' and 'fileencoding' are ignored. The line index just after the
|
||||
/// last line gives the total byte-count of the buffer. A final EOL byte is
|
||||
/// counted if it would be written, see 'eol'.
|
||||
///
|
||||
/// Unlike |line2byte()|, throws error for out-of-bounds indexing.
|
||||
/// Returns -1 for unloaded buffer.
|
||||
|
@ -504,7 +502,7 @@ end:
|
|||
/// @param buffer Buffer handle
|
||||
/// @param index Line index
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Integer Byte offset
|
||||
/// @return Integer byte offset, or -1 for unloaded buffer.
|
||||
Integer nvim_buf_get_offset(Buffer buffer, Integer index, Error *err)
|
||||
FUNC_API_SINCE(5)
|
||||
{
|
||||
|
@ -907,34 +905,34 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
|
|||
///
|
||||
/// Useful for plugins that dynamically generate highlights to a buffer
|
||||
/// (like a semantic highlighter or linter). The function adds a single
|
||||
/// highlight to a buffer. Unlike matchaddpos() highlights follow changes to
|
||||
/// highlight to a buffer. Unlike |matchaddpos()| highlights follow changes to
|
||||
/// line numbering (as lines are inserted/removed above the highlighted line),
|
||||
/// like signs and marks do.
|
||||
///
|
||||
/// `src_id` is useful for batch deletion/updating of a set of highlights. When
|
||||
/// called with `src_id = 0`, an unique source id is generated and returned.
|
||||
/// Successive calls can pass that `src_id` to associate new highlights with
|
||||
/// the same source group. All highlights in the same group can be cleared
|
||||
/// with `nvim_buf_clear_highlight`. If the highlight never will be manually
|
||||
/// deleted, pass `src_id = -1`.
|
||||
/// Namespaces are used for batch deletion/updating of a set of highlights. To
|
||||
/// create a namespace, use |nvim_create_namespace| which returns a namespace
|
||||
/// id. Pass it in to this function as `ns_id` to add highlights to the
|
||||
/// namespace. All highlights in the same namespace can then be cleared with
|
||||
/// single call to |nvim_buf_clear_namespace|. If the highlight never will be
|
||||
/// deleted by an API call, pass `ns_id = -1`.
|
||||
///
|
||||
/// 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 plugin to synchrounously
|
||||
/// request an unique `src_id` at initialization, and later asynchronously add
|
||||
/// and clear highlights in response to buffer changes.
|
||||
/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
|
||||
/// highlight, the allocated id is then returned. If `hl_group` is the empty
|
||||
/// string no highlight is added, but a new `ns_id` is still returned. This is
|
||||
/// supported for backwards compatibility, new code should use
|
||||
/// |nvim_create_namespace| to create a new empty namespace.
|
||||
///
|
||||
/// @param buffer Buffer handle
|
||||
/// @param src_id Source group to use or 0 to use a new group,
|
||||
/// or -1 for ungrouped highlight
|
||||
/// @param ns_id namespace to use or -1 for ungrouped highlight
|
||||
/// @param hl_group Name of the highlight group to use
|
||||
/// @param line Line to highlight (zero-indexed)
|
||||
/// @param col_start Start of (byte-indexed) column range to highlight
|
||||
/// @param col_end End of (byte-indexed) column range to highlight,
|
||||
/// or -1 to highlight to end of line
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return The src_id that was used
|
||||
/// @return The ns_id that was used
|
||||
Integer nvim_buf_add_highlight(Buffer buffer,
|
||||
Integer src_id,
|
||||
Integer ns_id,
|
||||
String hl_group,
|
||||
Integer line,
|
||||
Integer col_start,
|
||||
|
@ -964,28 +962,28 @@ Integer nvim_buf_add_highlight(Buffer buffer,
|
|||
hlg_id = syn_check_group((char_u *)hl_group.data, (int)hl_group.size);
|
||||
}
|
||||
|
||||
src_id = bufhl_add_hl(buf, (int)src_id, hlg_id, (linenr_T)line+1,
|
||||
(colnr_T)col_start+1, (colnr_T)col_end);
|
||||
return src_id;
|
||||
ns_id = bufhl_add_hl(buf, (int)ns_id, hlg_id, (linenr_T)line+1,
|
||||
(colnr_T)col_start+1, (colnr_T)col_end);
|
||||
return ns_id;
|
||||
}
|
||||
|
||||
/// Clears highlights and virtual text from a given source id and range of lines
|
||||
/// Clears namespaced objects, highlights and virtual text, from a line range
|
||||
///
|
||||
/// To clear a source group in the entire buffer, pass in 0 and -1 to
|
||||
/// To clear the namespace in the entire buffer, pass in 0 and -1 to
|
||||
/// line_start and line_end respectively.
|
||||
///
|
||||
/// @param buffer Buffer handle
|
||||
/// @param src_id Highlight source group to clear, or -1 to clear all.
|
||||
/// @param ns_id Namespace to clear, or -1 to clear all namespaces.
|
||||
/// @param line_start Start of range of lines to clear
|
||||
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
|
||||
/// to end of file.
|
||||
/// to end of buffer.
|
||||
/// @param[out] err Error details, if any
|
||||
void nvim_buf_clear_highlight(Buffer buffer,
|
||||
Integer src_id,
|
||||
void nvim_buf_clear_namespace(Buffer buffer,
|
||||
Integer ns_id,
|
||||
Integer line_start,
|
||||
Integer line_end,
|
||||
Error *err)
|
||||
FUNC_API_SINCE(1)
|
||||
FUNC_API_SINCE(5)
|
||||
{
|
||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||
if (!buf) {
|
||||
|
@ -1000,7 +998,27 @@ void nvim_buf_clear_highlight(Buffer buffer,
|
|||
line_end = MAXLNUM;
|
||||
}
|
||||
|
||||
bufhl_clear_line_range(buf, (int)src_id, (int)line_start+1, (int)line_end);
|
||||
bufhl_clear_line_range(buf, (int)ns_id, (int)line_start+1, (int)line_end);
|
||||
}
|
||||
|
||||
/// Clears highlights and virtual text from namespace and range of lines
|
||||
///
|
||||
/// @deprecated use |nvim_buf_clear_namespace|.
|
||||
///
|
||||
/// @param buffer Buffer handle
|
||||
/// @param ns_id Namespace to clear, or -1 to clear all.
|
||||
/// @param line_start Start of range of lines to clear
|
||||
/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
|
||||
/// to end of file.
|
||||
/// @param[out] err Error details, if any
|
||||
void nvim_buf_clear_highlight(Buffer buffer,
|
||||
Integer ns_id,
|
||||
Integer line_start,
|
||||
Integer line_end,
|
||||
Error *err)
|
||||
FUNC_API_SINCE(1)
|
||||
{
|
||||
nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end, err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1009,15 +1027,20 @@ void nvim_buf_clear_highlight(Buffer buffer,
|
|||
/// By default (and currently the only option) the text will be placed after
|
||||
/// the buffer text. Virtual text will never cause reflow, rather virtual
|
||||
/// text will be truncated at the end of the screen line. The virtual text will
|
||||
/// begin after one cell to the right of the ordinary text, this will contain
|
||||
/// the |lcs-eol| char if set, otherwise just be a space.
|
||||
/// begin one cell (|lcs-eol| or space) after the ordinary text.
|
||||
///
|
||||
/// The same src_id can be used for both virtual text and highlights added by
|
||||
/// nvim_buf_add_highlight. Virtual text is cleared using
|
||||
/// nvim_buf_clear_highlight.
|
||||
/// Namespaces are used to support batch deletion/updating of virtual text.
|
||||
/// To create a namespace, use |nvim_create_namespace|. Virtual text is
|
||||
/// cleared using |nvim_buf_clear_namespace|. The same `ns_id` can be used for
|
||||
/// both virtual text and highlights added by |nvim_buf_add_highlight|, both
|
||||
/// can then be cleared with a single call to |nvim_buf_clear_namespace|. If the
|
||||
/// virtual text never will be cleared by an API call, pass `ns_id = -1`.
|
||||
///
|
||||
/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
|
||||
/// virtual text, the allocated id is then returned.
|
||||
///
|
||||
/// @param buffer Buffer handle
|
||||
/// @param src_id Source group to use or 0 to use a new group,
|
||||
/// @param ns_id Namespace to use or 0 to create a namespace,
|
||||
/// or -1 for a ungrouped annotation
|
||||
/// @param line Line to annotate with virtual text (zero-indexed)
|
||||
/// @param chunks A list of [text, hl_group] arrays, each representing a
|
||||
|
@ -1025,9 +1048,9 @@ void nvim_buf_clear_highlight(Buffer buffer,
|
|||
/// can be omitted for no highlight.
|
||||
/// @param opts Optional parameters. Currently not used.
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return The src_id that was used
|
||||
/// @return The ns_id that was used
|
||||
Integer nvim_buf_set_virtual_text(Buffer buffer,
|
||||
Integer src_id,
|
||||
Integer ns_id,
|
||||
Integer line,
|
||||
Array chunks,
|
||||
Dictionary opts,
|
||||
|
@ -1077,9 +1100,9 @@ Integer nvim_buf_set_virtual_text(Buffer buffer,
|
|||
kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
|
||||
}
|
||||
|
||||
src_id = bufhl_add_virt_text(buf, (int)src_id, (linenr_T)line+1,
|
||||
virt_text);
|
||||
return src_id;
|
||||
ns_id = bufhl_add_virt_text(buf, (int)ns_id, (linenr_T)line+1,
|
||||
virt_text);
|
||||
return ns_id;
|
||||
|
||||
free_exit:
|
||||
kv_destroy(virt_text);
|
||||
|
|
|
@ -46,6 +46,24 @@
|
|||
# include "api/vim.c.generated.h"
|
||||
#endif
|
||||
|
||||
void api_vim_init(void)
|
||||
FUNC_API_NOEXPORT
|
||||
{
|
||||
namespace_ids = map_new(String, handle_T)();
|
||||
}
|
||||
|
||||
void api_vim_free_all_mem(void)
|
||||
FUNC_API_NOEXPORT
|
||||
{
|
||||
String name;
|
||||
handle_T id;
|
||||
map_foreach(namespace_ids, name, id, {
|
||||
(void)id;
|
||||
xfree(name.data);
|
||||
})
|
||||
map_free(String, handle_T)(namespace_ids);
|
||||
}
|
||||
|
||||
/// Executes an ex-command.
|
||||
///
|
||||
/// On execution error: fails with VimL error, does not update v:errmsg.
|
||||
|
@ -725,6 +743,9 @@ void nvim_err_writeln(String str)
|
|||
|
||||
/// Gets the current list of buffer handles
|
||||
///
|
||||
/// Includes unlisted (unloaded/deleted) buffers, like `:ls!`.
|
||||
/// Use |nvim_buf_is_loaded()| to check if a buffer is loaded.
|
||||
///
|
||||
/// @return List of buffer handles
|
||||
ArrayOf(Buffer) nvim_list_bufs(void)
|
||||
FUNC_API_SINCE(1)
|
||||
|
@ -884,6 +905,49 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
|
|||
}
|
||||
}
|
||||
|
||||
/// create a new namespace, or get one with an exisiting name
|
||||
///
|
||||
/// Namespaces are currently used for buffer highlighting and virtual text, see
|
||||
/// |nvim_buf_add_highlight| and |nvim_buf_set_virtual_text|.
|
||||
///
|
||||
/// Namespaces can have a name of be anonymous. If `name` is a non-empty string,
|
||||
/// and a namespace already exists with that name,the existing namespace id is
|
||||
/// returned. If an empty string is used, a new anonymous namespace is returned.
|
||||
///
|
||||
/// @param name Name of the namespace or empty string
|
||||
/// @return the namespace id
|
||||
Integer nvim_create_namespace(String name)
|
||||
FUNC_API_SINCE(5)
|
||||
{
|
||||
handle_T id = map_get(String, handle_T)(namespace_ids, name);
|
||||
if (id > 0) {
|
||||
return id;
|
||||
}
|
||||
id = next_namespace_id++;
|
||||
if (name.size > 0) {
|
||||
String name_alloc = copy_string(name);
|
||||
map_put(String, handle_T)(namespace_ids, name_alloc, id);
|
||||
}
|
||||
return (Integer)id;
|
||||
}
|
||||
|
||||
/// Get existing named namespaces
|
||||
///
|
||||
/// @return dict that maps from names to namespace ids.
|
||||
Dictionary nvim_get_namespaces(void)
|
||||
FUNC_API_SINCE(5)
|
||||
{
|
||||
Dictionary retval = ARRAY_DICT_INIT;
|
||||
String name;
|
||||
handle_T id;
|
||||
|
||||
map_foreach(namespace_ids, name, id, {
|
||||
PUT(retval, name.data, INTEGER_OBJ(id));
|
||||
})
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// Subscribes to event broadcasts
|
||||
///
|
||||
/// @param channel_id Channel id (passed automatically by the dispatcher)
|
||||
|
@ -1028,7 +1092,7 @@ Array nvim_get_api_info(uint64_t channel_id)
|
|||
/// @param attributes Informal attributes describing the client. Clients might
|
||||
/// define their own keys, but the following are suggested:
|
||||
/// - "website" Website of client (for instance github repository)
|
||||
/// - "license" Informal descripton of the license, such as "Apache 2",
|
||||
/// - "license" Informal description of the license, such as "Apache 2",
|
||||
/// "GPLv3" or "MIT"
|
||||
/// - "logo" URI or path to image, preferably small logo or icon.
|
||||
/// .png or .svg format is preferred.
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/map.h"
|
||||
|
||||
EXTERN Map(String, handle_T) *namespace_ids INIT(= NULL);
|
||||
EXTERN handle_T next_namespace_id INIT(= 1);
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "api/vim.h.generated.h"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/buffer.h"
|
||||
#include "nvim/cursor.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/screen.h"
|
||||
|
@ -33,6 +34,41 @@ Buffer nvim_win_get_buf(Window window, Error *err)
|
|||
return win->w_buffer->handle;
|
||||
}
|
||||
|
||||
/// Sets the current buffer in a window, without side-effects
|
||||
///
|
||||
/// @param window Window handle
|
||||
/// @param buffer Buffer handle
|
||||
/// @param[out] err Error details, if any
|
||||
void nvim_win_set_buf(Window window, Buffer buffer, Error *err)
|
||||
FUNC_API_SINCE(5)
|
||||
{
|
||||
win_T *win = find_window_by_handle(window, err), *save_curwin = curwin;
|
||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||
tabpage_T *tab = win_find_tabpage(win), *save_curtab = curtab;
|
||||
|
||||
if (!win || !buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (switch_win(&save_curwin, &save_curtab, win, tab, false) == FAIL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to switch to window %d",
|
||||
window);
|
||||
}
|
||||
|
||||
try_start();
|
||||
int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
|
||||
if (!try_end(err) && result == FAIL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to set buffer %d",
|
||||
buffer);
|
||||
}
|
||||
|
||||
restore_win(save_curwin, save_curtab, false);
|
||||
}
|
||||
|
||||
/// Gets the cursor position in the window
|
||||
///
|
||||
/// @param window Window handle
|
||||
|
|
|
@ -26,7 +26,6 @@ void aucmd_schedule_focusgained(bool gained)
|
|||
}
|
||||
|
||||
static void do_autocmd_focusgained(bool gained)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
static bool recursive = false;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ return {
|
|||
'BufWritePre', -- before writing a buffer
|
||||
'ChanInfo', -- info was received about channel
|
||||
'ChanOpen', -- channel was opened
|
||||
'CmdLineChanged', -- command line was modified
|
||||
'CmdLineEnter', -- after entering cmdline mode
|
||||
'CmdLineLeave', -- before leaving cmdline mode
|
||||
'CmdUndefined', -- command undefined
|
||||
|
@ -33,6 +34,7 @@ return {
|
|||
'CursorHoldI', -- idem, in Insert mode
|
||||
'CursorMoved', -- cursor was moved
|
||||
'CursorMovedI', -- cursor was moved in Insert mode
|
||||
'DiffUpdated', -- diffs have been updated
|
||||
'DirChanged', -- directory changed
|
||||
'EncodingChanged', -- after changing the 'encoding' option
|
||||
'ExitPre', -- before exiting
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "nvim/api/private/handle.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/api/vim.h"
|
||||
#include "nvim/ascii.h"
|
||||
#include "nvim/assert.h"
|
||||
#include "nvim/vim.h"
|
||||
|
@ -5327,10 +5328,10 @@ int bufhl_add_hl(buf_T *buf,
|
|||
int hl_id,
|
||||
linenr_T lnum,
|
||||
colnr_T col_start,
|
||||
colnr_T col_end) {
|
||||
static int next_src_id = 1;
|
||||
colnr_T col_end)
|
||||
{
|
||||
if (src_id == 0) {
|
||||
src_id = next_src_id++;
|
||||
src_id = (int)nvim_create_namespace((String)STRING_INIT);
|
||||
}
|
||||
if (hl_id <= 0) {
|
||||
// no highlight group or invalid line, just return src_id
|
||||
|
@ -5395,9 +5396,8 @@ int bufhl_add_virt_text(buf_T *buf,
|
|||
linenr_T lnum,
|
||||
VirtText virt_text)
|
||||
{
|
||||
static int next_src_id = 1;
|
||||
if (src_id == 0) {
|
||||
src_id = next_src_id++;
|
||||
src_id = (int)nvim_create_namespace((String)STRING_INIT);
|
||||
}
|
||||
|
||||
BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true);
|
||||
|
|
|
@ -58,10 +58,10 @@ typedef struct {
|
|||
* functions that set or reset the flags.
|
||||
*
|
||||
* VALID_BOTLINE VALID_BOTLINE_AP
|
||||
* on on w_botline valid
|
||||
* off on w_botline approximated
|
||||
* off off w_botline not valid
|
||||
* on off not possible
|
||||
* on on w_botline valid
|
||||
* off on w_botline approximated
|
||||
* off off w_botline not valid
|
||||
* on off not possible
|
||||
*/
|
||||
#define VALID_WROW 0x01 /* w_wrow (window row) is valid */
|
||||
#define VALID_WCOL 0x02 /* w_wcol (window col) is valid */
|
||||
|
@ -159,7 +159,7 @@ typedef struct {
|
|||
int wo_arab;
|
||||
# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
|
||||
int wo_bri;
|
||||
# define w_p_bri w_onebuf_opt.wo_bri /* 'breakindent' */
|
||||
# define w_p_bri w_onebuf_opt.wo_bri // 'breakindent'
|
||||
char_u *wo_briopt;
|
||||
# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */
|
||||
int wo_diff;
|
||||
|
@ -412,13 +412,13 @@ typedef struct {
|
|||
* syntax state too often.
|
||||
* b_sst_array[] is allocated to hold the state for all displayed lines,
|
||||
* and states for 1 out of about 20 other lines.
|
||||
* b_sst_array pointer to an array of synstate_T
|
||||
* b_sst_len number of entries in b_sst_array[]
|
||||
* b_sst_first pointer to first used entry in b_sst_array[] or NULL
|
||||
* b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL
|
||||
* b_sst_freecount number of free entries in b_sst_array[]
|
||||
* b_sst_check_lnum entries after this lnum need to be checked for
|
||||
* validity (MAXLNUM means no check needed)
|
||||
* b_sst_array pointer to an array of synstate_T
|
||||
* b_sst_len number of entries in b_sst_array[]
|
||||
* b_sst_first pointer to first used entry in b_sst_array[] or NULL
|
||||
* b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL
|
||||
* b_sst_freecount number of free entries in b_sst_array[]
|
||||
* b_sst_check_lnum entries after this lnum need to be checked for
|
||||
* validity (MAXLNUM means no check needed)
|
||||
*/
|
||||
synstate_T *b_sst_array;
|
||||
int b_sst_len;
|
||||
|
@ -475,15 +475,15 @@ struct file_buffer {
|
|||
int b_locked; // Buffer is being closed or referenced, don't
|
||||
// let autocommands wipe it out.
|
||||
|
||||
/*
|
||||
* b_ffname has the full path of the file (NULL for no name).
|
||||
* b_sfname is the name as the user typed it (or NULL).
|
||||
* b_fname is the same as b_sfname, unless ":cd" has been done,
|
||||
* then it is the same as b_ffname (NULL for no name).
|
||||
*/
|
||||
char_u *b_ffname; /* full path file name */
|
||||
char_u *b_sfname; /* short file name */
|
||||
char_u *b_fname; /* current file name */
|
||||
//
|
||||
// b_ffname has the full path of the file (NULL for no name).
|
||||
// b_sfname is the name as the user typed it (or NULL).
|
||||
// b_fname is the same as b_sfname, unless ":cd" has been done,
|
||||
// then it is the same as b_ffname (NULL for no name).
|
||||
//
|
||||
char_u *b_ffname; // full path file name
|
||||
char_u *b_sfname; // short file name
|
||||
char_u *b_fname; // current file name
|
||||
|
||||
bool file_id_valid;
|
||||
FileID file_id;
|
||||
|
@ -587,12 +587,12 @@ struct file_buffer {
|
|||
|
||||
bool b_scanned; /* ^N/^P have scanned this buffer */
|
||||
|
||||
/* flags for use of ":lmap" and IM control */
|
||||
long b_p_iminsert; /* input mode for insert */
|
||||
long b_p_imsearch; /* input mode for search */
|
||||
#define B_IMODE_USE_INSERT -1 /* Use b_p_iminsert value for search */
|
||||
#define B_IMODE_NONE 0 /* Input via none */
|
||||
#define B_IMODE_LMAP 1 /* Input via langmap */
|
||||
// flags for use of ":lmap" and IM control
|
||||
long b_p_iminsert; // input mode for insert
|
||||
long b_p_imsearch; // input mode for search
|
||||
#define B_IMODE_USE_INSERT -1 // Use b_p_iminsert value for search
|
||||
#define B_IMODE_NONE 0 // Input via none
|
||||
#define B_IMODE_LMAP 1 // Input via langmap
|
||||
# define B_IMODE_LAST 1
|
||||
|
||||
short b_kmap_state; /* using "lmap" mappings */
|
||||
|
@ -760,7 +760,7 @@ struct file_buffer {
|
|||
/* Two special kinds of buffers:
|
||||
* help buffer - used for help files, won't use a swap file.
|
||||
* spell buffer - used for spell info, never displayed and doesn't have a
|
||||
* file name.
|
||||
* file name.
|
||||
*/
|
||||
bool b_help; /* TRUE for help file buffer (when set b_p_bt
|
||||
is "help") */
|
||||
|
@ -787,6 +787,8 @@ struct file_buffer {
|
|||
// array of channelids which have asked to receive updates for this
|
||||
// buffer.
|
||||
kvec_t(uint64_t) update_channels;
|
||||
|
||||
int b_diff_failed; // internal diff failed for this buffer
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -840,6 +842,7 @@ struct tabpage_S {
|
|||
diff_T *tp_first_diff;
|
||||
buf_T *(tp_diffbuf[DB_COUNT]);
|
||||
int tp_diff_invalid; ///< list of diffs is outdated
|
||||
int tp_diff_update; ///< update diffs before redrawing
|
||||
frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
|
||||
ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
|
||||
dict_T *tp_vars; ///< Internal variables, local to tab page.
|
||||
|
@ -916,9 +919,9 @@ typedef struct {
|
|||
/// Same as lpos_T, but with additional field len.
|
||||
typedef struct
|
||||
{
|
||||
linenr_T lnum; ///< line number
|
||||
colnr_T col; ///< column number
|
||||
int len; ///< length: 0 - to the end of line
|
||||
linenr_T lnum; ///< line number
|
||||
colnr_T col; ///< column number
|
||||
int len; ///< length: 0 - to the end of line
|
||||
} llpos_T;
|
||||
|
||||
/// posmatch_T provides an array for storing match items for matchaddpos()
|
||||
|
@ -926,10 +929,10 @@ typedef struct
|
|||
typedef struct posmatch posmatch_T;
|
||||
struct posmatch
|
||||
{
|
||||
llpos_T pos[MAXPOSMATCH]; ///< array of positions
|
||||
int cur; ///< internal position counter
|
||||
linenr_T toplnum; ///< top buffer line
|
||||
linenr_T botlnum; ///< bottom buffer line
|
||||
llpos_T pos[MAXPOSMATCH]; ///< array of positions
|
||||
int cur; ///< internal position counter
|
||||
linenr_T toplnum; ///< top buffer line
|
||||
linenr_T botlnum; ///< bottom buffer line
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1036,7 +1039,7 @@ struct window_S {
|
|||
* Recomputing is minimized by storing the result of computations.
|
||||
* Use functions in screen.c to check if they are valid and to update.
|
||||
* w_valid is a bitfield of flags, which indicate if specific values are
|
||||
* valid or need to be recomputed.
|
||||
* valid or need to be recomputed.
|
||||
*/
|
||||
int w_valid;
|
||||
pos_T w_valid_cursor; /* last known position of w_cursor, used
|
||||
|
|
|
@ -161,7 +161,6 @@ void channel_init(void)
|
|||
channels = pmap_new(uint64_t)();
|
||||
channel_alloc(kChannelStreamStderr);
|
||||
rpc_init();
|
||||
remote_ui_init();
|
||||
}
|
||||
|
||||
/// Allocates a channel.
|
||||
|
@ -284,6 +283,8 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
|
|||
uint16_t pty_width, uint16_t pty_height,
|
||||
char *term_name, varnumber_T *status_out)
|
||||
{
|
||||
assert(cwd == NULL || os_isdir_executable(cwd));
|
||||
|
||||
Channel *chan = channel_alloc(kChannelStreamProc);
|
||||
chan->on_stdout = on_stdout;
|
||||
chan->on_stderr = on_stderr;
|
||||
|
@ -605,12 +606,15 @@ static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf,
|
|||
}
|
||||
|
||||
rbuffer_consumed(buf, count);
|
||||
// if buffer wasn't consumed, a pending callback is stalled. Aggregate the
|
||||
// received data and avoid a "burst" of multiple callbacks.
|
||||
bool buffer_set = reader->buffer.ga_len > 0;
|
||||
ga_concat_len(&reader->buffer, ptr, count);
|
||||
if (!reader->buffered && !buffer_set && callback_reader_set(*reader)) {
|
||||
process_channel_event(chan, &reader->cb, type, reader, 0);
|
||||
|
||||
if (callback_reader_set(*reader) || reader->buffered) {
|
||||
// if buffer wasn't consumed, a pending callback is stalled. Aggregate the
|
||||
// received data and avoid a "burst" of multiple callbacks.
|
||||
bool buffer_set = reader->buffer.ga_len > 0;
|
||||
ga_concat_len(&reader->buffer, ptr, count);
|
||||
if (callback_reader_set(*reader) && !reader->buffered && !buffer_set) {
|
||||
process_channel_event(chan, &reader->cb, type, reader, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
972
src/nvim/diff.c
972
src/nvim/diff.c
File diff suppressed because it is too large
Load Diff
|
@ -3127,10 +3127,16 @@ static void ins_compl_restart(void)
|
|||
*/
|
||||
static void ins_compl_set_original_text(char_u *str)
|
||||
{
|
||||
/* Replace the original text entry. */
|
||||
if (compl_first_match->cp_flags & ORIGINAL_TEXT) { /* safety check */
|
||||
// Replace the original text entry.
|
||||
// The ORIGINAL_TEXT flag is either at the first item or might possibly be
|
||||
// at the last item for backward completion
|
||||
if (compl_first_match->cp_flags & ORIGINAL_TEXT) { // safety check
|
||||
xfree(compl_first_match->cp_str);
|
||||
compl_first_match->cp_str = vim_strsave(str);
|
||||
} else if (compl_first_match->cp_prev != NULL
|
||||
&& (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT)) {
|
||||
xfree(compl_first_match->cp_prev->cp_str);
|
||||
compl_first_match->cp_prev->cp_str = vim_strsave(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3189,7 +3195,8 @@ static bool ins_compl_prep(int c)
|
|||
|
||||
/* Ignore end of Select mode mapping and mouse scroll buttons. */
|
||||
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|
||||
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT) {
|
||||
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
|
||||
|| c == K_COMMAND) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -2728,6 +2728,12 @@ void ex_call(exarg_T *eap)
|
|||
lnum = eap->line1;
|
||||
for (; lnum <= eap->line2; lnum++) {
|
||||
if (eap->addr_count > 0) { // -V560
|
||||
if (lnum > curbuf->b_ml.ml_line_count) {
|
||||
// If the function deleted lines or switched to another buffer
|
||||
// the line number may become invalid.
|
||||
EMSG(_(e_invrange));
|
||||
break;
|
||||
}
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
curwin->w_cursor.coladd = 0;
|
||||
|
@ -8119,6 +8125,7 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
const int save_msg_silent = msg_silent;
|
||||
const int save_emsg_silent = emsg_silent;
|
||||
const bool save_emsg_noredir = emsg_noredir;
|
||||
const bool save_redir_off = redir_off;
|
||||
garray_T *const save_capture_ga = capture_ga;
|
||||
|
||||
if (check_secure()) {
|
||||
|
@ -8146,6 +8153,7 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
garray_T capture_local;
|
||||
ga_init(&capture_local, (int)sizeof(char), 80);
|
||||
capture_ga = &capture_local;
|
||||
redir_off = false;
|
||||
|
||||
if (argvars[0].v_type != VAR_LIST) {
|
||||
do_cmdline_cmd(tv_get_string(&argvars[0]));
|
||||
|
@ -8163,6 +8171,7 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
msg_silent = save_msg_silent;
|
||||
emsg_silent = save_emsg_silent;
|
||||
emsg_noredir = save_emsg_noredir;
|
||||
redir_off = save_redir_off;
|
||||
|
||||
ga_append(capture_ga, NUL);
|
||||
rettv->v_type = VAR_STRING;
|
||||
|
@ -10326,10 +10335,10 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
tabnr++;
|
||||
int16_t winnr = 0;
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
|
||||
winnr++;
|
||||
if (wparg != NULL && wp != wparg) {
|
||||
continue;
|
||||
}
|
||||
winnr++;
|
||||
dict_T *const d = get_win_info(wp, tabnr, winnr);
|
||||
tv_list_append_dict(rettv->vval.v_list, d);
|
||||
if (wparg != NULL) {
|
||||
|
@ -10793,17 +10802,6 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
n = true;
|
||||
}
|
||||
|
||||
if (STRICMP(name, "ruby") == 0 && n == true) {
|
||||
char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, NULL, true);
|
||||
if (rubyhost) {
|
||||
if (*rubyhost == NUL) {
|
||||
// Invalid rubyhost executable. Gem is probably not installed.
|
||||
n = false;
|
||||
}
|
||||
xfree(rubyhost);
|
||||
}
|
||||
}
|
||||
|
||||
rettv->vval.v_number = n;
|
||||
}
|
||||
|
||||
|
@ -11718,7 +11716,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
if (new_cwd && strlen(new_cwd) > 0) {
|
||||
cwd = new_cwd;
|
||||
// The new cwd must be a directory.
|
||||
if (!os_isdir((char_u *)cwd)) {
|
||||
if (!os_isdir_executable((const char *)cwd)) {
|
||||
EMSG2(_(e_invarg2), "expected valid directory");
|
||||
shell_free_argv(argv);
|
||||
return;
|
||||
|
@ -16763,7 +16761,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||
if (new_cwd && *new_cwd != NUL) {
|
||||
cwd = new_cwd;
|
||||
// The new cwd must be a directory.
|
||||
if (!os_isdir((const char_u *)cwd)) {
|
||||
if (!os_isdir_executable((const char *)cwd)) {
|
||||
EMSG2(_(e_invarg2), "expected valid directory");
|
||||
shell_free_argv(argv);
|
||||
return;
|
||||
|
@ -19244,7 +19242,8 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv,
|
|||
}
|
||||
return;
|
||||
} else if (v->di_tv.v_type != tv->v_type) {
|
||||
internal_error("set_var()");
|
||||
EMSG2(_("E963: setting %s to value with wrong type"), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19532,6 +19531,7 @@ void ex_echo(exarg_T *eap)
|
|||
typval_T rettv;
|
||||
bool needclr = true;
|
||||
bool atstart = true;
|
||||
const int did_emsg_before = did_emsg;
|
||||
|
||||
if (eap->skip)
|
||||
++emsg_skip;
|
||||
|
@ -19546,7 +19546,7 @@ void ex_echo(exarg_T *eap)
|
|||
// Report the invalid expression unless the expression evaluation
|
||||
// has been cancelled due to an aborting error, an interrupt, or an
|
||||
// exception.
|
||||
if (!aborting()) {
|
||||
if (!aborting() && did_emsg == did_emsg_before) {
|
||||
EMSG2(_(e_invexpr2), p);
|
||||
}
|
||||
need_clr_eos = false;
|
||||
|
@ -19635,7 +19635,7 @@ void ex_execute(exarg_T *eap)
|
|||
int ret = OK;
|
||||
char_u *p;
|
||||
garray_T ga;
|
||||
int save_did_emsg;
|
||||
int save_did_emsg = did_emsg;
|
||||
|
||||
ga_init(&ga, 1, 80);
|
||||
|
||||
|
@ -19649,8 +19649,9 @@ void ex_execute(exarg_T *eap)
|
|||
* has been cancelled due to an aborting error, an interrupt, or an
|
||||
* exception.
|
||||
*/
|
||||
if (!aborting())
|
||||
if (!aborting() && did_emsg == save_did_emsg) {
|
||||
EMSG2(_(e_invexpr2), p);
|
||||
}
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
|
@ -22758,7 +22759,18 @@ bool eval_has_provider(const char *name)
|
|||
CHECK_PROVIDER(python);
|
||||
return has_python;
|
||||
} else if (strequal(name, "ruby")) {
|
||||
bool need_check_ruby = (has_ruby == -1);
|
||||
CHECK_PROVIDER(ruby);
|
||||
if (need_check_ruby && has_ruby == 1) {
|
||||
char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, NULL, true);
|
||||
if (rubyhost) {
|
||||
if (*rubyhost == NUL) {
|
||||
// Invalid rubyhost executable. Gem is probably not installed.
|
||||
has_ruby = 0;
|
||||
}
|
||||
xfree(rubyhost);
|
||||
}
|
||||
}
|
||||
return has_ruby;
|
||||
}
|
||||
|
||||
|
|
|
@ -933,7 +933,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
|
|||
|
||||
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
|
||||
do { \
|
||||
if ((num)) { \
|
||||
if (num) { \
|
||||
msgpack_pack_true(packer); \
|
||||
} else { \
|
||||
msgpack_pack_false(packer); \
|
||||
|
|
|
@ -2850,7 +2850,7 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
|
|||
/// Get the string value of a "stringish" VimL object.
|
||||
///
|
||||
/// @warning For number and special values it uses a single, static buffer. It
|
||||
/// may be used only once, next call to get_tv_string may reuse it. Use
|
||||
/// may be used only once, next call to tv_get_string may reuse it. Use
|
||||
/// tv_get_string_buf() if you need to use tv_get_string() output after
|
||||
/// calling it again.
|
||||
///
|
||||
|
@ -2869,7 +2869,7 @@ const char *tv_get_string_chk(const typval_T *const tv)
|
|||
/// Get the string value of a "stringish" VimL object.
|
||||
///
|
||||
/// @warning For number and special values it uses a single, static buffer. It
|
||||
/// may be used only once, next call to get_tv_string may reuse it. Use
|
||||
/// may be used only once, next call to tv_get_string may reuse it. Use
|
||||
/// tv_get_string_buf() if you need to use tv_get_string() output after
|
||||
/// calling it again.
|
||||
///
|
||||
|
|
|
@ -816,10 +816,23 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
|
|||
linenr_T last_line; // Last line in file after adding new text
|
||||
|
||||
if (dest >= line1 && dest < line2) {
|
||||
EMSG(_("E134: Move lines into themselves"));
|
||||
EMSG(_("E134: Cannot move a range of lines into itself"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Do nothing if we are not actually moving any lines. This will prevent
|
||||
// the 'modified' flag from being set without cause.
|
||||
if (dest == line1 - 1 || dest == line2) {
|
||||
// Move the cursor as if lines were moved (see below) to be backwards
|
||||
// compatible.
|
||||
if (dest >= line1) {
|
||||
curwin->w_cursor.lnum = dest;
|
||||
} else {
|
||||
curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
num_lines = line2 - line1 + 1;
|
||||
|
||||
/*
|
||||
|
@ -5672,6 +5685,14 @@ void ex_sign(exarg_T *eap)
|
|||
int len;
|
||||
|
||||
arg += 5;
|
||||
for (s = arg; s + 1 < p; s++) {
|
||||
if (*s == '\\') {
|
||||
// Remove a backslash, so that it is possible
|
||||
// to use a space.
|
||||
STRMOVE(s, s + 1);
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
// Count cells and check for non-printable chars
|
||||
cells = 0;
|
||||
|
|
|
@ -28,15 +28,15 @@ local FILES = bit.bor(XFILE, EXTRA)
|
|||
local WORD1 = bit.bor(EXTRA, NOSPC)
|
||||
local FILE1 = bit.bor(FILES, NOSPC)
|
||||
|
||||
local ADDR_LINES = 0
|
||||
local ADDR_WINDOWS = 1
|
||||
local ADDR_ARGUMENTS = 2
|
||||
local ADDR_LOADED_BUFFERS = 3
|
||||
local ADDR_BUFFERS = 4
|
||||
local ADDR_TABS = 5
|
||||
local ADDR_TABS_RELATIVE = 6
|
||||
local ADDR_QUICKFIX = 7
|
||||
local ADDR_OTHER = 99
|
||||
local ADDR_LINES = 0 -- buffer line numbers
|
||||
local ADDR_WINDOWS = 1 -- window number
|
||||
local ADDR_ARGUMENTS = 2 -- argument number
|
||||
local ADDR_LOADED_BUFFERS = 3 -- buffer number of loaded buffer
|
||||
local ADDR_BUFFERS = 4 -- buffer number
|
||||
local ADDR_TABS = 5 -- tab page number
|
||||
local ADDR_TABS_RELATIVE = 6 -- Tab page that only relative
|
||||
local ADDR_QUICKFIX = 7 -- quickfix list entry number
|
||||
local ADDR_OTHER = 99 -- something else
|
||||
|
||||
-- The following table is described in ex_cmds_defs.h file.
|
||||
return {
|
||||
|
@ -1706,24 +1706,6 @@ return {
|
|||
addr_type=ADDR_LINES,
|
||||
func='ex_next',
|
||||
},
|
||||
{
|
||||
command='nbkey',
|
||||
flags=bit.bor(EXTRA, NOTADR, NEEDARG),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_ni',
|
||||
},
|
||||
{
|
||||
command='nbclose',
|
||||
flags=bit.bor(TRLBAR, CMDWIN),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_ni',
|
||||
},
|
||||
{
|
||||
command='nbstart',
|
||||
flags=bit.bor(WORD1, TRLBAR, CMDWIN),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_ni',
|
||||
},
|
||||
{
|
||||
command='new',
|
||||
flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR),
|
||||
|
@ -1958,18 +1940,6 @@ return {
|
|||
addr_type=ADDR_LINES,
|
||||
func='ex_previous',
|
||||
},
|
||||
{
|
||||
command='promptfind',
|
||||
flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_ni',
|
||||
},
|
||||
{
|
||||
command='promptrepl',
|
||||
flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_ni',
|
||||
},
|
||||
{
|
||||
command='profile',
|
||||
flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN),
|
||||
|
@ -2326,8 +2296,8 @@ return {
|
|||
},
|
||||
{
|
||||
command='scriptnames',
|
||||
flags=bit.bor(TRLBAR, CMDWIN),
|
||||
addr_type=ADDR_LINES,
|
||||
flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR, CMDWIN),
|
||||
addr_type=ADDR_OTHER,
|
||||
func='ex_scriptnames',
|
||||
},
|
||||
{
|
||||
|
@ -3116,12 +3086,6 @@ return {
|
|||
addr_type=ADDR_LINES,
|
||||
func='do_wqall',
|
||||
},
|
||||
{
|
||||
command='wsverb',
|
||||
flags=bit.bor(EXTRA, NOTADR, NEEDARG),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_ni',
|
||||
},
|
||||
{
|
||||
command='wshada',
|
||||
flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN),
|
||||
|
|
|
@ -3069,6 +3069,17 @@ theend:
|
|||
/// ":scriptnames"
|
||||
void ex_scriptnames(exarg_T *eap)
|
||||
{
|
||||
if (eap->addr_count > 0) {
|
||||
// :script {scriptId}: edit the script
|
||||
if (eap->line2 < 1 || eap->line2 > script_items.ga_len) {
|
||||
EMSG(_(e_invarg));
|
||||
} else {
|
||||
eap->arg = SCRIPT_ITEM(eap->line2).sn_name;
|
||||
do_exedit(eap, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= script_items.ga_len && !got_int; i++) {
|
||||
if (SCRIPT_ITEM(i).sn_name != NULL) {
|
||||
home_replace(NULL, SCRIPT_ITEM(i).sn_name,
|
||||
|
@ -3506,7 +3517,12 @@ static char *get_locale_val(int what)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Return true when "lang" starts with a valid language name.
|
||||
// Rejects NULL, empty string, "C", "C.UTF-8" and others.
|
||||
static bool is_valid_mess_lang(char *lang)
|
||||
{
|
||||
return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]);
|
||||
}
|
||||
|
||||
/// Obtain the current messages language. Used to set the default for
|
||||
/// 'helplang'. May return NULL or an empty string.
|
||||
|
@ -3526,14 +3542,14 @@ char *get_mess_lang(void)
|
|||
# endif
|
||||
# else
|
||||
p = os_getenv("LC_ALL");
|
||||
if (p == NULL) {
|
||||
if (!is_valid_mess_lang(p)) {
|
||||
p = os_getenv("LC_MESSAGES");
|
||||
if (p == NULL) {
|
||||
if (!is_valid_mess_lang(p)) {
|
||||
p = os_getenv("LANG");
|
||||
}
|
||||
}
|
||||
# endif
|
||||
return p;
|
||||
return is_valid_mess_lang(p) ? p : NULL;
|
||||
}
|
||||
|
||||
// Complicated #if; matches with where get_mess_env() is used below.
|
||||
|
@ -3812,7 +3828,13 @@ static void script_host_execute(char *name, exarg_T *eap)
|
|||
// current range
|
||||
tv_list_append_number(args, (int)eap->line1);
|
||||
tv_list_append_number(args, (int)eap->line2);
|
||||
(void)eval_call_provider(name, "execute", args);
|
||||
|
||||
if (!eval_has_provider(name)) {
|
||||
emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"",
|
||||
name);
|
||||
} else {
|
||||
(void)eval_call_provider(name, "execute", args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1804,15 +1804,19 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
|||
errormsg = (char_u *)_(get_text_locked_msg());
|
||||
goto doend;
|
||||
}
|
||||
/* Disallow editing another buffer when "curbuf_lock" is set.
|
||||
* Do allow ":edit" (check for argument later).
|
||||
* Do allow ":checktime" (it's postponed). */
|
||||
|
||||
// Disallow editing another buffer when "curbuf_lock" is set.
|
||||
// Do allow ":checktime" (it is postponed).
|
||||
// Do allow ":edit" (check for an argument later).
|
||||
// Do allow ":file" with no arguments (check for an argument later).
|
||||
if (!(ea.argt & CMDWIN)
|
||||
&& ea.cmdidx != CMD_edit
|
||||
&& ea.cmdidx != CMD_checktime
|
||||
&& ea.cmdidx != CMD_edit
|
||||
&& ea.cmdidx != CMD_file
|
||||
&& !IS_USER_CMDIDX(ea.cmdidx)
|
||||
&& curbuf_locked())
|
||||
&& curbuf_locked()) {
|
||||
goto doend;
|
||||
}
|
||||
|
||||
if (!ni && !(ea.argt & RANGE) && ea.addr_count > 0) {
|
||||
/* no range allowed */
|
||||
|
@ -1884,6 +1888,11 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
|||
else
|
||||
ea.arg = skipwhite(p);
|
||||
|
||||
// ":file" cannot be run with an argument when "curbuf_lock" is set
|
||||
if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) {
|
||||
goto doend;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for "++opt=val" argument.
|
||||
* Must be first, allow ":w ++enc=utf8 !cmd"
|
||||
|
@ -8645,7 +8654,10 @@ eval_vars (
|
|||
break;
|
||||
|
||||
case SPEC_AFILE: // file name for autocommand
|
||||
if (autocmd_fname != NULL && !path_is_absolute(autocmd_fname)) {
|
||||
if (autocmd_fname != NULL
|
||||
&& !path_is_absolute(autocmd_fname)
|
||||
// For CmdlineEnter and related events, <afile> is not a path! #9348
|
||||
&& !strequal("/", (char *)autocmd_fname)) {
|
||||
// Still need to turn the fname into a full path. It was
|
||||
// postponed to avoid a delay when <afile> is not used.
|
||||
result = (char_u *)FullName_save((char *)autocmd_fname, false);
|
||||
|
|
|
@ -1804,6 +1804,37 @@ static int empty_pattern(char_u *p)
|
|||
|
||||
static int command_line_changed(CommandLineState *s)
|
||||
{
|
||||
// Trigger CmdlineChanged autocommands.
|
||||
if (has_event(EVENT_CMDLINECHANGED)) {
|
||||
TryState tstate;
|
||||
Error err = ERROR_INIT;
|
||||
bool tl_ret = true;
|
||||
dict_T *dict = get_vim_var_dict(VV_EVENT);
|
||||
|
||||
char firstcbuf[2];
|
||||
firstcbuf[0] = s->firstc > 0 ? s->firstc : '-';
|
||||
firstcbuf[1] = 0;
|
||||
|
||||
// set v:event to a dictionary with information about the commandline
|
||||
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
|
||||
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
|
||||
tv_dict_set_keys_readonly(dict);
|
||||
try_enter(&tstate);
|
||||
|
||||
apply_autocmds(EVENT_CMDLINECHANGED, (char_u *)firstcbuf,
|
||||
(char_u *)firstcbuf, false, curbuf);
|
||||
tv_dict_clear(dict);
|
||||
|
||||
tl_ret = try_leave(&tstate, &err);
|
||||
if (!tl_ret && ERROR_SET(&err)) {
|
||||
msg_putchar('\n');
|
||||
msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
|
||||
api_clear_error(&err);
|
||||
redrawcmd();
|
||||
}
|
||||
tl_ret = true;
|
||||
}
|
||||
|
||||
// 'incsearch' highlighting.
|
||||
if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {
|
||||
pos_T end_pos;
|
||||
|
|
|
@ -1739,13 +1739,13 @@ failed:
|
|||
close(0);
|
||||
#ifndef WIN32
|
||||
// On Unix, use stderr for stdin, makes shell commands work.
|
||||
ignored = dup(2);
|
||||
vim_ignored = dup(2);
|
||||
#else
|
||||
// On Windows, use the console input handle for stdin.
|
||||
HANDLE conin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,
|
||||
OPEN_EXISTING, 0, (HANDLE)NULL);
|
||||
ignored = _open_osfhandle(conin, _O_RDONLY);
|
||||
vim_ignored = _open_osfhandle(conin, _O_RDONLY);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -4531,48 +4531,83 @@ bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL
|
|||
}
|
||||
|
||||
/// Read 2 bytes from "fd" and turn them into an int, MSB first.
|
||||
/// Returns -1 when encountering EOF.
|
||||
int get2c(FILE *fd)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = getc(fd);
|
||||
n = (n << 8) + getc(fd);
|
||||
return n;
|
||||
const int n = getc(fd);
|
||||
if (n == EOF) {
|
||||
return -1;
|
||||
}
|
||||
const int c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
return (n << 8) + c;
|
||||
}
|
||||
|
||||
/// Read 3 bytes from "fd" and turn them into an int, MSB first.
|
||||
/// Returns -1 when encountering EOF.
|
||||
int get3c(FILE *fd)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = getc(fd);
|
||||
n = (n << 8) + getc(fd);
|
||||
n = (n << 8) + getc(fd);
|
||||
return n;
|
||||
int n = getc(fd);
|
||||
if (n == EOF) {
|
||||
return -1;
|
||||
}
|
||||
int c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
n = (n << 8) + c;
|
||||
c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
return (n << 8) + c;
|
||||
}
|
||||
|
||||
/// Read 4 bytes from "fd" and turn them into an int, MSB first.
|
||||
/// Returns -1 when encountering EOF.
|
||||
int get4c(FILE *fd)
|
||||
{
|
||||
// Use unsigned rather than int otherwise result is undefined
|
||||
// when left-shift sets the MSB.
|
||||
unsigned n;
|
||||
|
||||
n = (unsigned)getc(fd);
|
||||
n = (n << 8) + (unsigned)getc(fd);
|
||||
n = (n << 8) + (unsigned)getc(fd);
|
||||
n = (n << 8) + (unsigned)getc(fd);
|
||||
int c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
n = (unsigned)c;
|
||||
c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
n = (n << 8) + (unsigned)c;
|
||||
c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
n = (n << 8) + (unsigned)c;
|
||||
c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
n = (n << 8) + (unsigned)c;
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
/// Read 8 bytes from `fd` and turn them into a time_t, MSB first.
|
||||
/// Returns -1 when encountering EOF.
|
||||
time_t get8ctime(FILE *fd)
|
||||
{
|
||||
time_t n = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
n = (n << 8) + getc(fd);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
const int c = getc(fd);
|
||||
if (c == EOF) {
|
||||
return -1;
|
||||
}
|
||||
n = (n << 8) + c;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -5932,19 +5967,19 @@ void au_event_restore(char_u *old_ei)
|
|||
* will be automatically executed for <event>
|
||||
* when editing a file matching <pat>, in
|
||||
* the current group.
|
||||
* :autocmd <event> <pat> Show the auto-commands associated with
|
||||
* :autocmd <event> <pat> Show the autocommands associated with
|
||||
* <event> and <pat>.
|
||||
* :autocmd <event> Show the auto-commands associated with
|
||||
* :autocmd <event> Show the autocommands associated with
|
||||
* <event>.
|
||||
* :autocmd Show all auto-commands.
|
||||
* :autocmd! <event> <pat> <cmd> Remove all auto-commands associated with
|
||||
* :autocmd Show all autocommands.
|
||||
* :autocmd! <event> <pat> <cmd> Remove all autocommands associated with
|
||||
* <event> and <pat>, and add the command
|
||||
* <cmd>, for the current group.
|
||||
* :autocmd! <event> <pat> Remove all auto-commands associated with
|
||||
* :autocmd! <event> <pat> Remove all autocommands associated with
|
||||
* <event> and <pat> for the current group.
|
||||
* :autocmd! <event> Remove all auto-commands associated with
|
||||
* :autocmd! <event> Remove all autocommands associated with
|
||||
* <event> for the current group.
|
||||
* :autocmd! Remove ALL auto-commands for the current
|
||||
* :autocmd! Remove ALL autocommands for the current
|
||||
* group.
|
||||
*
|
||||
* Multiple events and patterns may be given separated by commas. Here are
|
||||
|
@ -6037,8 +6072,8 @@ void do_autocmd(char_u *arg_in, int forceit)
|
|||
* Print header when showing autocommands.
|
||||
*/
|
||||
if (!forceit && *cmd == NUL) {
|
||||
/* Highlight title */
|
||||
MSG_PUTS_TITLE(_("\n--- Auto-Commands ---"));
|
||||
// Highlight title
|
||||
MSG_PUTS_TITLE(_("\n--- Autocommands ---"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -6868,7 +6903,13 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
|||
} else {
|
||||
sfname = vim_strsave(fname);
|
||||
// Don't try expanding the following events.
|
||||
if (event == EVENT_COLORSCHEME
|
||||
if (event == EVENT_CMDLINECHANGED
|
||||
|| event == EVENT_CMDLINEENTER
|
||||
|| event == EVENT_CMDLINELEAVE
|
||||
|| event == EVENT_CMDWINENTER
|
||||
|| event == EVENT_CMDWINLEAVE
|
||||
|| event == EVENT_CMDUNDEFINED
|
||||
|| event == EVENT_COLORSCHEME
|
||||
|| event == EVENT_COLORSCHEMEPRE
|
||||
|| event == EVENT_DIRCHANGED
|
||||
|| event == EVENT_FILETYPE
|
||||
|
@ -6907,8 +6948,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
|||
autocmd_match = fname;
|
||||
|
||||
|
||||
/* Don't redraw while doing auto commands. */
|
||||
++RedrawingDisabled;
|
||||
// Don't redraw while doing autocommands.
|
||||
RedrawingDisabled++;
|
||||
save_sourcing_name = sourcing_name;
|
||||
sourcing_name = NULL; /* don't free this one */
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
|
@ -7119,7 +7160,7 @@ auto_next_pat (
|
|||
apc->tail, ap->allow_dirs)
|
||||
: ap->buflocal_nr == apc->arg_bufnr) {
|
||||
const char *const name = event_nr2name(apc->event);
|
||||
s = _("%s Auto commands for \"%s\"");
|
||||
s = _("%s Autocommands for \"%s\"");
|
||||
const size_t sourcing_name_len = (STRLEN(s) + strlen(name) + ap->patlen
|
||||
+ 1);
|
||||
sourcing_name = xmalloc(sourcing_name_len);
|
||||
|
|
|
@ -171,9 +171,8 @@ bool hasFoldingWin(
|
|||
int low_level = 0;
|
||||
|
||||
checkupdate(win);
|
||||
/*
|
||||
* Return quickly when there is no folding at all in this window.
|
||||
*/
|
||||
|
||||
// Return quickly when there is no folding at all in this window.
|
||||
if (!hasAnyFolding(win)) {
|
||||
if (infop != NULL)
|
||||
infop->fi_level = 0;
|
||||
|
@ -2851,8 +2850,9 @@ static void foldlevelIndent(fline_T *flp)
|
|||
flp->lvl = 0;
|
||||
else
|
||||
flp->lvl = -1;
|
||||
} else
|
||||
flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf);
|
||||
} else {
|
||||
flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(buf);
|
||||
}
|
||||
if (flp->lvl > flp->wp->w_p_fdn) {
|
||||
flp->lvl = (int) MAX(0, flp->wp->w_p_fdn);
|
||||
}
|
||||
|
|
|
@ -1125,8 +1125,7 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
|
|||
* can't do anything useful with the value. Assign to this variable to avoid
|
||||
* the warning.
|
||||
*/
|
||||
EXTERN int ignored;
|
||||
EXTERN char *ignoredp;
|
||||
EXTERN int vim_ignored;
|
||||
|
||||
// Start a msgpack-rpc channel over stdin/stdout.
|
||||
EXTERN bool embedded_mode INIT(= false);
|
||||
|
|
|
@ -177,8 +177,27 @@ void update_window_hl(win_T *wp, bool invalid)
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets HL_UNDERLINE highlight.
|
||||
int hl_get_underline(void)
|
||||
{
|
||||
return get_attr_entry((HlEntry){
|
||||
.attr = (HlAttrs){
|
||||
.cterm_ae_attr = (int16_t)HL_UNDERLINE,
|
||||
.cterm_fg_color = 0,
|
||||
.cterm_bg_color = 0,
|
||||
.rgb_ae_attr = (int16_t)HL_UNDERLINE,
|
||||
.rgb_fg_color = -1,
|
||||
.rgb_bg_color = -1,
|
||||
.rgb_sp_color = -1,
|
||||
},
|
||||
.kind = kHlUI,
|
||||
.id1 = 0,
|
||||
.id2 = 0,
|
||||
});
|
||||
}
|
||||
|
||||
/// Get attribute code for forwarded :terminal highlights.
|
||||
int get_term_attr_entry(HlAttrs *aep)
|
||||
int hl_get_term_attr(HlAttrs *aep)
|
||||
{
|
||||
return get_attr_entry((HlEntry){ .attr= *aep, .kind = kHlTerminal,
|
||||
.id1 = 0, .id2 = 0 });
|
||||
|
|
|
@ -22,7 +22,7 @@ typedef enum {
|
|||
/// Stores a complete highlighting entry, including colors and attributes
|
||||
/// for both TUI and GUI.
|
||||
typedef struct attr_entry {
|
||||
int16_t rgb_ae_attr, cterm_ae_attr; // HL_BOLD, etc.
|
||||
int16_t rgb_ae_attr, cterm_ae_attr; ///< HlAttrFlags
|
||||
RgbValue rgb_fg_color, rgb_bg_color, rgb_sp_color;
|
||||
int cterm_fg_color, cterm_bg_color;
|
||||
} HlAttrs;
|
||||
|
@ -37,17 +37,6 @@ typedef struct attr_entry {
|
|||
.cterm_bg_color = 0, \
|
||||
}
|
||||
|
||||
// sentinel value that compares unequal to any valid highlight
|
||||
#define HLATTRS_INVALID (HlAttrs) { \
|
||||
.rgb_ae_attr = -1, \
|
||||
.cterm_ae_attr = -1, \
|
||||
.rgb_fg_color = -1, \
|
||||
.rgb_bg_color = -1, \
|
||||
.rgb_sp_color = -1, \
|
||||
.cterm_fg_color = 0, \
|
||||
.cterm_bg_color = 0, \
|
||||
}
|
||||
|
||||
/// Values for index in highlight_attr[].
|
||||
/// When making changes, also update hlf_names below!
|
||||
typedef enum {
|
||||
|
@ -94,8 +83,8 @@ typedef enum {
|
|||
, HLF_TP // tabpage line
|
||||
, HLF_TPS // tabpage line selected
|
||||
, HLF_TPF // tabpage line filler
|
||||
, HLF_CUC // 'cursurcolumn'
|
||||
, HLF_CUL // 'cursurline'
|
||||
, HLF_CUC // 'cursorcolumn'
|
||||
, HLF_CUL // 'cursorline'
|
||||
, HLF_MC // 'colorcolumn'
|
||||
, HLF_QFL // selected quickfix line
|
||||
, HLF_0 // Whitespace
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#ifndef WIN32
|
||||
# include "nvim/os/pty_process_unix.h"
|
||||
#endif
|
||||
#include "nvim/api/vim.h"
|
||||
|
||||
// Maximum number of commands from + or -c arguments.
|
||||
#define MAX_ARG_CMDS 10
|
||||
|
@ -150,6 +151,8 @@ void event_init(void)
|
|||
signal_init();
|
||||
// finish mspgack-rpc initialization
|
||||
channel_init();
|
||||
remote_ui_init();
|
||||
api_vim_init();
|
||||
terminal_init();
|
||||
}
|
||||
|
||||
|
@ -1719,6 +1722,48 @@ static void exe_commands(mparm_T *parmp)
|
|||
TIME_MSG("executing command arguments");
|
||||
}
|
||||
|
||||
/// Source system-wide vimrc if built with one defined
|
||||
///
|
||||
/// Does one of the following things, stops after whichever succeeds:
|
||||
///
|
||||
/// 1. Source system vimrc file from $XDG_CONFIG_DIRS/nvim/sysinit.vim
|
||||
/// 2. Source system vimrc file from $VIM
|
||||
static void do_system_initialization(void)
|
||||
{
|
||||
char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
|
||||
if (config_dirs != NULL) {
|
||||
const void *iter = NULL;
|
||||
const char path_tail[] = {
|
||||
'n', 'v', 'i', 'm', PATHSEP,
|
||||
's', 'y', 's', 'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL
|
||||
};
|
||||
do {
|
||||
const char *dir;
|
||||
size_t dir_len;
|
||||
iter = vim_env_iter(':', config_dirs, iter, &dir, &dir_len);
|
||||
if (dir == NULL || dir_len == 0) {
|
||||
break;
|
||||
}
|
||||
char *vimrc = xmalloc(dir_len + sizeof(path_tail) + 1);
|
||||
memcpy(vimrc, dir, dir_len);
|
||||
vimrc[dir_len] = PATHSEP;
|
||||
memcpy(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
|
||||
if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) {
|
||||
xfree(vimrc);
|
||||
xfree(config_dirs);
|
||||
return;
|
||||
}
|
||||
xfree(vimrc);
|
||||
} while (iter != NULL);
|
||||
xfree(config_dirs);
|
||||
}
|
||||
|
||||
#ifdef SYS_VIMRC_FILE
|
||||
// Get system wide defaults, if the file name is defined.
|
||||
(void)do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Source vimrc or do other user initialization
|
||||
///
|
||||
/// Does one of the following things, stops after whichever succeeds:
|
||||
|
@ -1801,10 +1846,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
|
|||
}
|
||||
}
|
||||
} else if (!silent_mode) {
|
||||
#ifdef SYS_VIMRC_FILE
|
||||
// Get system wide defaults, if the file name is defined.
|
||||
(void) do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
|
||||
#endif
|
||||
do_system_initialization();
|
||||
|
||||
if (do_user_initialization()) {
|
||||
// Read initialization commands from ".vimrc" or ".exrc" in current
|
||||
|
|
|
@ -166,3 +166,4 @@ MAP_IMPL(handle_T, ptr_t, DEFAULT_INITIALIZER)
|
|||
MAP_IMPL(String, MsgpackRpcRequestHandler, MSGPACK_HANDLER_INITIALIZER)
|
||||
#define KVEC_INITIALIZER { .size = 0, .capacity = 0, .items = NULL }
|
||||
MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER)
|
||||
MAP_IMPL(String, handle_T, 0)
|
||||
|
|
|
@ -37,6 +37,7 @@ MAP_DECLS(uint64_t, ptr_t)
|
|||
MAP_DECLS(handle_T, ptr_t)
|
||||
MAP_DECLS(String, MsgpackRpcRequestHandler)
|
||||
MAP_DECLS(HlEntry, int)
|
||||
MAP_DECLS(String, handle_T)
|
||||
|
||||
#define map_new(T, U) map_##T##_##U##_new
|
||||
#define map_free(T, U) map_##T##_##U##_free
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "nvim/message.h"
|
||||
#include "nvim/misc1.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/api/vim.h"
|
||||
|
||||
#ifdef HAVE_JEMALLOC
|
||||
// Force je_ prefix on jemalloc functions.
|
||||
|
@ -681,6 +682,7 @@ void free_all_mem(void)
|
|||
break;
|
||||
|
||||
eval_clear();
|
||||
api_vim_free_all_mem();
|
||||
|
||||
// Free all buffers. Reset 'autochdir' to avoid accessing things that
|
||||
// were freed already.
|
||||
|
|
|
@ -505,7 +505,7 @@ int emsg(const char_u *s_)
|
|||
*/
|
||||
if (cause_errthrow((char_u *)s, severe, &ignore) == true) {
|
||||
if (!ignore) {
|
||||
did_emsg = true;
|
||||
did_emsg++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ int emsg(const char_u *s_)
|
|||
} else {
|
||||
flush_buffers(FLUSH_MINIMAL); // flush internal buffers
|
||||
}
|
||||
did_emsg = true; // flag for DoOneCmd()
|
||||
did_emsg++; // flag for DoOneCmd()
|
||||
}
|
||||
|
||||
emsg_on_display = true; // remember there is an error message
|
||||
|
@ -1896,6 +1896,9 @@ static void msg_scroll_up(void)
|
|||
} else {
|
||||
screen_del_lines(0, 1, (int)Rows, 0, Columns);
|
||||
}
|
||||
// TODO(bfredl): when msgsep display is properly batched, this fill should be
|
||||
// eliminated.
|
||||
screen_fill(Rows-1, Rows, 0, (int)Columns, ' ', ' ', 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2311,6 +2314,7 @@ static int do_more_prompt(int typed_char)
|
|||
|
||||
if (toscroll == -1
|
||||
&& screen_ins_lines(0, 1, (int)Rows, 0, (int)Columns) == OK) {
|
||||
screen_fill(0, 1, 0, (int)Columns, ' ', ' ', 0);
|
||||
// display line at top
|
||||
(void)disp_sb_line(0, mp);
|
||||
} else {
|
||||
|
@ -2821,7 +2825,6 @@ do_dialog (
|
|||
Ex command */
|
||||
)
|
||||
{
|
||||
int oldState;
|
||||
int retval = 0;
|
||||
char_u *hotkeys;
|
||||
int c;
|
||||
|
@ -2834,7 +2837,10 @@ do_dialog (
|
|||
}
|
||||
|
||||
|
||||
oldState = State;
|
||||
int save_msg_silent = msg_silent;
|
||||
int oldState = State;
|
||||
|
||||
msg_silent = 0; // If dialog prompts for input, user needs to see it! #8788
|
||||
State = CONFIRM;
|
||||
setmouse();
|
||||
|
||||
|
@ -2887,6 +2893,7 @@ do_dialog (
|
|||
|
||||
xfree(hotkeys);
|
||||
|
||||
msg_silent = save_msg_silent;
|
||||
State = oldState;
|
||||
setmouse();
|
||||
--no_wait_return;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nvim/window.h"
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/os/shell.h"
|
||||
#include "nvim/os/signal.h"
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/event/stream.h"
|
||||
|
@ -1121,8 +1122,9 @@ int get_last_leader_offset(char_u *line, char_u **flags)
|
|||
if (ascii_iswhite(string[0])) {
|
||||
if (i == 0 || !ascii_iswhite(line[i - 1]))
|
||||
continue;
|
||||
while (ascii_iswhite(string[0]))
|
||||
++string;
|
||||
while (ascii_iswhite(*string)) {
|
||||
string++;
|
||||
}
|
||||
}
|
||||
for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
|
||||
/* do nothing */;
|
||||
|
@ -1138,6 +1140,19 @@ int get_last_leader_offset(char_u *line, char_u **flags)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (vim_strchr(part_buf, COM_MIDDLE) != NULL) {
|
||||
// For a middlepart comment, only consider it to match if
|
||||
// everything before the current position in the line is
|
||||
// whitespace. Otherwise we would think we are inside a
|
||||
// comment if the middle part appears somewhere in the middle
|
||||
// of the line. E.g. for C the "*" appears often.
|
||||
for (j = 0; ascii_iswhite(line[j]) && j <= i; j++) {
|
||||
}
|
||||
if (j < i) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We have found a match, stop searching.
|
||||
*/
|
||||
|
@ -1936,10 +1951,10 @@ changed_lines(
|
|||
{
|
||||
changed_lines_buf(curbuf, lnum, lnume, xtra);
|
||||
|
||||
if (xtra == 0 && curwin->w_p_diff) {
|
||||
/* When the number of lines doesn't change then mark_adjust() isn't
|
||||
* called and other diff buffers still need to be marked for
|
||||
* displaying. */
|
||||
if (xtra == 0 && curwin->w_p_diff && !diff_internal()) {
|
||||
// When the number of lines doesn't change then mark_adjust() isn't
|
||||
// called and other diff buffers still need to be marked for
|
||||
// displaying.
|
||||
linenr_T wlnum;
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
|
@ -2008,6 +2023,10 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra
|
|||
/* mark the buffer as modified */
|
||||
changed();
|
||||
|
||||
if (curwin->w_p_diff && diff_internal()) {
|
||||
curtab->tp_diff_update = true;
|
||||
}
|
||||
|
||||
/* set the '. mark */
|
||||
if (!cmdmod.keepjumps) {
|
||||
RESET_FMARK(&curbuf->b_last_change, ((pos_T) {lnum, col, 0}), 0);
|
||||
|
@ -2653,6 +2672,8 @@ void preserve_exit(void)
|
|||
}
|
||||
|
||||
really_exiting = true;
|
||||
// Ignore SIGHUP while we are already exiting. #9274
|
||||
signal_reject_deadly();
|
||||
mch_errmsg(IObuff);
|
||||
mch_errmsg("\n");
|
||||
ui_flush();
|
||||
|
|
|
@ -918,9 +918,9 @@ void curs_columns(
|
|||
|
||||
extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width;
|
||||
if (extra > 0) {
|
||||
win_ins_lines(curwin, 0, extra, false);
|
||||
win_ins_lines(curwin, 0, extra);
|
||||
} else if (extra < 0) {
|
||||
win_del_lines(curwin, 0, -extra, false);
|
||||
win_del_lines(curwin, 0, -extra);
|
||||
}
|
||||
} else {
|
||||
curwin->w_skipcol = 0;
|
||||
|
|
|
@ -641,7 +641,16 @@ static WBuffer *serialize_response(uint64_t channel_id,
|
|||
{
|
||||
msgpack_packer pac;
|
||||
msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write);
|
||||
msgpack_rpc_serialize_response(response_id, err, arg, &pac);
|
||||
if (ERROR_SET(err) && response_id == NO_RESPONSE) {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
ADD(args, INTEGER_OBJ(err->type));
|
||||
ADD(args, STRING_OBJ(cstr_to_string(err->msg)));
|
||||
msgpack_rpc_serialize_request(0, cstr_as_string("nvim_error_event"),
|
||||
args, &pac);
|
||||
api_free_array(args);
|
||||
} else {
|
||||
msgpack_rpc_serialize_response(response_id, err, arg, &pac);
|
||||
}
|
||||
log_server_msg(channel_id, sbuffer);
|
||||
WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size),
|
||||
sbuffer->size,
|
||||
|
|
|
@ -1325,6 +1325,14 @@ static int normal_check(VimState *state)
|
|||
normal_check_cursor_moved(s);
|
||||
normal_check_text_changed(s);
|
||||
|
||||
// Updating diffs from changed() does not always work properly,
|
||||
// esp. updating folds. Do an update just before redrawing if
|
||||
// needed.
|
||||
if (curtab->tp_diff_update || curtab->tp_diff_invalid) {
|
||||
ex_diffupdate(NULL);
|
||||
curtab->tp_diff_update = false;
|
||||
}
|
||||
|
||||
// Scroll-binding for diff mode may have been postponed until
|
||||
// here. Avoids doing it for every change.
|
||||
if (diff_need_scrollbind) {
|
||||
|
|
|
@ -1068,6 +1068,10 @@ void set_helplang_default(const char *lang)
|
|||
if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) {
|
||||
p_hlg[0] = (char_u)TOLOWER_ASC(p_hlg[3]);
|
||||
p_hlg[1] = (char_u)TOLOWER_ASC(p_hlg[4]);
|
||||
} else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C') {
|
||||
// any C like setting, such as C.UTF-8, becomes "en"
|
||||
p_hlg[0] = 'e';
|
||||
p_hlg[1] = 'n';
|
||||
}
|
||||
p_hlg[2] = NUL;
|
||||
options[idx].flags |= P_ALLOCED;
|
||||
|
@ -1769,14 +1773,13 @@ do_set (
|
|||
// Set the new value.
|
||||
*(char_u **)(varp) = newval;
|
||||
|
||||
if (!starting && origval != NULL && newval != NULL) {
|
||||
// origval may be freed by
|
||||
// did_set_string_option(), make a copy.
|
||||
saved_origval = xstrdup((char *)origval);
|
||||
// newval (and varp) may become invalid if the
|
||||
// buffer is closed by autocommands.
|
||||
saved_newval = xstrdup((char *)newval);
|
||||
}
|
||||
// origval may be freed by
|
||||
// did_set_string_option(), make a copy.
|
||||
saved_origval = (origval != NULL) ? xstrdup((char *)origval) : 0;
|
||||
|
||||
// newval (and varp) may become invalid if the
|
||||
// buffer is closed by autocommands.
|
||||
saved_newval = (newval != NULL) ? xstrdup((char *)newval) : 0;
|
||||
|
||||
// Handle side effects, and set the global value for
|
||||
// ":set" on local options. Note: when setting 'syntax'
|
||||
|
@ -1786,8 +1789,14 @@ do_set (
|
|||
new_value_alloced, oldval, errbuf, opt_flags);
|
||||
|
||||
if (errmsg == NULL) {
|
||||
trigger_optionsset_string(opt_idx, opt_flags, saved_origval,
|
||||
saved_newval);
|
||||
if (!starting) {
|
||||
trigger_optionsset_string(opt_idx, opt_flags, saved_origval,
|
||||
saved_newval);
|
||||
}
|
||||
if (options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
STRING_OBJ(cstr_as_string(saved_newval)));
|
||||
}
|
||||
}
|
||||
xfree(saved_origval);
|
||||
xfree(saved_newval);
|
||||
|
@ -2378,8 +2387,8 @@ static char *set_string_option(const int opt_idx, const char *const value,
|
|||
char *const oldval = *varp;
|
||||
*varp = s;
|
||||
|
||||
char *const saved_oldval = (starting ? NULL : xstrdup(oldval));
|
||||
char *const saved_newval = (starting ? NULL : xstrdup(s));
|
||||
char *const saved_oldval = xstrdup(oldval);
|
||||
char *const saved_newval = xstrdup(s);
|
||||
|
||||
char *const r = (char *)did_set_string_option(
|
||||
opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, NULL, opt_flags);
|
||||
|
@ -2389,8 +2398,13 @@ static char *set_string_option(const int opt_idx, const char *const value,
|
|||
|
||||
// call autocommand after handling side effects
|
||||
if (r == NULL) {
|
||||
trigger_optionsset_string(opt_idx, opt_flags,
|
||||
saved_oldval, saved_newval);
|
||||
if (!starting) {
|
||||
trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_newval);
|
||||
}
|
||||
if (options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
STRING_OBJ(cstr_as_string(saved_newval)));
|
||||
}
|
||||
}
|
||||
xfree(saved_oldval);
|
||||
xfree(saved_newval);
|
||||
|
@ -4056,10 +4070,11 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
|
|||
(char_u *) options[opt_idx].fullname,
|
||||
NULL, false, NULL);
|
||||
reset_v_option_vars();
|
||||
if (options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
BOOLEAN_OBJ(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
BOOLEAN_OBJ(value));
|
||||
}
|
||||
|
||||
comp_col(); /* in case 'ruler' or 'showcmd' changed */
|
||||
|
@ -4429,10 +4444,11 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
|
|||
(char_u *) options[opt_idx].fullname,
|
||||
NULL, false, NULL);
|
||||
reset_v_option_vars();
|
||||
if (options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
INTEGER_OBJ(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
INTEGER_OBJ(value));
|
||||
}
|
||||
|
||||
comp_col(); /* in case 'columns' or 'ls' changed */
|
||||
|
@ -4461,10 +4477,6 @@ static void trigger_optionsset_string(int opt_idx, int opt_flags,
|
|||
apply_autocmds(EVENT_OPTIONSET,
|
||||
(char_u *)options[opt_idx].fullname, NULL, false, NULL);
|
||||
reset_v_option_vars();
|
||||
if (options[opt_idx].flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
|
||||
STRING_OBJ(cstr_as_string(newval)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -132,10 +132,10 @@ return {
|
|||
{
|
||||
full_name='background', abbreviation='bg',
|
||||
type='string', scope={'global'},
|
||||
vi_def=true,
|
||||
vim=true,
|
||||
redraw={'all_windows'},
|
||||
varname='p_bg',
|
||||
defaults={if_true={vi="light"}}
|
||||
defaults={if_true={vi="light",vim="dark"}}
|
||||
},
|
||||
{
|
||||
full_name='backspace', abbreviation='bs',
|
||||
|
@ -615,7 +615,7 @@ return {
|
|||
alloced=true,
|
||||
redraw={'current_window'},
|
||||
varname='p_dip',
|
||||
defaults={if_true={vi="filler"}}
|
||||
defaults={if_true={vi="internal,filler"}}
|
||||
},
|
||||
{
|
||||
full_name='digraph', abbreviation='dg',
|
||||
|
|
|
@ -110,7 +110,7 @@ bool os_isrealdir(const char *name)
|
|||
|
||||
/// Check if the given path is a directory or not.
|
||||
///
|
||||
/// @return `true` if `fname` is a directory.
|
||||
/// @return `true` if `name` is a directory.
|
||||
bool os_isdir(const char_u *name)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
|
@ -126,6 +126,25 @@ bool os_isdir(const char_u *name)
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Check if the given path is a directory and is executable.
|
||||
/// Gives the same results as `os_isdir()` on Windows.
|
||||
///
|
||||
/// @return `true` if `name` is a directory and executable.
|
||||
bool os_isdir_executable(const char *name)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
int32_t mode = os_getperm((const char *)name);
|
||||
if (mode < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
return (S_ISDIR(mode));
|
||||
#else
|
||||
return (S_ISDIR(mode) && (S_IXUSR & mode));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Check what `name` is:
|
||||
/// @return NODE_NORMAL: file or directory (or doesn't exist)
|
||||
/// NODE_WRITABLE: writable device, socket, fifo, etc.
|
||||
|
|
|
@ -17,14 +17,31 @@ void lang_init(void)
|
|||
{
|
||||
#ifdef __APPLE__
|
||||
if (os_getenv("LANG") == NULL) {
|
||||
CFLocaleRef cf_locale = CFLocaleCopyCurrent();
|
||||
CFTypeRef cf_lang_region = CFLocaleGetValue(cf_locale,
|
||||
kCFLocaleIdentifier);
|
||||
CFRetain(cf_lang_region);
|
||||
CFRelease(cf_locale);
|
||||
const char *lang_region = NULL;
|
||||
CFTypeRef cf_lang_region = NULL;
|
||||
|
||||
CFLocaleRef cf_locale = CFLocaleCopyCurrent();
|
||||
if (cf_locale) {
|
||||
cf_lang_region = CFLocaleGetValue(cf_locale, kCFLocaleIdentifier);
|
||||
CFRetain(cf_lang_region);
|
||||
lang_region = CFStringGetCStringPtr(cf_lang_region,
|
||||
kCFStringEncodingUTF8);
|
||||
CFRelease(cf_locale);
|
||||
} else {
|
||||
// Use the primary language defined in Preferences -> Language & Region
|
||||
CFArrayRef cf_langs = CFLocaleCopyPreferredLanguages();
|
||||
if (cf_langs && CFArrayGetCount(cf_langs) > 0) {
|
||||
cf_lang_region = CFArrayGetValueAtIndex(cf_langs, 0);
|
||||
CFRetain(cf_lang_region);
|
||||
CFRelease(cf_langs);
|
||||
lang_region = CFStringGetCStringPtr(cf_lang_region,
|
||||
kCFStringEncodingUTF8);
|
||||
} else {
|
||||
ELOG("$LANG is empty and your primary language cannot be inferred.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const char *lang_region = CFStringGetCStringPtr(cf_lang_region,
|
||||
kCFStringEncodingUTF8);
|
||||
if (lang_region) {
|
||||
os_setenv("LANG", lang_region, true);
|
||||
} else {
|
||||
|
@ -37,6 +54,11 @@ void lang_init(void)
|
|||
CFRelease(cf_lang_region);
|
||||
# ifdef HAVE_LOCALE_H
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
# ifdef LC_NUMERIC
|
||||
// Make sure strtod() uses a decimal point, not a comma.
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
|
||||
// forkpty is not in POSIX, so headers are platform-specific
|
||||
#if defined(__FreeBSD__) || defined (__DragonFly__)
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
# include <libutil.h>
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
|
||||
# include <util.h>
|
||||
|
|
|
@ -8,6 +8,7 @@ if(NOT LANGUAGES)
|
|||
af
|
||||
ca
|
||||
cs
|
||||
da
|
||||
de
|
||||
en_GB
|
||||
eo
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue